超酷!!HTML5 Canvas 水流樣式 Loading 動畫

前端新世界發表於2022-04-16

今天我們要分享另外一款基於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動畫繪製物件,結合簡單的數學三角函式組合,如果你覺得不錯,點個贊吧!

相關文章