WD1X.COM - 问答一下,轻松解决,电脑应用解决专家
主板显卡CPU内存显示器
硬盘维修显卡维修显示器维修
注册表系统命令DOS命令Win8
存储光存储鼠标键盘
内存维修打印机维修
WinXPWin7Win11Linux
硬件综合机箱电源散热器手机数码
主板维修CPU维修键盘鼠标维修
Word教程Excel教程PowerPointWPS
网络工具系统工具图像工具
数据库javascript服务器
PHP教程CSS教程XML教程

canvas旋转跟随鼠标线条 html+css+js

更新时间:2021-04-12 10:36 作者:北极光之夜点击:
先看效果(完整代码在底部):
 

实现过程(可一步一步实现):
 
1.定义标签与基本css样式:
 
<canvas id="canvas"></canvas>
 
canvas{
          display: block;
      }
 

 
2. 开始正式js部分,先获取画布:
 
 var canvas = document.querySelector("#canvas");
 var ctx = canvas.getContext("2d");
 

 
3.定义基本变量:
 
       // 画布宽与高
        var kuan=0,gao=0;
       // 线条数量    
        var num=25;
        //数组,存储每条线的基本信息
        var arr=[];
        // 存几个喜欢的颜色后面给线条
        var colors = ["#2196F3","#1976D2","#00BCD4","#4CAF50","#FF5252","#E040FB"];
 

 
4. 使得画布动态与窗口一样大小,直接copy该方法就行,顺便定义初始鼠标位置变量为画布的中间位置:
 
    window.onresize=resizeCanvas;
        function resizeCanvas(){
            kuan=canvas.width=window.innerWidth;
            gao=canvas.height=window.innerHeight;
        }
        resizeCanvas(); 
 
  var mouseX = kuan/2,mouseY = gao/2;
 

 
5. 初始化数组,初始化每条线条的基本信息:
 
注:Math.random()*(max-min) + min 为随机获取min到max间的一个数。
 
for(let i=0;i<num;i++){
            arr.push({
              // 线条的宽度
                r: Math.random()*(5-3) + 3,
              // 线条的颜色  
                color: colors[parseInt(Math.random()*6)],
                 /* 线条最初始小点所在旋转圆上的位置,就是在旋转开始的角度 */
                rot: Math.random()*2*Math.PI,
                /* 线条与旋转圆中心的距离 */
                distance: Math.random() * (75 - 40) + 40,
                /* 记录初始位置,后面鼠标拖拽时做缓动动画用 */
                lastMouse:{
                    x:kuan/2,
                    y:gao/2
                }
            })
        }
 

 
6.绑定鼠标移动事件:
 
 window.addEventListener('mousemove',function(event){
               mouseX = event.clientX;
               mouseY = event.clientY;               
         })   
 

 
7.执行更新操作,在更新里调用绘制:
 
注意:在一个圆上,坐标 x=cos(…)× r,y = sin(…)× r 。
cos(.)与sin(.)取值范围为【-1,1】。细品。
 
 function update (){
            for(let i=0;i<num;i++){
                //先保存上一帧的位置与i值
               let last ={x:arr[i].x,y:arr[i].y,i:i};             
            // 移动后位置 = 当前位置 + (移动后位置-当前位置)*0.05 缓动动画原理 
                arr[i].lastMouse.x+=(mouseX-arr[i].lastMouse.x)*0.05;
                arr[i].lastMouse.y+=(mouseY-arr[i].lastMouse.y)*0.05;
             // 角度改变,就是进行旋转
               arr[i].rot+=0.1;
               // 坐标X改变
                arr[i].x = arr[i].lastMouse.x + Math.cos(arr[i].rot)*arr[i].distance;
                // 坐标y改变
                arr[i].y = arr[i].lastMouse.y + Math.sin(arr[i].rot)*arr[i].distance;
                 /* 位置改变了,把last传给draw,得到不同两点后绘制画线 */
                draw(last);
            }
         }
 

 
8. 绘制:
 
 function draw(last) {
            var yuan = arr[last.i]; 
            // 开始绘制
            ctx.beginPath();
            //颜色
            ctx.strokeStyle = yuan.color;
            // 宽度
            ctx.lineWidth = yuan.r;
            ctx.moveTo(last.x,last.y);
            ctx.lineTo(yuan.x,yuan.y);
            ctx.stroke();
            ctx.closePath();
        }
 

 
