JavaScript實現環繞鼠標旋轉效果

本文實例為大傢分享瞭JavaScript實現環繞鼠標旋轉效果的具體代碼,供大傢參考,具體內容如下

<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Canvas Resize</title>
    <style type="text/css">
        /* 清除默認邊距 */
        *{
            margin: 0;
            padding:0
        }
        html,body{
            /* 設置瀏覽器寬高為100% */
            width: 100%;
            height: 100%;
        }
    </style>
</head>
 
<body>
    <!-- canvas可以書寫內容 但是隻會在瀏覽器不顯示canvas時才會顯示書寫的內容 -->
    <canvas></canvas>
    <script src="js/javascript.js"></script>
</body>
 
</html>

js:

//以前封裝的函數 直接從工具庫中復制過來的
/**
 * 獲取隨機數的函數 獲取到的隨機數取整
 */
 function getRandom(a, b){
    return Math.floor(Math.random() * Math.abs(a - b)) + Math.min(a, b)
}
/**
 * 獲取16進制的隨機顏色值
 */
function getColor(){
    var color = '#'
    for(var i=0;i<3;i++){
        var hex = getRandom(0, 256).toString(16)
        color += hex.length === 1 ? '0' + hex : hex;
    }
    return color
}
//獲取隨機數 但是不取整
function randomDoubleFromRange(a,b) {
    return Math.random() * (Math.abs(a - b)) + Math.min(a, b);
}
 
//設置鼠標的位置 先設置為window的中心
var mouse = {
    x: window.innerWidth / 2,
    y: window.innerHeight / 2
}
 
//創建鼠標移動的事件監聽事件  監聽鼠標所在window中的實時位置
window.addEventListener('mousemove', function (window) {
    //給數組中的x和y修改值
    mouse.x = window.clientX;
    mouse.y = window.clientY;
});
 
//當窗口大小發生改變時 重新獲取畫佈寬高並且重置代碼 resize事件在窗口大小變化時觸發
window.addEventListener('resize', function () {
    //window的可用窗口大小 包含瞭滾動條的區域大小
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    init();
});
 
//獲取頁面上的canvas
var canvas = document.querySelector('canvas');
 
//設置canvas的大小為window大小 如果不設置 就使用默認寬高300*150
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
 
//設置canvas繪畫的環境 語法Canvas.getContext(contextID) 現在版本隻能寫參數2d 以後可能會支持3d
var ctx = canvas.getContext('2d');
 
//封裝一個制造環繞鼠標的小球的函數 參數是小球圓心在x軸的位置 在y軸的位置 小球半徑 小球填充顏色
function Particle(x, y, radius, color) {
    //小球中心點的x軸位置
    this.x = x;
    //小球中心點的y軸位置
    this.y = y;
    //小球半徑
    this.radius = radius;
    //小球顏色
    this.color = color;
    //小球轉動的弧度值 不取整 如果取整 就少瞭很多數字 很多小球都會重疊
    this.theta = randomDoubleFromRange(0, 2 * Math.PI);
    //小球繞中心點轉動的速度
    this.speed = 0.05;
    //小球距離中心點的距離
    this.distance = getRandom(70, 90);
    //小球跟隨鼠標移動的速度
    this.dragSpeed = 0.05;
    //記錄鼠標移動前鼠標的位置
    this.lastMouse = {
        x: x,
        y: y
    };
    //繪制函數
    this.draw = function (lastPosition) {
        //重置當前路徑 因為創建的每一個路徑都會以上一個beginPath之後的所有路徑作為基礎繪制 會把之前所有線條的顏色全部繪制成和最後一個線條相同的一個顏色
        ctx.beginPath();
        //將小球顏色作為填充顏色
        ctx.strokeStyle = this.color;
        //將小球半徑作為路徑寬度
        ctx.lineWidth = this.radius;
        //路徑起始位置
        ctx.moveTo(lastPosition.x, lastPosition.y);
        //路徑結束位置
        ctx.lineTo(this.x, this.y);
        //繪制確切路徑
        ctx.stroke();
        //關閉路徑 不是結束路徑 而是從結束點創建一條線連接到起始點 使路徑閉合
        ctx.closePath();
    }
 
    //更新數據的函數
    this.update = function () {
        //創建lastPosition對象接收上一次鼠標的x和y的值
        var lastPosition = {
            x: this.x,
            y: this.y
        }
 
        //每次調用函數移動鼠標當前位置和上一次位置之間的dragSpeed = 0.05的距離 產生拖拽感覺
        this.lastMouse.x += (mouse.x - this.lastMouse.x) * this.dragSpeed;
        this.lastMouse.y += (mouse.y - this.lastMouse.y) * this.dragSpeed;
 
        //更新小球當前位置 因為每一次調用小球的旋轉角度不同導致其位置不同
        this.x = this.lastMouse.x + Math.cos(this.theta) * this.distance;
        this.y = this.lastMouse.y + Math.sin(this.theta) * this.distance;
 
        //更新小球的角度值
        this.theta += this.speed;
        //將參數傳遞給繪制函數繪制路徑
        this.draw(lastPosition);
    }
}
 
//定義particles變量
var particles;
 
//初始化函數
function init() {
    // 每次調用這個函數都要先把數組內容清空 因為使用這個函數除瞭打開網頁後第一次代表調用之外 別的調用都表示窗口大小發生瞭改變 參數發生瞭變化 為瞭修改窗口大小之後又因為調用該函數導致小球重復創建 所以要調用後先清空再創建
    particles = [];
    // 繪制50個小球
    for (var i = 0; i < 50; i++) {
        //獲取隨機的顏色
        let color = getColor()
        //將構造函數創造的小球添加到數組中
        particles.push(new Particle(canvas.width / 2, canvas.height / 2, 3, color));
    }
}
 
function animate() {
    //定時的調用這個函數 類似於setInterval 但是setInterval時間間隔不是很準確 requestAnimationFrame固定為以每秒60次的頻率調用一次括號內的函數
    requestAnimationFrame(animate);
 
    // 每一幀都給之前的幀蒙上一層白色透明的矩形 用以清除上一幀繪制的路徑
    //填充矩形顏色 矩形背景顏色 透明度設置為0.1 可以使之前幾幀的路徑因為多次覆蓋慢慢邊淡 隻是會在背景上留下很淡的痕跡 如果直接使用rgb白色覆蓋 雖然沒有痕跡殘留 但是之前路徑直接被白色覆蓋 沒有拖尾效果
    // ctx.fillStyle = 'rgb(255, 255, 255)';
    ctx.fillStyle = 'rgba(255, 255, 255, 0.1)';
    //繪制矩形 給window繪制一個等高等寬的矩形 以此制造一個漸變的效果
    ctx.fillRect(0, 0, canvas.width, canvas.height);
 
    //對鍵名遍歷數組 獲取canvas.width / 2, canvas.height / 2, 3, color參數 每遍歷一次就調用一次update函數 將獲取到的參數作為實參傳遞給update函數
    for (var p of particles) {
        p.update();
    }
}
 
//初始化 創建小球
init();
//開始動畫
animate();

以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: