three.js和画布实现信号光圈动画

实现效果
信号光圈由中心向外发散,并逐渐消失。
image

实现思路
使用画布制作光圈,以画布作为纹理,在循环渲染函数中改变mesh的尺寸和透明度。

具体实现

1、画布制作光圈
image

 //创建画布
    var canvas = document.createElement('canvas');
    //设置画布大小
    canvas.width = 300;
    canvas.height=300;
    //2.获取在 canvas 上绘图的 canvasRenderingContent2D 对象。这两行是必不可少的哦
    var ctx=canvas.getContext("2d");

    //3.绘制
    //第一圈
    ctx.beginPath();//开始绘制
    ctx.lineWidth = 2;//线的宽度
    ctx.arc(150,150,1,0,2*Math.PI);//arc 的意思是“弧”
    ctx.fillStyle = 'rgba(255, 255, 255, 0)';//画布背景
    ctx.strokeStyle="#00ff00";//将线条颜色设置为蓝色
    ctx.stroke();//stroke() 方法默认颜色是黑色(如果没有上面一行,则会是黑色)。
    ctx.closePath();//结束绘制

    //第二圈
    ctx.beginPath();//开始绘制
    ctx.lineWidth = 2;//线的宽度
    ctx.arc(150,150,30,0,2*Math.PI);//arc 的意思是“弧”
    ctx.fillStyle = 'rgba(255, 255, 255, 0)';//画布背景
    ctx.strokeStyle="#5CFF5C";//将线条颜色设置为蓝色
    ctx.stroke();//stroke() 方法默认颜色是黑色(如果没有上面一行,则会是黑色)。
    ctx.closePath();//结束绘制

    //第三圈
    ctx.beginPath();//开始绘制
    ctx.lineWidth = 2;//线的宽度
    ctx.arc(150,150,60,0,2*Math.PI);//arc 的意思是“弧”
    ctx.fillStyle = 'rgba(255, 255, 255, 0)';//画布背景
    ctx.strokeStyle="#97FF97";//将线条颜色设置为蓝色
    ctx.stroke();//stroke() 方法默认颜色是黑色(如果没有上面一行,则会是黑色)。
    ctx.closePath();//结束绘制

    //第四圈
    ctx.beginPath();//开始绘制
    ctx.lineWidth = 2;//线的宽度
    ctx.arc(150,150,90,0,2*Math.PI);//arc 的意思是“弧”
    ctx.fillStyle = 'rgba(255, 255, 255, 0)';//画布背景
    ctx.strokeStyle="#BDFFBD";//将线条颜色设置为蓝色
    ctx.stroke();//stroke() 方法默认颜色是黑色(如果没有上面一行,则会是黑色)。
    ctx.closePath();//结束绘制

2、动画光圈实现(主要代码)

 /**
  * 发送信号光圈
  */
  var mesh;
    function signalLightCanvas(){
        //创建画布
        var canvas = document.createElement('canvas');
    	.....(实现画布看`画布制作多圆嵌套`)

		//画布作为纹理
        var canvas_texture = new THREE.CanvasTexture(canvas);
        canvas_texture.needsUpdate = true;
        var canvas_geometry = new THREE.PlaneBufferGeometry (10,10);
        var canvas_material = new THREE.MeshBasicMaterial({
        map:canvas_texture,
        transparent:true,
        side:THREE.DoubleSide,
        depthWrite:false
        });
		mesh = new THREE.Mesh(canvas_geometry,canvas_material);
         mesh.position.set(posArr[i].x,posArr[i].y,posArr[i].z);
        scene.add(mesh);
      }
    }
    
    //渲染函数中:改变mesh的尺寸和透明度
    function animate() {
        window.requestAnimationFrame(() => {
           
            
            //光圈动画
            var size = 0.03;//可自行更改
            if (mesh) {
                mesh._s += 0.007;
                mesh.scale.set( size* mesh._s, size * mesh._s,size * mesh._s );
                if (mesh._s <= 1.5) {
                  //mesh._s=1,透明度=0 mesh._s=1.5,透明度=1
                  mesh.material.opacity = ( mesh._s - 1 ) * 2;
                } else if (mesh._s > 1.5 && mesh._s <= 2) {
                  //mesh._s=1.5,透明度=1 mesh._s=2,透明度=0
                  mesh.material.opacity = 1 - ( mesh._s - 1.5 ) * 2;
                } else {
                  mesh._s = 1.0;
                }
            }

            renderer.clear();
        	renderer.render( scene, camera );
            animate();
        });
    }

posted @ 2022-09-06 11:33  huangchun0121  阅读(734)  评论(0编辑  收藏  举报