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制作的下雨動畫

本文轉載于:猿2048?https://www.mk2048.com/blog/blog.php?id=ckbahaa&title=Canvas制作的下雨動畫

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370325.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370325.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370325.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在Eclipse中有效使用JUnit

最近&#xff0c;我被卷入了討論1和一些受感染的同伴2&#xff0c;他們關于我們如何在Eclipse IDE中使用JUnit 。 令人驚訝的是&#xff0c;對話帶來了并非所有人都知道的一些“技巧”。 這使我有了寫這篇文章的想法&#xff0c;總結了我們的演講。 誰知道–也許有人也有新事物…

jquery文件上傳控件 Uploadify

基于jquery的文件上傳控件&#xff0c;支持ajax無刷新上傳&#xff0c;多個文件同時上傳&#xff0c;上傳進行進度顯示&#xff0c;刪除已上傳文件。 要求使用jquery1.4或以上版本&#xff0c;flash player 9.0.24以上。 有兩個版本&#xff0c;一個用flash,一個是html5。html5…

imagick php 縮放,php使用imagick模塊實現圖片縮放、裁剪、壓縮示例

PHP 使用Imagick模塊 縮放&#xff0c;裁剪&#xff0c;壓縮圖片 包括gif圖片縮放 裁剪代碼如下:/*** 圖片裁剪* 裁剪規則&#xff1a;* 1. 高度為空或為零 按寬度縮放 高度自適應* 2. 寬度為空或為零 按高度縮放 寬度自適應* 3. 寬度&#xff0c;高度到不為空或為…

php實現第三方郵箱登錄_PHP實現用戶異地登錄提醒功能的方法

有時候你的網站賬號被盜或你在別處登錄操作后臺時&#xff0c;右下角會彈出提示信息&#xff0c;提醒你的賬號異地登錄&#xff0c;或者會被強制下線。對于這種安全性要求比較高的web網站&#xff0c;很多后臺管理都會做這種功能提醒。甄別自己的賬號是否被盜或者是否有另一個人…

課時47.datalist標簽(了解)

1.datalist標簽 作用&#xff1a;給輸入框綁定待選項 2.datalist格式&#xff1a; <datalist> <option>待選項內容</option> </datalist> 3.如何給輸入框綁定待選列表&#xff1f; 搞一個輸入框搞一個datalist列表給datalist列表標簽添加一個id給…

pandas.read_csv參數詳解

讀取CSV&#xff08;逗號分割&#xff09;文件到DataFrame也支持文件的部分導入和選擇迭代更多幫助參見&#xff1a;http://pandas.pydata.org/pandas-docs/stable/io.html參數&#xff1a;filepath_or_buffer : str&#xff0c;pathlib。str, pathlib.Path, py._path.local.Lo…

Gradle – Maven的觀點

正如我博客的讀者所知道的&#xff0c; 我有點像Maven迷 。 我從2007年8月左右開始使用Maven&#xff0c;從沒有回過頭。 但是&#xff0c;就像其他所有情況一樣&#xff0c;“變化是唯一不變的”。 現在這個領域還有其他參與者&#xff0c;Gradle看起來是最有前途的。 我決定試…

postgis安裝_從零開始,構建電子地圖網站:0_2_數據處理postgis

軟件安裝完&#xff0c;開始數據處理。從China Historical GIS下載一份數據。一、數據下載數據來源&#xff1a;China Historical GIS&#xff1a;https://sites.fas.harvard.edu/~chgis/data/chgis/v6/先下載一份時間序列數據&#xff1a;Download CHGIS V6 TIME SERIES Datah…

sar圖像去噪matlab,一種基于總曲率的SAR圖像變分去噪方法與流程

本發明屬于數字圖像處理技術領域&#xff0c;具體涉及一種基于總曲率的SAR圖像變分去噪方法。背景技術&#xff1a;&#xff1a;相干斑噪聲是合成孔徑雷達(Synthetic Aperture Radar&#xff0c;簡稱SAR)圖像的重要特征&#xff0c;嚴重影響SAR圖像的可解譯性。相干斑噪聲通常作…

Linux下用netstat查看網絡狀態、端口狀態

