rplus.github.io icon indicating copy to clipboard operation
rplus.github.io copied to clipboard

[POST] Codrops Collective Cover CSS version note

Open Rplus opened this issue 6 years ago • 0 comments

前些天抽空參考 Codrops Collective 的封面做了個 CSS 動畫版的 https://codepen.io/Rplus/pen/YMBmOK 要看錄的示範影片請到 Twitter

Codrops 原圖image

因為最近寫 code 都沒在錄影 而且這玩意算數學也稍微花了一些時間 錄起來應該會像停格一樣吧 XD

下面回憶/記錄一下自己的製作思路:

1 基板

看到圖形時 就大概有個概念弄個一堆點點 然後配上不同的 scale 數值,讓它們有不同的尺寸

主要的思考是在於需不需要使用 CSS Grid 因為其實主要圖案的排版也不難 Grid 似乎有些大材小用的感覺 原本是想直接用 inline-block 做 後來想想,算了,得需要 gap,那就用 Grid 吧…

因為參數都在 pug 那邊就用 CSS variables 傳到上層了 所以 grid columns 也就直接吃參數了

另外說一下自己的(~~偷懶~~)命名習慣 這類沒什麼語意的基礎單元, 我是滿喜歡用 .o 來當 class name 的 兩個 o .oo 代表小組件,常見的是線形, 而這邊因為沒有單軸向的單元 所以 .oo 就代表兩軸向的平面 三個 o 的 .ooo 就單純懶得想上層命名,嗯,就是這樣 XD

而稍後用到的 --oi 是指該單元(.o)的 index -ooi => .ooindex 很懶~ 但我覺得這樣還算直觀好記 XDD

2 單元點

因為對這類點的規則悟性不夠 並不像 Ana Tudor 一樣可以很迅速地推出參數與方程 XDD 所以最一開始我是做觀察 方法就是把 index, col index, row index 全部列上去 然後再慢慢去想該怎麼搭配組合出我想要的大小變化

image

就寫個 pseudo-element 塞一些 index 來看 看著上面這圖,再看看圖源 先找出規律性

2-1 單元點的尺寸

整體一起看會有點難想 那就一排排往下看;或先看邊界條件:看頭尾

第一排看起來是依照 col index 逐一遞增 1 最後一排剛好相反,依 col index 遞減

PS: 要看之前,得記得先定義 絕對大小 不然看第二排就大概忘記第一排的大小了 XD 這邊我是把第一排當作基準,最小的當 0 ,最大的當 15 (一排 16 顆)

看完頭尾兩列,再來看同樣是邊界的兩欄 第一欄也是很直觀地,依 row index 遞增 1;最末欄相反

不在邊線、中間的點點,看起來似乎不是單純整數的關係 雖然單看左上角,似乎有點像 x = y 的線性關係 但看 中央部份 跟 右上、左下的尺寸就明顯不同 所以應該沒那麼簡單~

接下來就是要算聯立方程了 嘿嘿嘿~ 正好我線性代數重修了三次

教授,抱歉,我全忘光了呢~ XDDD

線代不會沒關係~ 幸好我還記得國中的二元方程怎麼列 XD

若有人看不下去的,歡迎回覆救援~ XDD

這些點點的大小若化作座標點 每列連成線的話,大概就會長得像這圖:

image

先看第一列的線性函數(紅色那條) 左下座標 (0, 0) => { col:0, size:0 } 右上座標 (15, 15) => { col:15, size: 15 }

代入二元來解 a, b ax + b = y

row1: (0, 0), (15, 15)
	0a + b = 0
	15a + b = 15
		=> a = 1, b = 0
		=> row1: 1x + 0 = y
		=> row1: 15x/15 + 0 = y

row2: (0, 1), (15, 14)
	0a + b = 1
	15a + b = 14
		=> b = 1, a = 13 / 15
		=> 13x/15 + 1 = y

…

row16: (0, 15) (15, 0)
	0a + b = 15
	15a + b = 0
		=> b = 15, a = -1
		=> row15: -1x + 15 = y
		=> row15: -15x/15 + 15 = y

歸納出

y = x * (15 - 2 * row-index) / 15 + row-index

將 x, y 用參數代入

y : size
x : col-index(ci)
row-index(ri)

=> size = ci * (15 - ri * 2) / 15 + ri

15 = col count - 1 = col gap count

嗯~ 好吧 我刻完那張一堆線的圖 再打完上面那堆解聯立 我也不曉得到底有用到了什麼數學原理 數學能力大概只剩下:直觀感覺不出來的話,那就算了吧 XDD

不管如何~ 總算得到了圓點尺寸了呢~

而用在 CSS 裡的話,最好再處理一次數值 免得 CSS 裡還要寫一堆 normalization 算式 在 pug 裡有另外寫了一支 shiftNumber() 來處理數值轉換 裡頭也就只是簡單的線代 反正就是 x0-y0 線段上的 n 點映射到 x1-y1 線段後的座標點 當然這邊只用了單維,所以當作伸縮平移也就可以了~ 這段主要是輸出 CSS 要的數值範圍與格式 因為 CSS 那邊不太需要過多的小數點 算個大概就好,反正最小刻度也不能低於 1px, 一般狀況下精度不用太在意

