Maison  >  Article  >  interface Web  >  Partager des exemples de la façon dont Canvas implémente l'animation de pluie

Partager des exemples de la façon dont Canvas implémente l'animation de pluie

小云云
小云云original
2018-03-09 10:49:421938parcourir

J'ai vu une animation d'effet de pluie réalisée avec Canvas sur codepen, qui était assez intéressante. J'ai fait quelques recherches et je partagerai ici les techniques de mise en œuvre.

Capture d'écran de l'effet :

Bases de l'animation sur toile

Vous le savez, Canvas n’est en réalité qu’une planche à dessin. Nous pouvons utiliser l'API Canvas pour y dessiner divers graphiques.

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

Ensuite, les étapes pour dessiner une animation avec Canvas sont :

  1. Dessinez la première image graphique (à l'aide du dessin API)

  2. Effacez le plan de travail (appliquez clearRect() ou fillRect())

  3. Dessiner la prochaine image d'animation

Qu'est-ce qui est utilisé pour contrôler le temps de dessin de chaque image d'animation ? Il est facile pour tout le monde de penser à window.setInterval() et window.setTimeout(). Oui, vous pouvez également utiliser ces deux-là. De plus, une nouvelle méthode est apparue plus tard : window.requestAnimationFrame(callback).

requestAnimationFrame indique au navigateur que vous souhaitez dessiner une animation. Laissez le navigateur appeler votre méthode spécifiée (rappel) pour dessiner votre animation lorsqu'il souhaite la redessiner.

La méthode d'utilisation est la suivante :


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

Généralement, l'utilisation de requestAnimationFrame en premier peut maintenir la fréquence de dessin de l'animation cohérente avec la fréquence de redessin du navigateur. . Malheureusement, la compatibilité de requestAnimationFrame n'est pas encore très bonne. IE9 et versions antérieures et Addroid 4.3 et versions antérieures ne semblent pas prendre en charge cet attribut. Les navigateurs qui ne le prennent pas en charge doivent utiliser setInterval ou setTimeout pour des raisons de compatibilité.

Effet de chute de goutte de pluie

Tout d'abord, parlons de la façon de créer l'effet de chute de goutte de pluie. La goutte de pluie est en fait un rectangle, puis l'image rémanente est ajoutée. Le dessin des images rémanentes peut être considéré comme la clé pour savoir où se trouvent les gouttes de pluie. L'image rémanente est un effet produit en dessinant un arrière-plan translucide et un rectangle à chaque image dans le sens avant, puis en superposant les graphiques précédemment dessinés. Étant donné que les graphiques vers l'avant sont dessinés en dernier, ils apparaissent plus clairs et les graphiques vers l'arrière sont davantage superposés, ils sont donc visuellement affaiblis. Le tout ressemble à une image rémanente. La clé ici est de dessiner un fond transparent, sinon l'effet de superposition ne sera pas produit.

Ensuite, dessinons une goutte de pluie. Préparez d'abord une planche à dessin :

code 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>

Je dessine l'animation dans le fichier js (raindrop.js), le code est comme suit :


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();

Effet d'entraînement

Dessinez ensuite l'effet d'entraînement. Semblable à la manière de dessiner des gouttes de pluie, l’effet d’ombre intérieure est produit en superposant l’image précédente avec un fond transparent.

Le code est le suivant (rippling.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();

Résumé

Par ici tout le monde peut comprendre l'ensemble. Vous devez avoir une certaine compréhension de la façon de créer des effets de pluie. L'effet de Canvas utilisé pour dessiner des animations est vraiment accrocheur et améliore considérablement l'effet visuel du Web. Utilisez votre propre sagesse et je crois que vous pouvez créer des animations encore plus merveilleuses. C'est une des raisons pour lesquelles j'aime de plus en plus le web O(∩_∩)O~~.

Recommandations associées :

Parler de Canvas combiné avec JavaScript pour obtenir des effets spéciaux d'image

Carte interactive des lignes de métro HTML5 Canvas code d'implémentation

Comment utiliser Canvas pour traiter des images

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn