- 原文地址:Animating URLs with Javascript and Emojis
- 原文作者:Matthew Rayfield
- 譯者:Wpeach
你可以在位址列使用 emoji(和其它圖形 unicode 字元),這看著很棒,但是好像沒人這麼做,為什麼呢?也許 emoji 對於正常的網路平臺來說太過異國情調了?或許是他們因為害怕不利於SEO?
不管什麼原因,維恩圖中的合理性觀點“沒人這麼做,但這是可能的”是讓我興奮的點。所以我決定花費一些時間研究在位址列中圖形字元的可能性,特別是通過 JavaScript 給這些字元加上動畫。
迴圈動畫
首先,確保你頁面的 JavaScript 程式碼是 UTF-8 編碼,否則無法在你的程式碼中顯示 emoji,這可以通過設定 HTTP 頭部或頁面的 META 標籤來實現。你很可能不用擔心這個,但你可以在這裡找到更多資訊:Unicode in Javascript by Flavio。
為了達到我們想要的效果,讓 emoji 像小仙女一樣在位址列裡偏偏起舞,我們需要一個迴圈,實際上,我們所需要的只是一個迴圈,我們啟動這個迴圈,它不斷迴圈,我們的目的就達到了。這是我們的第一個迴圈動畫,一個旋轉的emoji 月亮。我猜當他們新增這個 emoji 序列時,也有這個想法吧?
var f = ['?', '?', '?', '?', '?', '?', '?', '?'];
function loop() {
location.hash = f[Math.floor((Date.now()/100)%f.length)];
setTimeout(loop, 50);
}
loop();
複製程式碼
執行程式碼,你可以在位址列看到此迴圈的結果。
如果你不喜歡旋轉的月亮,你可以選擇任何你喜歡的 emoji 來替換這個陣列,比如一個時鐘:
var f = ['?','?','?','?','?','?','?','?','?','?','?','?'];
複製程式碼
這是一個非常簡單的例子,真的非常簡單,所以我們來升級一下迴圈,讓它顯示一串 emoji ! 這次我們使用 emoji 的skin tone modifiers
膚色調節屬性來製作一些變色寶寶:
var e = ['?', '?', '?', '?', '?'];
function loop() {
var s = '',
i, m;
for (i = 0; i < 10; i ++) {
m = Math.floor(e.length * ((Math.sin((Date.now()/100) + i)+1)/2));
s += '?' + e[m];
}
location.hash = s;
setTimeout(loop, 50);
}
loop();
複製程式碼
我們可以使用時間和位置控制的正弦波來選擇我們想要的顏色,這給了我們一個很好的顏色變幻效果!
比如我們再來一次月亮旋轉,使它展開,製作一個類似於載入條的動畫?好的,開始實現:
var f = ['?', '?', '?', '?', '?', '?', '?', '?'],
d = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
m = 0;
function loop() {
var s = '', x = 0;
if (!m) {
while (d[x] == 4) {
x ++;
}
if (x >= d.length) m = 1;
else {
d[x] ++;
}
}
else {
while (d[x] == 0) {
x ++;
}
if (x >= d.length) m = 0;
else {
d[x] ++;
if (d[x] == 8) d[x] = 0;
}
}
d.forEach(function (n) {
s += f[n];
});
location.hash = s;
setTimeout(loop, 50);
}
loop();
複製程式碼
探索其它字元
不止是 emoji 給我們提供了一種在位址列顯示圖形的方法,我們的目標中也有一些 unicode 字元。
特別有趣的是 框線字元:
它們中很多更適合二維輸出,但它們在一維輸出也很棒,例如,我們可以建立一個多個高度變化的塊字串,並構造一個漂亮的小波浪動畫:
function loop() {
var i, n, s = '';
for (i = 0; i < 10; i++) {
n = Math.floor(Math.sin((Date.now()/200) + (i/2)) * 4) + 4;
s += String.fromCharCode(0x2581 + n);
}
window.location.hash = s;
setTimeout(loop, 50);
}
loop();
複製程式碼
我非常喜歡它的效果,我把它永久放在了 wavyurl.com 上。
使用可變寬度字元,我們甚至在水平方向上擺動,建立類似於進度條的東西:
function loop() {
var s = '',
p;
p = Math.floor(((Math.sin(Date.now()/300)+1)/2) * 100);
while (p >= 8) {
s += '█';
p -= 8;
}
s += ['⠀','▏','▎','▍','▌','▋','▊','▉'][p];
location.hash = s;
setTimeout(loop, 50);
}
複製程式碼
進度條?這看起來,還是有用的,這讓我想到了……
在位址列顯示視訊進度
為了增加我們小實驗的可能性,我提出了在位址列中顯示網路視訊進度的想法。我只需附加一個函式,將我們的進度字串定義在視訊的timeupdate
事件中,瞧!位址列中的視訊進度條包含時間和持續時間!
var video;
function formatTime(seconds) {
var minutes = Math.floor(seconds/60),
seconds = Math.floor(seconds - (minutes*60));
return ('0'+minutes).substr(-2) + ':' + ('0'+seconds).substr(-2);
}
function renderProgressBar() {
var s = '',
l = 15,
p = Math.floor(video.currentTime / video.duration * (l-1)),
i;
for (i = 0; i < l; i ++) {
if (i == p) s +='◯';
else if (i < p) s += '─';
else s += '┄';
}
location.hash = '╭'+s+'╮'+formatTime(video.currentTime)+'╱'+formatTime(video.duration);
}
video = document.getElementById('video');
video.addEventListener('timeupdate', renderProgressBar);
複製程式碼
我比較喜歡這個線條和圓組成的進度條,如果你喜歡別的 emoji 比如月亮,我也能讓你滿意:
var e = ['?', '?', '?', '?', '?'],
video;
function formatTime(seconds) {
var minutes = Math.floor(seconds/60),
seconds = Math.floor(seconds - (minutes*60));
return ('0'+minutes).substr(-2) + ':' + ('0'+seconds).substr(-2);
}
function renderProgressBar() {
var s = '',
c = 0,
l = 10,
p = Math.floor(video.currentTime / video.duration * ((l*5)-1)),
i;
while (p >= 5) {
s += e[4];
c ++;
p -= 5;
}
s += e[p];
c ++;
while (c < l) {
s += e[0];
c ++;
}
location.hash = s+formatTime(video.currentTime)+'╱'+formatTime(video.duration);
}
video = document.getElementById('video');
video.addEventListener('timeupdate', renderProgressBar);
複製程式碼
好的,將此進度條稱為“有用”的延伸。 只瞄一眼,我也可以看到在視訊分享 URL 中的進度。 與YouTube一樣,你可以選擇在特定時間建立指向視訊的連結,新增視覺指示是不是很酷?嗯?
也許我還沒有提出一些更有用的“技術”實現,我會繼續思考這個問題。 嘿,也許你可以嘗試一些東西?
最後
你可能想知道為什麼我使用location.hash =
,而不是新且酷的HTML5 History API
。 有兩個原因:
第一個問題是 History API
有一個特點:它實際上更改了整個 URL 路徑,而不僅僅是 hash
。 因此,如果我使用 History API
並將頁面更改為/?????
,它看起來會比新增 # 更好。 但這也意味著我的 Web 伺服器必須能夠響應/?????
,否則如果使用者重新整理或以其他方式導航到修改後的 URL 將會失敗。 這是可行的,但比使用location.hash =
更復雜,需要我修改伺服器配置。
第二個問題有些出乎意料。 實際上,在我測試的3個瀏覽器中,有2個歷史API被限制的。 如果我以極快的速度將我的波形網址推送到位址列,我最終會在 Chrome 中收到以下錯誤:
Throttling history state changes to prevent the browser from hanging.
Safari 給我們提供了更詳細的資訊:
SecurityError: Attempt to use history.pushState() more than 100 times per 30.000000 seconds
現在,如果讓我保持在這個限制下也行,但是每秒3幀只是不會影響我目前的動畫效果。
好孩子 Firefox 似乎並不在乎我推送新歷史的次數和速度,這真是想得太周到了。但是,兩個主要的瀏覽器受到影響,加上需要web伺服器配置來修復第一個問題,使我更願意忍受 URL 中的 #。
結語
我就講到這裡。但我要告訴你,我還有一些想法,讓小遊戲顯示在位址列。特別是考慮到盲文字元我們還沒有探索,所以請繼續關注。
如果你有任何問題、評論,或者只是想了解我的最新進展,請在 Twitter 上關注我: @MatthewRayfield
。或者點這裡訂閱我的幾乎從未被打擾過的電子郵件。
哦,如果你想要以上示例的原始碼,點這下載。