ホームページ  >  記事  >  ウェブフロントエンド  >  Canvas に雨のアニメーションを実装する方法の例を共有する

Canvas に雨のアニメーションを実装する方法の例を共有する

小云云
小云云オリジナル
2018-03-09 10:49:421940ブラウズ

codepenのCanvasで作った雨エフェクトアニメーションを見ましたが、なかなか面白かったです。いくつか調査を行ったので、ここで実装テクニックを共有します。

エフェクトのスクリーンショット:

キャンバスアニメーションの基本

ご存知のとおり、キャンバスは実際には単なる製図板です。 Canvas API を使用して、さまざまなグラフィックを描画できます。

Canvas 2D API: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D

Canvas 描画アニメーションの手順は次のとおりです:

  1. グラフィックスの最初のフレームを描画します ( API 描画)

  2. アートボードをクリアします (clearRect() または fillRect() を適用します)

  3. アニメーションの次のフレームを描画します

アニメーションの各フレームの描画時間を制御するには何を使用しますか? window.setInterval() と window.setTimeout() は誰でも簡単に思いつくでしょう。はい、この 2 つを使用することもできます。さらに、後に新しいメソッド window.requestAnimationFrame(callback) が登場しました。

requestAnimationFrame はブラウザにアニメーションを描画したいことを伝えます。ブラウザが再描画したいときに、指定したメソッド (コールバック) を呼び出してアニメーションを描画できるようにします。

使い方は以下の通りです:


function anim() {
    ctx.fillStyle = clearColor;
    ctx.fillRect(0,0,w,h);
    for(var i in drops){
        drops[i].draw();
    }
    requestAnimationFrame(anim);
}

一般的にはアニメーションの描画頻度とブラウザの再描画頻度を一致させるためにrequestAnimationFrameを使用することが優先されます。残念ながら、requestAnimationFrame の互換性はまだあまり良くありません。 IE9 以下および addroid 4.3 以下はこの属性をサポートしていないようです。これをサポートしていないブラウザでは、互換性を確保するために setInterval または setTimeout を使用する必要があります。

雨粒が落ちるエフェクト

まず、雨粒が落ちるエフェクトの作成方法について説明します。雨粒は実際には長方形であり、そこに残像が追加されます。残像の描き方が雨粒の行方を知る鍵と言える。残像とは、半透明の背景と四角形をフレームごとに順方向に描画し、それまでに描画したグラフィックスを重ね合わせることで発生するエフェクトです。前方向のグラフィックが最後に描画されるため明るく見え、後ろのグラフィックが多く重なるため視覚的に弱くなっています。全体が残像のように見えます。ここで重要なのは、透明な背景を描画することです。そうしないと、オーバーレイ効果が生成されません。

それでは雨粒を描いてみましょう。まず描画ボードを準備します:

html コード:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>霓虹雨</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <style type="text/css">
        .bg {
            background: #000;
            overflow: hidden;
        }
    </style>

</head>
<body class="bg">
<canvas id="canvas-club"></canvas>
<script type="text/javascript" src="raindrop.js"></script>
</body>
</html>

js ファイルにアニメーション (raindrop.js) を描画します。コードは次のとおりです:


var c = document.getElementById("canvas-club");
var ctx = c.getContext("2d");//获取canvas上下文
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;//设置canvas宽、高
var clearColor = &#39;rgba(0, 0, 0, .1)&#39;;//画板背景,注意最后的透明度0.1 这是产生叠加效果的基础

function random(min, max) {
    return Math.random() * (max - min) + min;
}

function RainDrop(){}
//雨滴对象 这是绘制雨滴动画的关键
RainDrop.prototype = {
    init:function(){
        this.x =  random(0, w);//雨滴的位置x
        this.y = 0;//雨滴的位置y
        this.color = &#39;hsl(180, 100%, 50%)&#39;;//雨滴颜色 长方形的填充色
        this.vy = random(4, 5);//雨滴下落速度
        this.hit = random(h * .8, h * .9);//下落的最大值
        this.size = 2;//长方形宽度
    },
    draw:function(){
        if (this.y < this.hit) {
            ctx.fillStyle = this.color;
            ctx.fillRect(this.x, this.y, this.size, this.size * 5);//绘制长方形,通过多次叠加长方形,形成雨滴下落效果
        }
        this.update();//更新位置
    },
    update:function(){
        if(this.y < this.hit){
            this.y += this.vy;//未达到底部,增加雨滴y坐标
        }else{
            this.init();
        }
    }
};

