p5.js實(shí)現(xiàn)簡(jiǎn)單貨車運(yùn)動(dòng)動(dòng)畫
本文為大家分享了p5.js實(shí)現(xiàn)簡(jiǎn)單貨車運(yùn)動(dòng)動(dòng)畫的具體代碼,供大家參考,具體內(nèi)容如下
使用工具
Visual Studio Code+p5.js
下載地址
目標(biāo)
在網(wǎng)頁上畫出一輛貨車,通過運(yùn)用循環(huán)、條件分支、函數(shù)等流程控制方法來達(dá)到動(dòng)態(tài)的效果。
具體流程
首先我們建立一個(gè)index.html文件(主頁)和一個(gè)car.js文件(碼繪實(shí)現(xiàn)文件),并把car.js和p5.js鏈接到index.html上。
在car.js中我們創(chuàng)建setup()和draw()兩個(gè)函數(shù),用于畫布的初始化和作圖。
// car.js function setup() { createCanvas(1440, 750); } function draw() { background(0); }
然后加上地面和兩個(gè)車輪。
// car.js function setup() { createCanvas(1440, 750); } function draw() { background(0); stroke(255); line(0,600,1440,600); push(); translate(400,500); tyre(); pop(); translate(900,500); tyre(); } function tyre(){ //輪胎 fill(255); ellipse(0,0,200,200); fill(0); ellipse(0,0,160,160); fill(255); ellipse(0,0,40,40); //鋼圈十字 fill(255); ellipse(0,-50,40,80); fill(255); ellipse(0,50,40,80); fill(255); ellipse(-50,0,80,40); fill(255); ellipse(50,0,80,40); //軸 fill(0); ellipse(0,0,30,30); fill(255); ellipse(0,0,20,20); }
注意這里使用的pop()和push()函數(shù)。push() 函數(shù)將儲(chǔ)存當(dāng)時(shí)的繪畫樣式設(shè)置及變形,而 pop() 將恢復(fù)這些設(shè)置。這兩個(gè)函數(shù)需要一起使用。它們讓您改變樣式及變形設(shè)置然后再回到您之前的設(shè)置。由于p5.js的translate()、rotate()等函數(shù)的效果在draw()的一次調(diào)用中是累積的,不使用pop()和push()函數(shù)的話會(huì)導(dǎo)致移動(dòng)、旋轉(zhuǎn)等代碼的效果的重疊。
車輪的旋轉(zhuǎn)
定義兩個(gè)變量step(控制旋轉(zhuǎn)速度)和angle(每調(diào)用一次draw()車輪旋轉(zhuǎn)的角度)用于車輪的旋轉(zhuǎn)。
// car.js var step=0.1; var angle=0; 123 將draw()中代碼改至如下 // car.js function draw() { background(0); stroke(255); line(0,600,1440,600); push(); if(angle<2*PI) { angle+=step*PI; } else angle=0; translate(400,500); rotate(angle); tyre(); pop(); push(); translate(900,500); rotate(angle); tyre(); pop(); }
效果圖
車身部分我們直接在draw中修改
// car.js function draw() { background(0); stroke(255); line(0,600,1440,600); //車身部分 push(); stroke(150); fill(150); rect(250,300,800,200,5); stroke(100); fill(100); rect(750,150,150,150); triangle(900,150,900,300,1050,300); stroke(160); fill(160); stroke(255); rect(800,200,100,100); triangle(900,200,900,300,1000,300); //車輪部分 stroke(255); if(angle<2*PI) { angle+=step*PI; } else angle=0; translate(400,500); rotate(angle); tyre(); pop(); push(); translate(900,500); rotate(angle); tyre(); pop(); }
效果
最后我們加上一棵草作為參照物,來使得整幅圖“動(dòng)起來”。
// car.js var grassstep=1440; function draw() { background(0); stroke(255); line(0,600,1440,600); push(); stroke(150); fill(150); rect(250,300,800,200,5); stroke(100); fill(100); rect(750,150,150,150); triangle(900,150,900,300,1050,300); stroke(160); fill(160); stroke(255); rect(800,200,100,100); triangle(900,200,900,300,1000,300); stroke(255); if(angle<2*PI) { angle+=step*PI; } else angle=0; translate(400,500); rotate(angle); tyre(); pop(); push(); translate(900,500); rotate(angle); tyre(); pop(); push(); if(grassstep>-20) grassstep-=5; else grassstep=1440; translate(grassstep,0); weed(); pop(); } function weed(){ stroke(160); fill(160); stroke(255); triangle(20,600,40,600,0,580); triangle(20,600,40,600,28,560); triangle(20,600,40,600,43,585); }
效果
到此為止,一個(gè)簡(jiǎn)單的貨車運(yùn)動(dòng)作畫已經(jīng)完成。
我們可以將官方的雪花特效加進(jìn)去,使畫面更加豐滿。
效果圖
附上源碼
// car.js var step=0.1; var angle=0; var grassstep=1440; let snowflakes = []; function setup() { createCanvas(1440, 750); } function draw() { background(0); stroke(255); line(0,600,1440,600); push(); stroke(150); fill(150); rect(250,300,800,200,5); stroke(100); fill(100); rect(750,150,150,150); triangle(900,150,900,300,1050,300); stroke(160); fill(160); stroke(255); rect(800,200,100,100); triangle(900,200,900,300,1000,300); stroke(255); if(angle<2*PI) { angle+=step*PI; } else angle=0; translate(400,500); rotate(angle); tyre(); pop(); push(); translate(900,500); rotate(angle); tyre(); pop(); push(); if(grassstep>-20) grassstep-=5; else grassstep=1440; translate(grassstep,0); weed(); pop(); let t = frameCount / 60; // update time // create a random number of snowflakes each frame for (var i = 0; i < random(5); i++) { snowflakes.push(new snowflake()); // append snowflake object } // loop through snowflakes with a for..of loop for (let flake of snowflakes) { flake.update(t); // update snowflake position flake.display(); // draw snowflake } } function tyre(){ //輪胎 fill(255); ellipse(0,0,200,200); fill(0); ellipse(0,0,160,160); fill(255); ellipse(0,0,40,40); //鋼圈十字 fill(255); ellipse(0,-50,40,80); fill(255); ellipse(0,50,40,80); fill(255); ellipse(-50,0,80,40); fill(255); ellipse(50,0,80,40); //軸 fill(0); ellipse(0,0,30,30); fill(255); ellipse(0,0,20,20); } function weed(){ stroke(160); fill(160); stroke(255); triangle(20,600,40,600,0,580); triangle(20,600,40,600,28,560); triangle(20,600,40,600,43,585); } function snowflake() { // initialize coordinates this.posX = 0; this.posY = random(-50, 0); this.initialangle = random(0, 2 * PI); this.size = random(2, 5); // radius of snowflake spiral // chosen so the snowflakes are uniformly spread out in area this.radius = sqrt(random(pow(width / 2, 2))); this.update = function(time) { // x position follows a circle let w = 0.6; // angular speed let angle = w * time + this.initialangle; this.posX = width / 2 + this.radius * sin(angle); // different size snowflakes fall at slightly different y speeds this.posY += pow(this.size, 0.5); // delete snowflake if past end of screen if (this.posY > height) { let index = snowflakes.indexOf(this); snowflakes.splice(index, 1); } }; this.display = function() { ellipse(this.posX, this.posY, this.size); }; }
碼繪與手繪相比
手繪由于是靜態(tài)的,來表現(xiàn)車的運(yùn)動(dòng)效果主要有速度線、車輪線、煙霧以及物體高速變形,通過這些靜態(tài)的線條來還原物體運(yùn)動(dòng)的效果。而碼繪則是通過參數(shù)的改變實(shí)現(xiàn)每一幀圖像的變化來達(dá)到動(dòng)態(tài)的效果,比起手繪更直觀地體現(xiàn)了“動(dòng)感”這個(gè)詞。在細(xì)節(jié)方面,手繪明顯更勝一籌,可以方便地勾勒出車的細(xì)節(jié),而碼繪由于參數(shù)、循環(huán)等一系列問題(可能動(dòng)一個(gè)參數(shù)就要改一大片,以及坐標(biāo)問題),在繪畫體驗(yàn)上明顯不行。整體比較下來,手繪給人的感覺更具藝術(shù)氣息,能夠感受到一股人情味,碼繪雖然更容易產(chǎn)生動(dòng)感的效果,線條更加精準(zhǔn),但是總感覺少了一份繪畫原有的感覺,更像是另一種藝術(shù)創(chuàng)作形式,而不是在繪畫。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JS實(shí)現(xiàn)的判斷方法、變量是否存在功能示例
這篇文章主要介紹了JS實(shí)現(xiàn)的判斷方法、變量是否存在功能,涉及javascript針對(duì)變量、方法判斷與異常處理操作技巧,需要的朋友可以參考下2018-05-05uniapp實(shí)現(xiàn)全局設(shè)置字體大小(小中大的字體切換)
隨著UniApp的流行,越來越多的開發(fā)者選擇使用它來構(gòu)建跨平臺(tái)應(yīng)用程序,下面這篇文章主要給大家介紹了關(guān)于uniapp實(shí)現(xiàn)全局設(shè)置字體大小(小中大的字體切換)的相關(guān)資料,需要的朋友可以參考下2023-06-06javascript圖像處理—邊緣梯度計(jì)算函數(shù)
上一篇文章,我們講解了圖像處理中的膨脹和腐蝕函數(shù),這篇文章將做邊緣梯度計(jì)算函數(shù),感興趣的朋友可以了解下2013-01-01基于substring()和substr()的使用以及區(qū)別(實(shí)例講解)
下面小編就為大家分享一篇基于substring()和substr()的使用以及區(qū)別實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12小程序:授權(quán)、登錄、session_key、unionId的詳解
這篇文章主要介紹了小程序:授權(quán)、登錄、session_key、unionId的詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05微信小程序中的canvas 文字?jǐn)嘈泻褪÷蕴?hào)顯示功能的處理方法
大家都知道在canvas中沒有提供方法來處理文字的多行問題,只有通過截取指定字符串來達(dá)到目的。接下來通過本文給大家介紹微信小程序中的canvas 文字?jǐn)嘈泻褪÷蕴?hào)顯示功能 ,需要的朋友可以參考下2018-11-11JS獲取計(jì)算機(jī)mac地址以及IP的實(shí)現(xiàn)方法
本篇文章主要是對(duì)利用JS獲取計(jì)算機(jī)mac地址以及IP的實(shí)現(xiàn)方法進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-01-01JS獲取短信驗(yàn)證碼倒計(jì)時(shí)的實(shí)現(xiàn)代碼
這篇文章主要介紹了JS獲取短信驗(yàn)證碼倒計(jì)時(shí)的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-05-05