html5Canvas动画实现球内波浪效果

前言

先自己动手通过Canvas实现的效果始终不很满意,后来在网上找了一些html5Canvas实现的类似的波浪效果,但都没有我想要的,最后在github上找到一个我想要的类似效果,只不过这个是在长方形内的波浪,然后我根据例子的步骤,改成在圆球内实现波浪的效果,这个过程发现初高中学的那点知识也忘得差不多了,用到还要搜索下才能想起来,虽然最后效果还是不太满意,没有被采纳,不过还是把过程分享出来吧。

效果


先画个最简单的圆

<canvas id="myCanvas" width="200" height="200" style="margin:20px;"></canvas>


<span style="white-space:pre">	</span>var ctx = document.getElementById('myCanvas').getContext('2d');
<span style="white-space:pre">	</span>ctx.lineWidth = 1;
        ctx.strokeStyle = "orange";
        ctx.arc(100,100,90,0,2*Math.PI,false);
        ctx.stroke();


在圆内上下滚动的线


var ctx = document.getElementById('myCanvas').getContext('2d');
      

      var y = 100;
      var flag = 0;

      function init(){

        //清空canvas
        ctx.clearRect(0,0,200,200);

        //计算在左半圆上随着y值上下移动,对应的x值
        // var y = 30;
        var expression = 8100 - Math.pow((100-y),2);
        var x = 100 - Math.sqrt(expression) ;

        ctx.beginPath();

        ctx.lineWidth = 1;
        ctx.strokeStyle = "orange";
        ctx.arc(100,100,90,0,2*Math.PI,false);

        ctx.stroke();

        ctx.lineWidth = 1;
        ctx.strokeStyle = "green";
        ctx.beginPath();
        ctx.moveTo(x,y);
        ctx.lineTo(200-x, y);
        ctx.stroke();


        if (flag == 0) {
          y += 1;
          if(y == 130){
            flag = 1;
          }
        }else{
          y -= 1;
          if (y == 70) {
            flag = 0;
          }
        }

        window.requestAnimationFrame(init);
      }

模拟水在整个球内起伏


var ctx = document.getElementById('myCanvas').getContext('2d');
      

      var y = 100;
      var flag = 0;

      function init(){

        //清空canvas
        ctx.clearRect(0,0,200,200);

        //计算在左半圆上随着y值上下移动,对应的x值
        var expression = 8100 - Math.pow((100-y),2);
        var x = 100 - Math.sqrt(expression) ;

        ctx.lineWidth = 1;
        ctx.strokeStyle = "green";
        ctx.beginPath();
        ctx.moveTo(x,y);
        ctx.lineTo(200-x, y);

        ctx.stroke();
        //计算圆起始点(与X轴平行的直径的右侧端点)与圆左侧给定Y坐标的点
        var distance = Math.sqrt(Math.pow((190-x),2)+Math.pow((100-y),2));

        //sina=d/2r   a为夹角的一半  2a为两点的圆心角   Math.asin最终结果为弧度 如asin(1)=1/2*PI
        var angle = Math.asin(distance/180)*2;

        ctx.beginPath();

        if(y<100){
          angle = 2*Math.PI - angle;
        }

        ctx.arc(100,100,90,Math.PI-angle,angle,false);


        ctx.stroke();

        if (flag == 0) {
          y += 1;
          if(y == 150){
            flag = 1;
          }
        }else{
          y -= 1;
          if (y == 50) {
            flag = 0;
          }
        }

        window.requestAnimationFrame(init);

      }

模拟球两边的起伏不同步


var ctx = document.getElementById('myCanvas').getContext('2d');
      

      var step = 0;

      function init(){

        //清空canvas
        ctx.clearRect(0,0,200,200);

        step++;
        //转化为弧度
        var stepAngle = step*Math.PI/180;
        var  deltaHeight = Math.sin(stepAngle)*30;

        var deltaHeightRight = Math.cos(stepAngle)*30;

         var y = 100 + deltaHeight;

        //计算在左半圆上随着y值上下移动,对应的x值
       
        var expression = 8100 - Math.pow((100-y),2);
        var x = 100 - Math.sqrt(expression) ;


        var rightY = 100 + deltaHeightRight;
        var expressionRight = 8100 - Math.pow((100-rightY),2);
        //取右侧的X坐标(同一个y值会有两个x坐标)
        var rightX = 200 - (100 - Math.sqrt(expressionRight));
        // alert("rightX:"+rightX+" rightY:"+rightY+" x:"+x+" y:"+y);

        ctx.lineWidth = 1;
        ctx.strokeStyle = "green";
        ctx.fillStyle = "green";
        ctx.beginPath();
        ctx.moveTo(x,y);
        ctx.lineTo(rightX, rightY);
        ctx.stroke();

        //计算圆起始点(与X轴平行的直径的右侧端点)与圆左侧给定Y坐标的点
        var distance = Math.sqrt(Math.pow((190-x),2)+Math.pow((100-y),2));
        //sina=d/2r   a为夹角的一半  2a为两点的圆心角   Math.asin最终结果为弧度 如asin(1)=1/2*PI
        var angle = Math.asin(distance/180)*2;


        var distanceRight = Math.sqrt(Math.pow((190-rightX),2)+Math.pow((100-rightY),2));
        var angleRight = Math.asin(distanceRight/180)*2;

        ctx.beginPath();

        //如果在左侧上半圆则用2PI-弧度
        if(y<100){
          angle = 2*Math.PI - angle;
        }

        if(rightY < 100){
          angleRight = -angleRight;
        }

        ctx.arc(100,100,90,angleRight,angle,false);

        ctx.stroke();
        // ctx.fill();

        window.requestAnimationFrame(init);

      }

把起伏的直线改成曲线(见开头的效果图)

var ctx = document.getElementById('myCanvas').getContext('2d');
      

      var step = 0;

      function init(){

        //清空canvas
        ctx.clearRect(0,0,200,200);

        step+=3;
        //转化为弧度
        var stepAngle = step*Math.PI/180;
        var  deltaHeight = Math.sin(stepAngle)*20;

        var deltaHeightRight = Math.cos(stepAngle)*20;

         var y = 100 + deltaHeight;

        //计算在左半圆上随着y值上下移动,对应的x值
       
        var expression = 8100 - Math.pow((100-y),2);
        var x = 100 - Math.sqrt(expression) ;


        var rightY = 100 + deltaHeightRight;
        var expressionRight = 8100 - Math.pow((100-rightY),2);
        //取右侧的X坐标(同一个y值会有两个x坐标)
        var rightX = 200 - (100 - Math.sqrt(expressionRight));
        // alert("rightX:"+rightX+" rightY:"+rightY+" x:"+x+" y:"+y);

        ctx.lineWidth = 5;
        ctx.strokeStyle = "green";
        ctx.beginPath();
        ctx.arc(100,100,90,0,Math.PI*2,false);
        ctx.stroke();
        
        
        // ctx.fillStyle = "green";
        ctx.fillStyle = "rgba(0,222,255, 0.2)";
        ctx.beginPath();
        ctx.moveTo(x,y);
        // ctx.lineTo(rightX, rightY);
        ctx.bezierCurveTo(100, y-30, 100, rightY-30, rightX,rightY);
        // ctx.stroke();

        //计算圆起始点(与X轴平行的直径的右侧端点)与圆左侧给定Y坐标的点
        var distance = Math.sqrt(Math.pow((190-x),2)+Math.pow((100-y),2));
        //sina=d/2r   a为夹角的一半  2a为两点的圆心角   Math.asin最终结果为弧度 如asin(1)=1/2*PI
        var angle = Math.asin(distance/180)*2;


        var distanceRight = Math.sqrt(Math.pow((190-rightX),2)+Math.pow((100-rightY),2));
        var angleRight = Math.asin(distanceRight/180)*2;

        // ctx.beginPath();

        //如果在左侧上半圆则用2PI-弧度
        if(y<100){
          angle = 2*Math.PI - angle;
        }

        if(rightY < 100){
          angleRight = -angleRight;
        }

        ctx.arc(100,100,90,angleRight,angle,false);

        // ctx.stroke();
        ctx.fill();

        window.requestAnimationFrame(init);

      }

下载链接

http://download.csdn.net/detail/yyy269954107/8419367

参考

https://github.com/cyclegtx/wave_background

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值