膽小的俾格米小人!

在線demo

Dome在這 由於兼容性的問題還沒解決。

建議Chrome打開

建議Chrome打開

建議Chrome打開

打開後允許Chrome瀏覽器訪問麥克風,然後你可以發出一點兒聲音,看看能不能吧小俾格米人嚇到板子後面去。

靈感來源

某天在觀看TED演講

High-tech art (with a sense of humor)?

www.ted.com圖標

的時候看到裡面的一個項目叫做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的位置信息
  • 只不過需要不斷的循環,來獲取最新的信息。

待優化部分

  • 手動的修改每個俾格米人的位置真的很煩人;
  • 通過修改transform參數來調節俾格米人的位置,很容易出錯;
  • 當俾格米人數量再多一點兒的時候,svg可能有性能缺陷;
  • 俾格米人並不唯妙唯俏,離原版的生動程度還差很遠; 這一部分需要去考慮生物的應激性特徵、分不同情況、動畫曲線等方面。達到賦予每個俾格米人不同的性格特徵的效果(有的膽小,有的膽大,有的好奇心強等等)。
  • 兼容性問題;
  • ...

參考

High-tech art (with a sense of humor)?

www.ted.com圖標Web Audio API?

developer.mozilla.org圖標畫隨音動!Web Audio API 入門(四)?

juejin.im

推薦閱讀:

TAG:Web開發 | 前端開發 | 有趣 |