function resize(){
    w = c.width = window.innerWidth;
    h = c.height = window.innerHeight;
}

//初始化一个雨滴
var r = new RainDrop();
r.init();

function anim() {
    ctx.fillStyle = clearColor;//每一帧都填充背景色
    ctx.fillRect(0,0,w,h);//填充背景色,注意不要用clearRect,否则会清空前面的雨滴,导致不能产生叠加的效果
    r.draw();//绘制雨滴
    requestAnimationFrame(anim);//控制动画帧
}

window.addEventListener("resize", resize);
//启动动画
anim();

波及効果

次に波及効果を引き出します。雨滴の描き方と同様に、背景を透明にした前の画像を重ねることでインナーシャドウの効果が生まれます。

コードは以下の通りです(ripped.js):


var c = document.getElementById("canvas-club");
var ctx = c.getContext("2d");//获取canvas上下文
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;//设置canvas宽、高
var clearColor = &#39;rgba(0, 0, 0, .1)&#39;;//画板背景,注意最后的透明度0.1 这是产生叠加效果的基础

function random(min, max) {
    return Math.random() * (max - min) + min;
}

function Rippling(){}
//涟漪对象 这是涟漪动画的主要部分
Rippling.prototype = {
    init:function(){
        this.x = random(0,w);//涟漪x坐标
        this.y = random(h * .8, h * .9);//涟漪y坐标
        this.w = 2;//椭圆形涟漪宽
        this.h = 1;//椭圆涟漪高
        this.vw = 3;//宽度增长速度
        this.vh = 1;//高度增长速度
        this.a = 1;//透明度
        this.va = .96;//涟漪消失的渐变速度
    },
    draw:function(){
        ctx.beginPath();
        ctx.moveTo(this.x, this.y - this.h / 2);
        //绘制右弧线
        ctx.bezierCurveTo(
            this.x + this.w / 2, this.y - this.h / 2,
            this.x + this.w / 2, this.y + this.h / 2,
            this.x, this.y + this.h / 2);
        //绘制左弧线
        ctx.bezierCurveTo(
            this.x - this.w / 2, this.y + this.h / 2,
            this.x - this.w / 2, this.y - this.h / 2,
            this.x, this.y - this.h / 2);
        
        ctx.strokeStyle = &#39;hsla(180, 100%, 50%, &#39;+this.a+&#39;)&#39;;
        ctx.stroke();
        ctx.closePath();
        this.update();//更新坐标
    },
    update:function(){
        if(this.a > .03){
            this.w += this.vw;//宽度增长
            this.h += this.vh;//高度增长
            if(this.w > 100){
                this.a *= this.va;//当宽度超过100,涟漪逐渐变淡消失
                this.vw *= .98;//宽度增长变缓慢
                this.vh *= .98;//高度增长变缓慢
            }
        } else {
            this.init();
        }

    }
};

function resize(){
    w = c.width = window.innerWidth;
    h = c.height = window.innerHeight;
}

//初始化一个涟漪
var r = new Rippling();
r.init();

function anim() {
    ctx.fillStyle = clearColor;
    ctx.fillRect(0,0,w,h);
    r.draw();
    requestAnimationFrame(anim);
}

window.addEventListener("resize", resize);
//启动动画
anim();

概要

このようにして、誰もが雨エフェクトの制作方法全体をある程度理解できるはずです。アニメーションの描画に使用される Canvas の効果は確かに目を引き、Web の視覚効果を大幅に向上させます。自分の知恵を絞れば、もっと素晴らしいアニメーションが作れると思います。これがウェブがますます好きになった理由の一つですO(∩_∩)O~~。

関連する推奨事項:

画像の特殊効果を実現するための JavaScript と組み合わせた Canvas について説明します

HTML5 Canvas インタラクティブな地下鉄路線図の実装コード

Canvas を使用して画像を処理する方法

以上がCanvas に雨のアニメーションを実装する方法の例を共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。