Canvas製作的下雨動畫

来源:https://www.cnblogs.com/qingshandaiyue/archive/2018/06/08/9101354.html
-Advertisement-
Play Games

簡介 在codepen上看到一個Canvas做的下雨效果動畫,感覺蠻有意思的。就研究了下,這裡來分享下,實現技巧。效果可以見下麵的鏈接。 霓虹雨: http://codepen.io/natewiley/full/NNgqVJ/ 效果截圖: Canvas動畫基礎 大家都知道,Canvas其實只是一個 ...


簡介

在codepen上看到一個Canvas做的下雨效果動畫,感覺蠻有意思的。就研究了下,這裡來分享下,實現技巧。效果可以見下麵的鏈接。

霓虹雨: http://codepen.io/natewiley/full/NNgqVJ/

效果截圖:

Canvas動畫基礎

大家都知道,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()。沒錯用這兩個也可以。除此之外,後來又出現一個新的方法:window.requestAnimationFrame(callback)。

requestAnimationFrame會告訴瀏覽器你要繪製一個動畫。讓瀏覽器要重繪時調用你指定的方法(callback)來繪製你的動畫。
使用方法如下:

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 = 'rgba(0, 0, 0, .1)';//畫板背景,註意最後的透明度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 = 'hsl(180, 100%, 50%)';//雨滴顏色 長方形的填充色
        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();

漣漪效果

接著來繪製漣漪效果。與繪製雨滴的方式類似,也是通過具有透明度的背景來疊加前面的圖像產生內陰影的效果。

代碼如下(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 = 'rgba(0, 0, 0, .1)';//畫板背景,註意最後的透明度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 = 'hsla(180, 100%, 50%, '+this.a+')';
        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的視覺效果提升一大截。發動自己的智慧,相信能做出更多奇妙的動畫。這是我越來越喜歡web的原因之一吧 O(∩_∩)O~~。

轉載出處:Web前端開發 » Canvas製作的下雨動畫


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • MAMP 我點擊start server的時候 發現mysql伺服器打不開 http://images.cnblogs.com/cnblogs_com/lwwen/1231721/o_111111111.png 就像如上鏈接里的照片一樣 在谷歌上搜索了一下是把mamp下麵的MySQL的ib_logf ...
  • PLSQL Developer 12 註冊碼product code: 4vkjwhfeh3ufnqnmpr9brvcuyujrx3n3le serial Number:226959 password: xs374ca 親測有效 ...
  • 需要學習的朋友可以通過網盤下載:http://tadown.com/fs/byib0ens3hu207015/內容簡介 · · · · · · 本書通過大量的實例,詳細說明瞭為提高 SQL編程技術而必須面對的思想方法上的根本轉變 ——由以過程式編程方式思考轉變為以數據集的方式來思考。此外,本書還討論 ...
  • iPhone上面的應用一直都是以流暢的操作體驗而著稱,但是由於之前開發人員把註意力更多的放在開發功能上面,比較少去考慮性能的問題,可能這其中涉及到objective-c,c++跟lua,優化起來相對複雜一些,導致應用在比如touch等較低端的產品上,光從啟動到進入頁面就花了將近一分鐘的時間,頁面之間 ...
  • 項目中包含多個工程 合併出現編譯錯誤問題 背景:當一個大型項目中包含2個以上的子項目時。比如,主項目中有master分支(發佈產品的分支)和dev分支(自己開發的分支)。同時在子項目中也有2個分支,分別是:sun_master(發佈分支)和sun_dev(自己開發的分支)。 產生錯誤:當開發時,把m ...
  • 一、首先獲取圖片 //第一種獲取圖片的方法 //第二種獲取圖片的方法 二、保存圖片 源碼下載地址:https://download.csdn.net/download/daxudada/10272805 喜歡我的就關註我 ...
  • 按照故事板的用語,應用中的一個界面屏幕被稱作一個”場景(Scene)",以後添加額外的場景時,停靠區中將有另一個部分。 一,新建立一個工程,如圖所示。 二,選中Main.storyboard.如圖所示。 三,在storyboard場景上拖入一個button,並命名為"firstButton". 四, ...
  • 網頁的固定格式 編寫網頁和寫信一樣都有一套規範和要求,這套規範和要求中規定了寫信的固定格式 寫信基本結構 親愛的xx: 你好! 我。。。。。。。。。。。。。。。。。。 。。。。。。 此致 敬禮! xxx 2018年x月x日 編寫網頁的步驟: 一定不用用中文命名文件,要用英文或者拼音 基本結構 ... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...