• 超酷!!HTML5 Canvas 水流样式 Loading 动画


    今天我们要分享另外一款基于HTML5 Canvas的液体流动样式Loading加载动画,这款Loading动画在加载时会呈现液体流动的动画效果,并且由于和背景颜色的对比,也略微呈现发光的动画效果。

    效果预览

    image

    代码实现

    HTML代码

    接下来我们讲讲实现这个加载动画的大致思路和实现过程。

    首先在页面上定义一个canvas元素,用来承载这个Loading动画的画布。

    <canvas id='canvas'></canvas>
    

    接下拉需要定义一个SVG滤镜,这个滤镜用来渲染Loading圈圈粒子化的效果。

    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <defs>
            <filter id="shadowed-goo">
                 <feGaussianBlur in="SourceGraphic" result="blur" stdDeviation="10" />
                 <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7" result="goo" />
                 <feGaussianBlur in="goo" stdDeviation="3" result="shadow" />
                 <feColorMatrix in="shadow" mode="matrix" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 1 -0.2" result="shadow" />
                 <feOffset in="shadow" dx="1" dy="1" result="shadow" />
                 <feBlend in2="shadow" in="goo" result="goo" />
                 <feBlend in2="goo" in="SourceGraphic" result="mix" />
            </filter>
            <filter id="goo">
                 <feGaussianBlur in="SourceGraphic" result="blur" stdDeviation="10" />
                 <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7" result="goo" />
                 <feBlend in2="goo" in="SourceGraphic" result="mix" />
            </filter>
        </defs>
    </svg>
    

    CSS代码

    这里我们先不谈页面中其他元素的样式,我们的重点是为canvas元素指定相应的svg滤镜:

    #canvas {
    	margin: 0px auto;
    	display: block;
    	filter: url("#shadowed-goo");
    }
    

    JavaScript代码

    然后用JavaScript代码实现Loading加载动画。这里用到了canvas的2d动画绘制对象:

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    

    getContext()方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。

    这个动画的核心是动态画一段弧线,代码如下:

    ctx.fillStyle = "rgba(255,255,255," + this.al + ")";
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    ctx.fill();
    

    下面是完整的JS代码:

    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var p = [];
    var particle = [];
    var angle = Math.PI/4;
    canvas.width = 600;
    canvas.height = 600;
    var width = canvas.width;
    var height = canvas.height;
    
    function getRandomInt(min, max) {
    	return min + Math.floor(Math.random() * (max - min + 1));
    }
    
    function retinaReady() {
    	var pixelRatio = window.devicePixelRatio || 1;
    	var backingStore = ctx.webkitBackingStorePixelRatio || 1;
    	window.ratio = pixelRatio / backingStore; // public var
    	if (pixelRatio !== backingStore) {
    		var oldWidth = canvas.width;
    		var oldHeight = canvas.height;
    		canvas.width = oldWidth * ratio;
    		canvas.height = oldHeight * ratio;
    		canvas.style.width = oldWidth + "px";
    		canvas.style.height = oldHeight + "px";
    		ctx.scale(window.ratio, window.ratio);
    	}
    }
    retinaReady();
    function run(a) {
    	var r = 140;
    	var x = r * Math.sin(a) + width / 2;
    	var y = r * Math.cos(a) + ((height / 2)-80);
    	var p;
    	p = new Particle(x, y);
    	particle.push(p);
    }
    
    function Particle(x, y) {
    	this.x = x;
    	this.y = y;
    	this.r = getRandomInt(10, 16);
    	this.v = {
    		x: 0,
    		y: 0
    	};
    	this.a = {
    		x: 0,
    		y: 0
    	};
    	this.al = 1;
    }
    
    Particle.prototype.update = function() {
    	this.a.x = getRandomInt(-0.001, 0.001);
    	this.a.y = getRandomInt(0.01, 0.02);
    	this.v.x += this.a.x;
    	this.v.y += this.a.y;
    	this.x += this.v.x;
    	this.y += this.v.y;
    
    	if (this.r >= 0.01) {
    		this.r -= 0.2;
    		this.al -= 0.001;
    	} else {
    		this.r = 0;
    		this.al = 0;
    	}
    };
    
    Particle.prototype.draw = function() {
    	ctx.fillStyle = "rgba(255,255,255," + this.al + ")";
    	ctx.beginPath();
    	ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
    	ctx.fill();
    };
    
    function animate() {
    	ctx.clearRect(0, 0, width, height);
    	run(angle);
    	requestAnimationFrame(animate);
    	for (var j = 0; j < particle.length; j++) {
    		var p = particle[j];
    		p.update();
    		p.draw();
    	}
    
    	if (angle <= 2 * Math.PI) {
    		angle += 0.04;
    	} else {
    		angle = 0;
    	}
    }
    animate();
    

    到这里为止,这个粒子流体状的Loading加载动画就完成了,文章最后也将源码献给大家。

    源码下载

    完整的代码我已经整理出了一个源码包,供大家下载学习。

    关注我的公众号“前端技术官”,回复关键字:3005,即可获取源码下载链接。

    代码仅供参考和学习,请不要用于商业用途。

    最后总结

    这个Loading动画我们主要用到了SVG滤镜知识,以及HTML5 Canvas的2d动画绘制对象,结合简单的数学三角函数组合,如果你觉得不错,点个赞吧!

  • 相关阅读:
    搭建 mariadb 数据库主从同步
    MySQL--MVCC
    剑指 Offer 07. 重建二叉树
    剑指 Offer 06. 从尾到头打印链表
    MySQL--数据库范式
    剑指 Offer 05. 替换空格
    剑指 Offer 04. 二维数组中的查找
    剑指offer_03_数组中重复的数字(Java)
    Redis
    MySQL--SQL执行过程
  • 原文地址:https://www.cnblogs.com/frontworld/p/16153447.html
Copyright © 2020-2023  润新知