在linux一般使用netstat 來查看系統端口使用情況步。 netstat命令是一個監控TCP/IP網絡的非常有用的工具&#xff0c;它可以顯示路由表、實際的網絡連接以及每一個網絡接口設備的 netstat命令的功能是顯示網絡連接、路由表和網絡接口信息&#xff0c;可以讓用戶得知目…

課時2.瀏覽器和服務器(了解)

1.什么是瀏覽器&#xff1f; 瀏覽器就是由安裝在我們電腦上的一款軟件&#xff0c;QQ&#xff0c;百度影音等一樣&#xff0c;都是安裝在電腦上的一款軟件 那這些軟件之間由什么區別呢&#xff1f; 它們的區別就是它們的功能不太一樣&#xff0c;QQ是用來聊天的&#xff0c;…

微信自動回復

http://itchat.readthedocs.io/zh/latest/tutorial/tutorial0/。 這個是學習網址&#xff0c;到時候自己學一下。做個案例試試轉載于:https://www.cnblogs.com/lilinzhiyu/p/7985864.html

python 定義變量_用python解決動態的定義變量名(并給其賦值方法:大數據處理)...

前言&#xff1a;今天為大家帶來的內容是&#xff1a;用python解決動態的定義變量名(并給其賦值方法&#xff1a;大數據處理)具有很好的參考價值&#xff0c;希望對大家有所幫助。喜歡本文內容的記得點贊轉發收藏不迷路哦&#xff01;&#xff01;&#xff01;最近消費kafka數據…

appcan php圖片上傳,appcan文件上傳php,asp通用

首先說appcan內部實現了file標簽&#xff0c;我們就不用糾結這個問題了&#xff0c;還提供了上傳百分比哦&#xff0c;然后下面的方法按從上到下依次看&#xff0c;很簡單。上傳php&#xff0c;asp頁面很簡單 &#xff0c;接收‘file_data’這個文件信息就可以了&#xff0c;如…

javascript 動態修改css樣式

方法一&#xff1a;改變外聯css文件&#xff0c;這里不講這個。 方法二&#xff1a;通過改變claaName來改變樣式&#xff0c;語法&#xff1a; obj.className "style2";//或者obj.setAttribute("class", "style2"); 方法三&#xff1a;使用obj…

POJ 3225 Help with Intervals(線段樹)

POJ 3225 Help with Intervals 題目鏈接 集合數字有的為1&#xff0c;沒有為0&#xff0c;那么幾種操作相應就是置為0或置為1或者翻轉&#xff0c;這個隨便推推就能夠了&#xff0c;然后開閉區間的處理方式就是把區間擴大成兩倍&#xff0c;偶數存點&#xff0c;奇數存線段就可…

在Spring中嵌入HSQLDB服務器實例

我一直在愉快地使用XAMPP進行開發&#xff0c;直到不得不將其托管在可通過Internet訪問的某個地方&#xff0c;供客戶端進行測試和使用。 我有一個僅具有384 RAM的VPS&#xff0c;并且需要快速找到一種方法&#xff0c;因此決定將XAMPP安裝到VPS中。 由于內存不足&#xff0c;因…

python與材料計算公式_《從問題到程序:用Python學編程和計算》——2.11 補充材料-阿里云開發者社區...

本節書摘來自華章計算機《從問題到程序&#xff1a;用Python學編程和計算》一書中的第2章&#xff0c;第2.11節&#xff0c;作者 裘宗燕&#xff0c;更多章節內容可以訪問云棲社區“華章計算機”公眾號查看。2.11 補充材料本書各章的主要內容將圍繞著怎樣通過編程解決計算問題…

centos 6.9 NTP基準時間服務器配置

時間服務器端 yum install ntp -y vim /etc/ntp.conf 增加允許客戶端訪問 restrict 192.168.0.0 mask 255.255.0.0 nomodify 配置成自啟動 chkconfig ntpd on service ntpd start 客戶端配置 每天對時一次 crontab -e * 2 * * * ntpdate 192.168.139.130 轉載于:https://www.cn…

hsdfz -- 6.16 -- day1

恩這回不寫游記了 按照老師要求記錄今天的心里路程&#xff1a;這題似乎可做期望得分150->日部分分似乎不是很顯然->a題似乎是結論題&#xff0c;大力猜一波結論->過不了樣例&#xff0c;先看b題->b題動態樹&#xff0c;似乎可以肝lct->不會維護重鏈&#xff0c…