利用p5.js進行“運動”主題的繪畫創作
利用p5.js進行“運動”主題的繪畫創作
主題
用碼繪和手繪兩種方式創作“運動”主題的作品,對比二者在表現“動態”方面的異同。
碼繪
工具
p5.js
創作理念
因為喜歡Apple,當提到“運動”或者“動態”這個主題時,腦海中第一個冒出來的就是Siri動態的水波紋形狀,所以決定用p5.js實現Siri的動態效果。
Siri的實際效果如下:(右側為動態圖片,圖片源自網路)
實現過程
分析
Siri是由紅黃藍綠等多種顏色的波紋混合起來的,每種波紋都有較低的透明度,並且不同顏色的波紋重疊部分要顯示多種顏色混合的效果;波紋的運動方式比較平滑自然,要考慮使用比random()更自然的隨機數函式來實現;不同顏色的波紋起始位置也不同,所以初始化每種波紋的時候要注意錯開起始位置;
程式碼實現
sketch.js中的一些基本設定:
//定義幾個全域性變數
var w;
var h;
var mult = 75;
//初始函式
function setup() {
createCanvas(windowWidth, windowHeight);
background(51);
}
//繪製函式
function draw() {
background(51);
push();
blendMode(ADD);//混合顏色
//紅
stroke(255, 0, 255, 3);
drawLine(w, h, 2000);
//黃
stroke(255, 255, 0, 3);//stroke()四個引數:R、G、B、透明度
drawLine(w, h, 0);
//藍
stroke(0, 0, 255, 3);
drawLine(w, h, 3000);
//綠
stroke(0, 255, 0, 3);
drawLine(w, h, 4000);
pop();
}
重點是drawLine()函式的編寫:
function drawLine(w, h, d) {
//w為可以控制波紋寬度的變數;h為可以控制波紋高度的變數;d為每種顏色波紋的偏移量
for (var i = 0; i < w; i++) {
var s = (noise(i / (w / 10), frameCount / 25 + d) * mult) - map(abs(i - w / 2), 0, w / 2, 0, mult) + h;
strokeWeight(s);
if (s > 1) line(i + (width / 2 - w / 2), height / 2, i + 1 + (width / 2 - w / 2), height / 2);
}
drawLine()函式的具體思路是隨機的更改線條的寬度,在給定範圍內繪製線條;其中noise(i / (w / 10))中,替換“10“為其他數字可以改變波紋的顆粒感。
新增互動功能
為了能讓自己編寫的Siri繼續向現實中的Siri看齊,我給它增加了聲音互動的功能,即可以根據聲音的強度對波形和整體的大小做出相應的變換,這就要求在用網頁開啟的時候要開啟麥克風的許可權,獲取聲音的實現方式也很簡單,用到了p5.js中的AudioIn模組,具體程式碼如下(包括前面用過的程式碼):
[當一直點選滑鼠的時候就會進入聲音互動模式]
var mic;
var volume;
var w;
var h;
var mult = 75;
function setup() {
createCanvas(windowWidth, windowHeight);
background(51);
mic = new p5.AudioIn();
mic.start();//啟動麥克風
}
function draw() {
background(51);
push();
blendMode(ADD);//混合顏色
if (mouseIsPressed) {
//w = width;//width為儲存畫布寬度的系統變數
//h = 10;
volumeLevel = mic.getLevel();
w = map(volumeLevel, 0, 1, 0, 6000);//w為可以控制波紋寬度的變數
h = map(volumeLevel, 0, 1, 0, 600);//h為可以控制博文高度的變數
} else {
w = width;//width為儲存畫布寬度的系統變數
h = 10;
//volumeLevel = mic.getLevel();
//w = map(volumeLevel, 0, 1, 0, 6000);//w為可以控制波紋寬度的變數
//h = map(volumeLevel, 0, 1, 0, 600);//h為可以控制博文高度的變數
}
//黃
stroke(255, 255, 0, 3);//stroke()四個引數:R、G、B、透明度
drawLine(w, h, 0);
// stroke(0, 255, 255, 3);
// drawLine(w, h, 1000);
//紅
stroke(255, 0, 255, 3);
drawLine(w, h, 2000);
//藍
stroke(0, 0, 255, 3);
drawLine(w, h, 3000);
//綠
stroke(0, 255, 0, 3);
drawLine(w, h, 4000);
pop();
}
function drawLine(w, h, d) {
//w為可以控制波紋寬度的變數;h為可以控制博文高度的變數;d為每種顏色波紋的偏移量
for (var i = 0; i < w; i++) {
var s = (noise(i / (w / 10), frameCount / 25 + d) * mult) - map(abs(i - w / 2), 0, w / 2, 0, mult) + h;
strokeWeight(s);
if (s > 1) line(i + (width / 2 - w / 2), height / 2, i + 2 + (width / 2 - w / 2), height / 2);
}
}
執行結果
(建議用Google Chrome瀏覽器開啟,並且允許開啟麥克風許可權)
正常模式下:
這個執行結果和實際的Siri還是有些差距的,一開始以為實現起來會很簡單,但是上手了才知道里面的道道,再次佩服Apple牛逼!
聲音互動模式下:(按住滑鼠進入聲音互動模式)
聲音互動效果(背景音樂為Good Form-Nicki Minaj,播放音樂時需一直點選滑鼠,進入聲音互動模式)
手繪
手繪效果圖(利用iPad繪製)
創作體驗
1.對於我的選題手繪要比碼繪簡單,難點在於Siri的自然的波形效果如何用程式碼來實現,一開始用了random()函式生成隨機位置,這樣會出現非常不自然的效果,隨後選用了noise()函式,得到現在的效果。
2.每條波紋的透明度始終沒有除錯的特別理想,以至於呈現出一種混合在一起的感覺,實際的Siri則是每種波紋可以被區分的特別明顯,這也是以後需要改進的地方。
3.還得感嘆一下Apple的設計,我找了很多資料,但是沒找到具體介紹iOS12上Siri 的設計理念,不過應該會比較複雜。不知道是不是因為自己親自動手實現了一下,發現最近對Siri的好感度大大提升,雖然不如其他語音助手那麼“聰明”,但是愛Apple不需要理由!!!