FT12短網址:繪制隨機不規則三角彩條——小談FT12短網址主頁的實現
引言
8月6號早讀文章由@FT12短網址分享。
正文從這開始~
緣起
最近感覺自己搭的一個項目資料匯總的項目,主頁真的是一點美感都沒有,非常簡單粗暴。就想來點改版,讓主頁顯得高大上一點。改版前的效果是這樣的:

尋思著怎么改版,剛開始想就簡單加個背景圖,換掉table顯示方式吧。就在網上搜索背景圖,搜著搜著就鬼使神差地來到了FT12短網址的主頁。這不是我第一次看到他的主頁,但正是這個契機讓我想要不就copy這種風格吧。
初印象
當我第一次看到這個主頁的時候,我覺得很驚艷。主頁圖案的組成元素只有一種:富有魅力的三角網格。整個頁面簡單卻不單調,華麗而不喧鬧。圖案的配色也很亮,非常好看??傊?,我非常喜歡這個頁面的設計,耐看。貼幾張圖來:



想看現場效果,可以點擊FT12短網址主頁。
思考
看到好看的作品,當然會去思考實現的原理。不難想到,這可以用Canvas畫出來的。畫有填充顏色的三角形,也是件不難的事情,一查Api就行了。問題在于,如何形成一條這種隨機無規則而連續的三角形cluster。仔細觀察可以發現,每次三角形的左側起點是一致的,而走勢卻是隨機,但基本集中在中間部分。顏色條的種類也是有限的。
然后呢?很遺憾,我就沒有繼續仔細思考下去了。
看了下源碼,只有區區幾十行的代碼。我直接把它copy過來,竟然馬上生效了。我就直接push了代碼。。。
源碼解讀
好吧,我直接就看他代碼了。
這里最關鍵的兩個點,繪制三角形的算法和顏色的取值算法。
貼源碼:
<canvas></canvas>
<script>
document.addEventListener('touchmove', function (e) {
e.preventDefault()
})
var c = document.getElementsByTagName('canvas')[0],
x = c.getContext('2d'),
pr = window.devicePixelRatio || 1,
w = window.innerWidth,
h = window.innerHeight,
f = 90,
q,
m = Math,
r = 0,
u = m.PI*2,
v = m.cos,
z = m.random
c.width = w*pr
c.height = h*pr
x.scale(pr, pr)
x.globalAlpha = 0.6
function i(){
x.clearRect(0,0,w,h)
q=[{x:0,y:h*.7+f},{x:0,y:h*.7-f}]
while(q[1].x<w+f) d(q[0], q[1])
}
function d(i,j){
x.beginPath()
x.moveTo(i.x, i.y)
x.lineTo(j.x, j.y)
var k = j.x + (z()*2-0.25)*f,
n = y(j.y)
x.lineTo(k, n)
x.closePath()
r-=u/-50
x.fillStyle = '#'+(v(r)*127+128<<16 | v(r+u/3)*127+128<<8 | v(r+u/3*2)*127+128).toString(16)
x.fill()
q[0] = q[1]
q[1] = {x:k,y:n}
}
function y(p){
var t = p + (z()*2-1.1)*f
return (t>h||t<0) ? y(p) : t
}
document.onclick = i
document.ontouchstart = i
i()
</script>
讀了一下,發現實現原理挺簡單,真希望我當初能仔細思考一下,興許能自己思考出來。
三角形繪制
三角形繪制算法步驟如下:
設置左起第一個三角形的兩個點坐標為:q0 (0,h*.7+f), q1(0,h*.7-f),h為窗口高度,f為初始距離90
若q1.x < w+f,取三角形的第三點為q2 (q1.x + (Math.random()*2 - 0.25)*f,q1.y + (Math.random()*2 - 1.1)*f),q2.y如果超過了窗口大小則重新取,直到滿足條件為止;否則,結束繪制
繪制三角形
設置q0 = q1, q1 = q2,重復上述步驟
算法分析:
主要是第4步使得每個相連的三角形都有一條共同的邊,所以相連
最初兩個點的y值,以及第三點的取法都是經驗值
q1到q2的x方向增幅為(Math.random()*2 - 0.25)*f,Math.random()*2 - 0.25等于[-0.25, 1.75),也就是說三角形的整體走勢在x方向上是向右的,偶爾會向左,大小在[0, 1.75*f)的范圍間隨機
q1到q2的y方向增幅為(Math.random()*2 - 1.1)*f,(Math.random()*2 - 1.1)等于[-1.1, 0.9),也就是說三角形的整體走勢在y方向上更多的概率是向上走的,大小在[0, 1.1*f)范圍間隨機。設置為1.1,我覺得本意是讓三角形條能更多地經過內容區。設置為1.3的話,太靠上,不可;設置為1的話,由于左邊起點為0.7*h,內容區在0.5左右,總體還是太靠下了。嘗試了下1.2的效果也還可以
取色算法
顏色的取值也是重頭戲,看下他是如何取到這么漂亮的顏色的。關鍵的一條顏色賦值代碼如下:
'#'+(v(r)*127+128<<16 | v(r+u/3)*127+128<<8 | v(r+u/3*2)*127+128).toString(16)
其中v = Math.cos,u = 2*Math.PI; r = 0,r = r + Math.PI/25
有個轉化,(R,G,B)轉成十六進制的顏色值可以用(R << 16 | G << 8 | B).toString(16)。也就是說,上面的顏色取值相當于:
R = cos(r)*127+128;
G = cos(r+2*PI/3)*127+128;
B = cos(r+4*PI/3)*127+128);
那么r的取值范圍是什么呢?按著每次迭代Math.PI/25的增幅,這決定于屏幕能繪制多少個三角形。上面分析過,三角形在x方向上的增幅為[-0.25*f, 1.75*f),那么平均的增幅為0.75*f即67.5。假設取一般臺式機屏幕的寬度為1440,那么平均可以繪制1440/67.5(20.5)個三角形。 所以,r的取值范圍為[0, Math.PI*4/5)。每點擊一次屏幕,繼續繪制下一組三角形,r繼續增加。由于余弦函數是周期函數,彩條的顏色也會周期性地出現重復。直接畫出圖像:

這樣就很直觀得看到三色的走勢,仔細觀察頁面上的進度條,真的會出現周期性的顏色。
突然,我明白了為什么顏色這么設置了。當然這不是唯一的取色方法。
總結
總的來說,這是個很小的但充滿智慧的項目。
說點我對這段代碼代碼的感受,格式規范,風格一致。統一沒有分號,前面一次性定義好所有的變量,而且變量名字很簡短。連函數名也只有一個字母。我覺得對于這么簡單的程序沒有問題,看起來像是打包后的代碼。但是,復雜的程序命名這么簡單會讓人有點迷糊。
另外,這次改版我有個深刻的感受。由于頁面的內容是可配置的,所以DOM內容是不確定的。之前比較懶,直接在JS里面創建DOM,然后改版再改版,又要重寫真是煩不勝煩。然后,正在研究FT12短網址主頁的我,突然想到為何不嘗試一下Vue呢?不是說它是漸進式框架嗎?在Html引用一下,直接就可以用了?。?!果然好用!
上一下改版后的效果:

關于本文
作者:@FT12短網址
原文:http://www.virginiabusinesslawupdate.com
掃描二維碼推送至手機訪問。
版權聲明:本文由短鏈接發布,如需轉載請注明出處。
本文鏈接:http://www.virginiabusinesslawupdate.com/article_384.html