很好,圓點大小就到這邊哩~

2-2 圓點對齊

原圖的對齊方式還挺奇妙的 我原本比為只是很普通地對齊正中心 結果細看之下,哇~ 這麼坑呀… 垂直對齊都是一致的正中心,很好 水平對齊方式真的奇葩:左邊的靠左、右邊的靠右…

我看了就碎念為什麼不弄成一樣的對齊方式…

不過後來想了一想, 覺得這設計還是有它的道理在 忘了是人眼是水平向的緣故、還是地平線的關係 人眼對於水平線的對齊會較為敏感 所以如果水平的對齊不一致的話,就會很突兀 垂直向就大概是設計師個人品味了吧(?

這邊就還滿簡單的 依據 col index,然後比例平移到 [0, 1] 之間即可 之後到 CSS 裡設定 transform-origin

2-3 圓點顏色

這邊看圖片 顏色分佈大概是右上到左下漸變 算式就比較簡單: col-index 與 row-index 的差值 因為套色會用算式來處理 所以記得讓差值正規化到 [1, -1] 區間

而在計算這種漸變色 通常會用 HSL 表式法來定義色彩

作法也挺簡單 就挑個支援 HSL 的取色器(或直接用 Chrome devtool 取色也可 得到的兩組 HSL,兩值取均值再加差值的一半 而這兩組 HSL 中的 S & L 數值差不多 所以就直接寫死了 反正我辨色力不佳~ XDD 如果設計師比較在意的話再一併調整也沒問題 :P

顏色、大小 都妥妥了~

3 動畫

上面做完後已經跟原版一樣了 但海報跟網頁有所不同, 網頁可以有更多互動嘛~

辛苦兜這麼久 當然不能只滿足於復現啦 一定得加點自己的料進去才行 XDD

原本是想弄成個上一個一樣 加些 transition 就好 但總覺得讓它們可以自己動起來好像會比較好玩

所以就加了 animation 進去 delay 時間就用 size 處理一下, 某方面來說,我們算出的 size 就是該點的 變化參數

要記得 animation 想先觸發動畫的話,delay 要設定成負數~

加好了之後,嗯~ 棒棒的

3-1 互動性

動態的有人喜歡,但也有些人喜歡靜態 能動能靜,兩種都能滿足的話不是更棒嗎~

在以往的 codepen 裡, 有些 CSS animation 我都是習慣讓滑鼠 :hover 過去後再啟動動畫 開發的時候也習慣先上一個 play-state: paused 一直動,很暈的…

所以在這邊用了 CSS variables + variables fallback animation-play-state: var(--animation-play-state, paused) 預設就先停止 滑過親代層時再啟動動畫,享受眼花撩亂 :hover { --animation-play-state: running }

但其中有個問題是 若滑鼠移入再移出,畫面就不再是初始狀態 會跟原本的圖源長得不一樣

這邊有用到另一個 CSS 小技巧來重設動畫

&:active { --animation-name: gg }

點擊時指派另外的動畫名稱(不一定要真實存在) 點擊狀態不再時,動畫就會回到初始狀態了

本來只是想記錄一下算數學那段 XDD 不過寫就寫了 就順便記錄一些有用到的小東西 :P


註:CSS custom property 使用習慣的變化

近來用的 CSS custom property(CSS variabls) 寫作習慣是有些些的不太一樣

以前會喜歡讓 HTML 完全乾淨,只有 class name 然後在 SCSS 裡下些迴圈生些 nth-of-type() 之類的選擇器 再配與相應的 index 或是 計算用參數

而最近有些作品,我會選擇直接將參數以 inline style 的方式刻在 DOM 上 像這例我就直接將 CSS 要用到的三個參數先算完再擺進 style 裡

前者用法的好處是,樣式就真的歸樣式處理 不會因為 DOM 因為 JS 新塞新的元件進去就 gg 沒套用到

但缺點就是 SCSS/CSS 會變得比較醜 比如說,這次的例子裡,pug 裡那些算式其實也可以放在 SCSS 裡處理 都只是一些四則運算而已, 在 CSS 裡單純用 --ci, --ri 加減乘除也是完全能處理過來的 但就真的是變得醜醜的 XD SCSS + calc + var() 的醜不是說說而已 XDD

另個原因是我覺得參數這類東西在 DOM 出來時就確立了 基本上不太會異動 這樣的情況我會比較喜歡直接在 pug 裡算完 然後在 CSS 裡寫比較明確與易懂的算式 CSS 算式寫太長,維護時讀起來有時會有點晃神 XDD


大概就這樣~ 支持的話可以到 codepen 點個 ♥️ 或是 follow ~

Rplus avatar Apr 28 '19 18:04 Rplus