9. 设置定时器,同时实现线条尾部慢慢消失效果:
 
setInterval(function(){
             /*  ctx.clearRect(0,0,kuan,gao); */
             /* 不直接用clearRect让上一帧内容全部变透明,而是逐渐给上一帧
             蒙上一层有点透明的当前背景色,这样一帧一帧的叠加,最开始的线段
             会逐渐与背景融合变得相当与消失 */
             ctx.fillStyle = "rgba(0,0,0,0.1)"; 
             ctx.fillRect(0,0,kuan,gao); 
             update(); 
          /*  draw(); */ 
        },20)
 

 
完整代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
      body{
          background-color: rgb(0, 0, 0);
        
      }
      canvas{
          display: block;
      }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
         var canvas = document.querySelector("#canvas");
         var ctx = canvas.getContext("2d");
       // 画布宽与高
        var kuan=0,gao=0;    
        var num=25;
        var arr=[];
        var colors = ["#2196F3","#1976D2","#00BCD4","#4CAF50","#FF5252","#E040FB"];
        window.onresize=resizeCanvas;
        function resizeCanvas(){
            kuan=canvas.width=window.innerWidth;
            gao=canvas.height=window.innerHeight;
        }
        resizeCanvas(); 
        var mouseX = kuan/2,mouseY = gao/2;
        for(let i=0;i<num;i++){
            arr.push({
               /*  x: kuan/2,
                y: gao/2, */
                r: Math.random()*(5-3) + 3,
                color: colors[parseInt(Math.random()*6)],
                 /* 旋转开始角度 */
                rot: Math.random()*2*Math.PI,
                /* 旋转小球距离中心距离 */
                distance: Math.random() * (75 - 40) + 40,
                /* 记录初始位置,鼠标拖拽时做缓动动画用 */
                lastMouse:{
                    x:kuan/2,
                    y:gao/2
                }
            })
        }
        function draw(last) {
           /*  for(let i=0;i<num;i++){ */ 
            var yuan = arr[last.i]; 
            ctx.beginPath();
            /* ctx.fillStyle = yuan.color; 
            ctx.arc(yuan.x,yuan.y,yuan.r, 0,Math.PI* 2, false);
            ctx.fill(); */
            ctx.strokeStyle = yuan.color;
            ctx.lineWidth = yuan.r;
            ctx.moveTo(last.x,last.y);
            ctx.lineTo(yuan.x,yuan.y);
            ctx.stroke();
            ctx.closePath();
           /*  } */ 
        }
          
         window.addEventListener('mousemove',function(event){
               mouseX = event.clientX;
               mouseY = event.clientY;               
         })       
        /*  var moveX=kuan/2,moveY=gao/2; */
         function update (){
            for(let i=0;i<num;i++){
                /* 传当前绘制的第i个的线的绘制前一帧的位置和当前i保存 */
               let last ={x:arr[i].x,y:arr[i].y,i:i};             
            /* 移动后位置 = 当前位置 + (移动后位置-当前位置)*0.05 缓动动画原理 */
                arr[i].lastMouse.x+=(mouseX-arr[i].lastMouse.x)*0.05;
                arr[i].lastMouse.y+=(mouseY-arr[i].lastMouse.y)*0.05;
               arr[i].rot+=0.1;
                arr[i].x = arr[i].lastMouse.x + Math.cos(arr[i].rot)*arr[i].distance;
                arr[i].y = arr[i].lastMouse.y + Math.sin(arr[i].rot)*arr[i].distance;
                 /* 位置改变,把last传给draw,画线 */
                draw(last);
            }
         }
        setInterval(function(){
             /*  ctx.clearRect(0,0,kuan,gao); */
             /* 不直接用clearRect让上一帧内容全部变透明,而是逐渐给上一帧
             蒙上一层有点透明的当前背景色,这样一帧一帧的叠加,最开始的小球
             会逐渐与背景融合变得相当与消失 */
             ctx.fillStyle = "rgba(0,0,0,0.1)"; 
             ctx.fillRect(0,0,kuan,gao); 
             update(); 
          /*  draw(); */ 
        },20)
    </script>
</body>
</html>
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
你可能感兴趣的内容