膽小的俾格米小人兒!

線上demo
Dome在這 由於相容性的問題還沒解決,建議 Chrome 開啟。
靈感來源
某天在觀看TED演講 ofollow,noindex">Aparna Rao High tech Art with a sense of humor 的時候看到裡面的一個專案叫做 pygmies ,中文名叫 俾格米人 (圖中的小黑人)。他們都很膽小,只要有聲音就會被嚇到躲到板子後面。
該專案的實物是由來自印度的團隊製作的。測試中,俾格米人表現得惟妙惟肖,就像是一群好奇而又膽小的小動物。十分可愛!
於是我想用web技術似乎也能達到同樣的效果。只需要瀏覽器呼叫麥克風,獲取資料,作用於svg元素(當然這是最初的簡單想法)。
準備svg素材
作圖工具,Mac平臺 sketch

主要程式碼
html部分
// 主要是svg程式碼,量比較大,請在原始碼中檢視 複製程式碼
css部分
// 主要是基本的定位程式碼,請在原始碼中檢視 複製程式碼
js部分
"use strict"; var ctx, analyser, frequencies, getByteFrequencyDataAverage, draw; // 相容性 window.AudioContext = window.AudioContext || window.webkitAudioContext; // 獲取音訊上下文 ctx = new window.AudioContext(); // 使用者獲取stream當中的時間、頻率資訊 analyser = ctx.createAnalyser(); frequencies = new Uint8Array(analyser.frequencyBinCount); getByteFrequencyDataAverage = function() { // 將當前頻域資料拷貝進陣列 analyser.getByteFrequencyData(frequencies); // 求得頻域的平均值 return ( frequencies.reduce(function(previous, current) { return previous + current; }) / analyser.frequencyBinCount ); }; // 返回 Promise 物件 navigator.mediaDevices .getUserMedia({ audio: true }) .then(function(stream) { // window.hackForMozzila = stream; ctx .createMediaStreamSource(stream) // 連線到AnalyserNode .connect(analyser); }) .catch(function(err) { console.log(err.message); }); var pygmies = []; for (let i = 0; i < 10; i++) { pygmies.push(document.getElementById(`pygmie-${i + 1}`)); } // 改變小人的位置 (draw = function() { var moveValue = getByteFrequencyDataAverage() * 10; if (moveValue >= 35) { moveValue = 35; } pygmies[0].style.transform = `translate(51.000000px, ${moveValue}px)`; console.log(getByteFrequencyDataAverage()); pygmies[1].style.transform = `translate(89.000000px, ${0.0 + moveValue}px)`; pygmies[2].style.transform = `translate(149.000000px, ${0.0 + moveValue}px)`; pygmies[3].style.transform = `translate(218.000000px, ${0.0 + moveValue}px)`; pygmies[4].style.transform = `translate(286.500000px, 51.000000px) rotate(90.000000deg) translate(-286.500000px, -51.000000px) translate(275.000000px, ${34.0 + moveValue}px)`; pygmies[5].style.transform = `translate(286.500000px, 152.000000px) rotate(90.000000deg) translate(-286.500000px, -152.000000px) translate(275.000000px, ${135.5 + moveValue}px)`; pygmies[6].style.transform = `translate(286.500000px, 196.5000000px) rotate(90.000000deg) translate(-286.500000px, -196.500000px) translate(275.000000px, ${179.5 + moveValue}px)`; pygmies[7].style.transform = `translate(17.500000px, 173.500000px) rotate(-90.000000deg) translate(-17.00000px, -173.500000px) translate(5.500000px, ${156.5 + moveValue}px)`; pygmies[8].style.transform = `translate(17.000000px, 106.500000px) rotate(-90.000000deg) translate(-17.00000px, -106.500000px) translate(5.500000px, ${89.5 + moveValue}px)`; pygmies[9].style.transform = `translate(17.00000px, 252.500000px) rotate(-90.000000deg) translate(-17.00000px, -252.500000px) translate(5.500000px, ${235.5 + moveValue}px)`; requestAnimationFrame(draw); })(); 複製程式碼
程式碼主要是做了兩件事:
- 獲取麥克風的音訊資訊
- 利用音訊資訊改變svg的位置資訊
只不過需要不斷的迴圈,來獲取最新的資訊。