小刘除三害 發表於 2022-4-16 16:54:00

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

<p>今天我们要分享另外一款基于HTML5 Canvas的液体流动样式Loading加载动画,这款Loading动画在加载时会呈现液体流动的动画效果,并且由于和背景颜色的对比,也略微呈现发光的动画效果。</p>
<h2 id="效果预览">效果预览</h2>
<p><img src="https://img2022.cnblogs.com/blog/352752/202204/352752-20220416165033268-1992799181.gif"></p>
<h2 id="代码实现">代码实现</h2>
<p><strong>HTML代码</strong></p>
<p>接下来我们讲讲实现这个加载动画的大致思路和实现过程。</p>
<p>首先在页面上定义一个<code>canvas</code>元素,用来承载这个Loading动画的画布。</p>
<pre><code class="language-html">&lt;canvas id='canvas'&gt;&lt;/canvas&gt;
</code></pre>
<p>接下拉需要定义一个SVG滤镜,这个滤镜用来渲染Loading圈圈粒子化的效果。</p>
<pre><code class="language-html">&lt;svg xmlns="http://www.w3.org/2000/svg" version="1.1"&gt;
    &lt;defs&gt;
      &lt;filter id="shadowed-goo"&gt;
             &lt;feGaussianBlur in="SourceGraphic" result="blur" stdDeviation="10" /&gt;
             &lt;feColorMatrix in="blur" mode="matrix" values="1 0 0 0 00 1 0 0 00 0 1 0 00 0 0 18 -7" result="goo" /&gt;
             &lt;feGaussianBlur in="goo" stdDeviation="3" result="shadow" /&gt;
             &lt;feColorMatrix in="shadow" mode="matrix" values="0 0 0 0 00 0 0 0 00 0 0 0 00 0 0 1 -0.2" result="shadow" /&gt;
             &lt;feOffset in="shadow" dx="1" dy="1" result="shadow" /&gt;
             &lt;feBlend in2="shadow" in="goo" result="goo" /&gt;
             &lt;feBlend in2="goo" in="SourceGraphic" result="mix" /&gt;
      &lt;/filter&gt;
      &lt;filter id="goo"&gt;
             &lt;feGaussianBlur in="SourceGraphic" result="blur" stdDeviation="10" /&gt;
             &lt;feColorMatrix in="blur" mode="matrix" values="1 0 0 0 00 1 0 0 00 0 1 0 00 0 0 18 -7" result="goo" /&gt;
             &lt;feBlend in2="goo" in="SourceGraphic" result="mix" /&gt;
      &lt;/filter&gt;
    &lt;/defs&gt;
&lt;/svg&gt;
</code></pre>
<p><strong>CSS代码</strong></p>
<p>这里我们先不谈页面中其他元素的样式,我们的重点是为<code>canvas</code>元素指定相应的svg滤镜:</p>
<pre><code class="language-css">#canvas {
        margin: 0px auto;
        display: block;
        filter: url("#shadowed-goo");
}
</code></pre>
<p><strong>JavaScript代码</strong></p>
<p>然后用JavaScript代码实现Loading加载动画。这里用到了<code>canvas</code>的2d动画绘制对象:</p>
<pre><code class="language-javascript">var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
</code></pre>
<p><code>getContext()</code>方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。</p>
<p>这个动画的核心是动态画一段弧线,代码如下:</p>
<pre><code class="language-javascript">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();
</code></pre>
<p>下面是完整的JS代码:</p>
<pre><code class="language-javascript">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 &gt;= 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 &lt; particle.length; j++) {
                var p = particle;
                p.update();
                p.draw();
        }

        if (angle &lt;= 2 * Math.PI) {
                angle += 0.04;
        } else {
                angle = 0;
        }
}
animate();
</code></pre>
<p>到这里为止,这个粒子流体状的Loading加载动画就完成了,文章最后也将源码献给大家。</p>
<h2 id="源码下载">源码下载</h2>
<p>完整的代码我已经整理出了一个源码包,供大家下载学习。</p>
<blockquote>
<p>关注我的公众号“前端技术官”,回复关键字:<strong>3005</strong>,即可获取源码下载链接。</p>
</blockquote>
<p>代码仅供参考和学习,请不要用于商业用途。</p>
<h2 id="最后总结">最后总结</h2>
<p>这个Loading动画我们主要用到了SVG滤镜知识,以及HTML5 Canvas的2d动画绘制对象,结合简单的数学三角函数组合,如果你觉得不错,点个赞吧!</p><br><br>
来源:https://www.cnblogs.com/frontworld/p/16153447.html
頁: [1]
查看完整版本: 超酷!!HTML5 Canvas 水流样式 Loading 动画