zoukankan      html  css  js  c++  java
  • canvas绘制流星雨特效

    源码:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <meta name="keywords" content="一起来看流星雨">
    <meta name="description" content="流星雨效果">
    <title>canvas雨滴</title>
    <style>
    body {
    margin: 0
    }

    #rain {
    display: block;
    background: #33ffff;

    /* 100%;
    height: 100%; */
    }
    </style>
    </head>
    <body>
    <canvas id="rain"></canvas>
    <script>
    // 1.1 设置canvas元素的宽高与浏览器一样
    var can = document.getElementById("rain");
    // 1.2 获取浏览器宽高
    var w = window.innerWidth;
    var h = window.innerHeight;
    // 1.3 给canvas元素设置宽高
    can.width = w
    can.height = h
    // 1.4 当窗口大小发生变化的时候自动再调整canvas的宽高
    window.onresize = function() {
    w = window.innerWidth
    h = window.innerHeight
    can.width = w
    can.height = h
    }
    // 2 如何用canvas绘制图形 画布(卷轴 -> 宣纸)
    var canContent = can.getContext("2d") //拿到画画的宣纸

    function Rain() {} //生成雨滴的封装函数

    //随机函数,生成x和y的坐标
    function random(min, max) {
    return Math.random() * (max - min) + min
    }
    Rain.prototype = {
    init: function() {
    this.x = random(0, w) //雨滴初始的x坐标
    this.y = 0 //雨滴初始的y坐标
    this.v = random(4, 5) //下落加速度
    this.h = random(0.8 * h, 0.9 * h) //雨滴下落的地面
    this.r = 1//初始半径
    this.vr = random(0.4, 0.6) //半径增长率
    this.a = 1//初始透明度
    this.va = 0.96 // 透明度变化系数
    },
    draw: function() {
    if (this.y < this.h) {
    canContent.fillStyle = "#33ffff" //拿一只画实心图形的红色的笔
    canContent.fillRect(this.x, this.y, 2, 10) // 画一个实心的矩形
    } else {
    canContent.strokeStyle = "rgba(51,255,255," + this.a + ")"
    canContent.beginPath() //重新拿起笔
    canContent.arc(this.x, this.y, this.r, 0, Math.PI * 2)
    canContent.stroke();
    }

    },
    move: function() {
    if (this.y < this.h) {
    this.y += this.v
    } else {
    if (this.a > 0.02) {
    this.r += this.vr
    if(this.r > 50){
    this.a *= this.va
    }
    } else {
    this.init()
    }
    }
    this.draw()
    }
    }

    //复用性
    var rainArray = []

    function createRain() {
    var rain = new Rain()
    rain.init() //基本配置
    rain.draw()
    rainArray.push(rain)
    }
    createRain()
    for (var i = 0; i < 30; i++) {
    setTimeout(createRain, 200 * i)
    }

    function moveRain() {
    canContent.fillStyle = "rgba(0, 0, 0, 0.05)"
    canContent.fillRect(0, 0, w, h)
    for (var k = 0; k < rainArray.length; k++) {
    rainArray[k].move();
    }
    }
    function run(){
    moveRain()
    setTimeout(run, 100 / 60)
    }
    run()
    // setInterval(moveRain, 1000 / 60) //所有的计算和渲染必须在16ms内完成
    </script>
    </body>
    </html>

    分析:

      雨滴由rain函数创建,rain的原型上挂在的init、draw、move分别对应的是数据初始化、雨滴绘制、雨滴移动;

      雨滴其实是一个小长方形,每次产生一个遮罩层和一个小长方形,那么之前的小长方形会逐渐倍淡化直到看不见,这就产生了视觉上的错觉,形成了小雨滴的形态

      通过move反复改变小长方形的位置,并重新加遮罩层,并且绘制小长方形,就实现了下滴的感觉

      快到底部时停止绘制小长方形,但是遮罩层依旧存在,开始绘制小圆,并且小圆半径逐渐扩大,实现雨滴扩散的效果,当小圆半径扩大到一定程度时开始让小圆逐渐变得透明直到消失

     

    效果图:

      

  • 相关阅读:
    初识python: xlsxwriter 将数据写入Excel
    oracle 之 数组、嵌套表、SQL查询式 实现多表数据for循环插入指定表
    初识python:tkinter 实现 弹球小游戏(面向对象)
    初识python:tkinter 实现 弹球小游戏(非面相对象)
    初识python:scoket 单用户互发消息
    MagicNotes:如何迈向工作的坦途
    兴趣决定你成为什么样的人
    选择对了才去努力,努力了才能看到希望
    最健康的作息时间表与建议
    长期接受碎片化信息,会有什么后果?
  • 原文地址:https://www.cnblogs.com/MrZWJ/p/11983698.html
Copyright © 2011-2022 走看看