canvas水波纹

轻戳预览

现在的水波纹效果,很多场景还是可以看到,这里用canvas实现一个类似的效果
思路:其实就是2个贝塞尔曲线填充2种不同颜色,然后动态改变贝塞尔的2个控制点,制造一个波纹的效果

代码比较简单,废话不多少,直接贴Demo吧
HTML:

<style>
    html,body{
        height: 100%;
        margin:0;
        background: grey;
    }
    canvas{
        width: 100%;
        height: 100%;
    }
</style>
<body>
    <canvas id="canvas"></canvas>
</body>

JS:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var _width = canvas.width = canvas.offsetWidth;
var _height = canvas.height = canvas.offsetHeight;
var leftDot = rightDot = _height * 0.7  //起始点和终点高度
var leftDotSpeed = 0.2;
var rightDotSpeed = 0.16;
var n = 0;
window.requestAnimationFrame =  window.requestAnimationFrame ||
                                window.mozRequestAnimationFrame ||
                                window.webkitRequestAnimationFrame ||
                                window.msRequestAnimationFrame;

run();
function drawSun(){
    var color = ctx.createRadialGradient(_width/2,_height*0.6,1,_width/2,_height*0.8,600);
    color.addColorStop(0,'red');
    color.addColorStop(.2,'#fff');
    color.addColorStop(0.5,'lightgrey');
    color.addColorStop(1,'grey');
    ctx.beginPath();
    ctx.arc(_width/2, _height*0.8, 600, 0, 2*Math.PI);
    ctx.fillStyle = color;
    ctx.fill();
}
function drawWater(n,color, leftDot, rightDot){
    var angle = n * Math.PI / 180;
    var deltaHeight = Math.sin(angle) * _height / 8;
    var deltaHeightRight = Math.cos(angle) * _height / 7;
    ctx.beginPath();
    ctx.moveTo(0, leftDot);
    ctx.bezierCurveTo(_width / 4, leftDot + deltaHeight, _width * 3 / 4, rightDot + deltaHeightRight, _width, rightDot);
    ctx.lineTo(_width, _height);
    ctx.lineTo(0, _height); //使得下半个矩形闭合
    ctx.fillStyle = color;
    ctx.fill();
}
function run() {
    ctx.clearRect(0, 0, _width, _height);
    n+=1;
    leftDot += leftDotSpeed
    rightDot += rightDotSpeed
    if(leftDot>_height*0.8 || leftDot<_height*0.6){
        leftDotSpeed *= -1
    }
    if(rightDot>_height*0.8 || rightDot<_height*0.6){
        rightDotSpeed *= -1
    }
    drawSun()
    drawWater(n+50,'lightcyan', leftDot, rightDot)
    drawWater(n,'cyan', leftDot, rightDot)
    requestAnimationFrame(run);
}