canvas绘制雪花飘落效果丨技术开发分享录

canvas绘制雪花飘落效果

{{ detail.nickname }}

转载 翻译 {{ formatTime(detail.create_time) }} 字数 {{ detail.content && detail.content.length }} 阅读 {{ detail.read_num }} {{ formatTag(v) }}

"效果\n\n![QQ截图20200104092039.jpg](/images/20200104092102QQ截图20200104092039.jpg)\n\n在线演示:https://codepen.io/zhangqh22/pen/VwYrGmm\n\nhtml\n\n```html\n<canvas class=\"zh-snow\" id=\"js_snow\"></canvas>\n<script>\n    var SNOW_IMG = \"./images/img-snow.png\"; // 雪花图片地址\n</script>\n```\n\n> 雪花图片下载:https://www.iconfont.cn/search/index?searchType=icon&q=snow\n\ncss\n\n```css\nbody {\n    background: #2d2d2d;\n}\n.zh-snow {\n    position: fixed;\n    z-index: 2;\n    left: 0;\n    top: 50px;\n    width: 100%;\n}\n```\n\njs\n\n```\nwindow.requestAnimationFrame = (function () {\n    return window.requestAnimationFrame ||\n        window.webkitRequestAnimationFrame ||\n        window.mozRequestAnimationFrame ||\n        window.oRequestAnimationFrame ||\n        window.msRequestAnimationFrame ||\n        function (callback) {\n            setTimeout(callback, 1000 / 60);\n        }\n})();\nwindow.onload = function () {\n    // 获取浏览器的长宽 \n    var b_width = window.screen.width;\n    var b_height = window.screen.height;\n    var c = document.getElementById(\"js_snow\");\n    c.width = b_width;\n    c.height = b_height;\n    // 获取canvas 的2d上下文\n    var ctx = c.getContext(\"2d\");\n    // 绘制背景\n    // drawBackground(ctx, c.width, c.height);\n    // 所有的雪花\n    const snows = [];\n    // 下落的加速度\n    const G = 0.01;\n    // 速度限制(X,Y)\n    const SPEED_LIMIT_X = 1;\n    const SPEED_LIMIT_Y = 1;\n    // 定时器定时的间隔(新增snow)\n    let tickerCount = 150;\n    // 定时器计数\n    let ticker = 0;\n    // 当前时间\n    let lastTime = Date.now();\n    // 执行循环的时间\n    let deltaTime = 0;\n    // 获取图片资源\n    let snowImage = new Image();\n    snowImage.src = SNOW_IMG;\n    // 开始绘制\n    loop();\n    // 循环绘制\n    function loop() {\n        requestAnimationFrame(loop);\n        // 清除画板\n        ctx.clearRect(0, 0, c.width, c.height);\n        // 计算时间间隔累加tricker\n        const now = Date.now();\n        deltaTime = now - lastTime;\n        lastTime = now;\n        ticker += deltaTime;\n        // 当超过tickcount时候,新增snow\n        if (ticker > tickerCount) {\n            snows.push(new Snow(\n                Math.random() * c.width,\n                0,\n                Math.random() * 5 + 5\n            ));\n            ticker %= tickerCount;\n        }\n        // 绘制背景\n        // drawBackground(ctx, c.width, c.height);\n        // 绘制雪花\n        snows.map(function (s, i) {\n            s.update();\n            s.draw();\n            // 如果雪花到底部删除\n            if (s.y > c.height) {\n                snows.splice(i, 1);\n            }\n        });\n    }\n    // 定义雪花实体\n    function Snow(x, y, radius) {\n        this.x = x;\n        this.y = y;\n        this.sx = 0;\n        this.sy = 0;\n        this.radius = radius;\n        this.deg = 0;\n        this.ax = Math.random() < 0.5 ? 0.005 : -0.005;\n    }\n    // 定义雪花的状态\n    Snow.prototype.update = function () {\n        const degr = Math.random() * 0.6 + 0.2;\n        // x方向调整\n        this.sx += this.ax;\n        if (this.sx >= SPEED_LIMIT_X || this.sx <= -SPEED_LIMIT_X) {\n            this.ax *= -1;\n        }\n        // y方向调整\n        if (this.sy < SPEED_LIMIT_Y) {\n            this.sy += G;\n        }\n        // 更新snow参数\n        this.x += this.sx;\n        this.y += this.sy;\n        this.deg += degr;\n    }\n    // 绘制雪花\n    Snow.prototype.draw = function () {\n        const radius = this.radius;\n        ctx.save();\n        ctx.translate(this.x, this.y);\n        ctx.rotate(this.deg * Math.PI / 180);\n        ctx.drawImage(snowImage, -radius, -radius, radius * 2, radius * 2);\n        ctx.restore();\n    }\n    // 绘制背景\n    // function drawBackground(ctx, W, H) {\n    //     ctx.save();\n    //     var grd = ctx.createRadialGradient(W / 2, H / 2, 1, W / 2, H / 2, H);\n    //     grd.addColorStop(0, \"white\");\n    //     grd.addColorStop(1, \"#0a2a39\");\n    //     ctx.fillStyle = grd;\n    //     ctx.fillRect(0, 0, W, H);\n    //     ctx.restore();\n    // }\n}  \n```"
PS:写作不易,如要转裁,请标明转载出处。

如果此篇对您有帮助,可小额赞助,以兹鼓励!

猜你想看