原文連接: box-shadowを使ってCSSだけでドット絵を描き、アニメーションさせる
做者推特: bc_rikko
做者的推特里面有很多例子,有能力的同窗能夠看一下
翻譯博客地址: https://ssshooter.com/css-pixel/
這篇文章將會介紹只用 CSS 就能製做像素畫·像素動畫的方法。雖然說純 CSS 就能作到,可是爲了更高的可維護性,也會順便介紹使用 Sass 的製做方法。css
上面的馬里奧和 Minecraft 方塊都沒有使用 JavaScript,單純使用 CSS 動畫製做。html
繪製像素點能夠藉助 box-shadow 屬性。
本來 box-shadow 屬性用於製做陰影效果,先介紹一下基本用法。html5
該屬性的寫法有幾種:git
offset-x
和 offset-y
用於指定陰影偏移位置。以元素的左上角爲原點,指定 XY 軸移動的位置。color
字面意思,指定陰影顏色。blur-radius
指定模糊效果的半徑。跟 border-radius 差很少。spread-raduis
模糊範圍的擴大與縮小。inset
關鍵字可使陰影效果顯示在元素內則。github
文字說明或許不夠形象,咱們能夠直接看效果:sass
https://jsfiddle.net/bc_rikko...ssh
實際效果以下,每一個值會形成什麼影響應該能很直觀地看懂。
動畫
box-shadow
基礎都明白了,就能夠進入下一步:描繪一個像素點。
對一個邊長 100px 的正方形使用 box-shadow
:ui
<div class="container"> <div class="box"></div> </div> <style> * { /* 爲了方便看到元素而添加的邊框(不加也行) */ box-sizing: border-box; } .container { /* 長和寬包括 box-shadow */ width: 200px; height: 200px; } .box { /* 元素屬性 */ width: 100px; height: 100px; border: 2px solid #777; /* 在元素右下角相同大小的方塊 */ box-shadow: 100px 100px rgba(7,7,7,.3); } </style>
如圖所示,使用 box-shadow 描繪了一個與元素相同大小的陰影。代碼的意思是把一個 100px 的方形的影子放到 (100px, 100px) 的位置。spa
完成預想圖
這兩個都是 5✖️5 的像素畫,咱們先從左邊開始:
<div class="container"> <div class="pixel one"></div> </div> <style> .container { /* 像素畫的大小 */ width: 100px; height: 100px; } .pixel { /* 使僞元素的位置可調整 */ position: relative; } .pixel::before { content: ""; /* 一個點的大小(例:20px x 20px) */ width: 20px; height: 20px; /* box-shadow 着色,僞元素設爲透明 */ background-color: transparent; /* 調整僞元素位置,讓左上角成爲(0,0) */ position: absolute; top: -20px; left: -20px; } .pixel.one::before { box-shadow: /* 列 行 色 */ /* 第1列 */ 20px 20px #FB0600, 20px 40px #FC322F, 20px 60px #FC6663, 20px 80px #FD9999, 20px 100px #FECCCB, /* 第2列 */ 40px 20px #60169F, 40px 40px #7A23B0, 40px 60px #964DC2, 40px 80px #B681D9, 40px 100px #D8BEED, /* 第3列 */ 60px 20px #1388BC, 60px 40px #269DC9, 60px 60px #55B3D7, 60px 80px #88CAE2, 60px 100px #BFE3EF, /* 第4列 */ 80px 20px #ACD902, 80px 40px #BDE02D, 80px 60px #CDEA5E, 80px 80px #DBEF8E, 80px 100px #F4FBC8, /* 第5列 */ 100px 20px #FB8F02, 100px 40px #FDA533, 100px 60px #FDBB64, 100px 80px #FED39A, 100px 100px #FDE8C9; } </style>
首先,box-shadow
生產的影子大小不包括本體元素的大小,container
類的大小設爲像素畫完成後的大小就行。
接着,box-shadow
的影子大小由,pixel
類的大小決定,因此把 width
和 height
設定爲 20px。
實際的點是 before 僞元素繪製的,pixel 的 20px 正方形會在左上角留下空位,爲此可使用 position: absolute
調整。
最後使用 box-shadow 逐格繪製像素畫。
接着實現右邊的像素畫。
.pixel.two::before { box-shadow: 20px 20px #704b16, 40px 20px #704b16, 60px 20px #704b16, 80px 20px #704b16, 100px 20px #704b16, 20px 40px #704b16, 40px 40px #fdb778, 60px 40px #fdb778, 80px 40px #fdb778, 100px 40px #704b16, 20px 60px #fdb778, 40px 60px #333333, 60px 60px #fdb778, 80px 60px #333333, 100px 60px #fdb778, 20px 80px #fdb778, 40px 80px #fdb778, 60px 80px #fdb778, 80px 80px #fdb778, 100px 80px #fdb778, 20px 100px #fdb778, 40px 100px #c70300, 60px 100px #c70300, 80px 100px #c70300, 100px 100px #fdb778; }
上面寫的幾個例子,至少我是沒什麼信心去維護好他們。5x5 的像素畫要寫 25 次屬性值,通常的 16x16 則是多達 256 個值。
因此,咱們可使用 Sass 編寫可維護像素畫。
Sass 環境搭建能夠參考如下文章(日語)
https://kuroeveryday.blogspot...
Sass 使用 mixin(function 亦可)生成樣式的方法:
@mixin pixelize($matrix, $size, $colors) { $ret: ""; @for $i from 1 through length($matrix) { $row: nth($matrix, $i); @for $j from 1 through length($row) { $dot: nth($row, $j); @if $dot != 0 { @if $ret != "" { $ret: $ret + ","; } $color: nth($colors, $dot); $ret: $ret + ($j * $size) + " " + ($i * $size) + " " + $color; } } } box-shadow: unquote($ret + ";"); } $heart-colors: (#333, #f11416, #831200); $heart: ( (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), (0,0,1,1,1,0,0,0,0,0,1,1,1,0,0,0), (0,1,2,2,2,1,0,0,0,1,2,2,3,1,0,0), (1,2,0,0,2,2,1,0,1,2,2,2,2,3,1,0), (1,2,0,2,2,2,2,1,2,2,2,2,2,3,1,0), (1,2,2,2,2,2,2,2,2,2,2,2,2,3,1,0), (1,2,2,2,2,2,2,2,2,2,2,2,2,3,1,0), (1,2,2,2,2,2,2,2,2,2,2,2,2,3,1,0), (0,1,2,2,2,2,2,2,2,2,2,2,3,1,0,0), (0,0,1,2,2,2,2,2,2,2,2,3,1,0,0,0), (0,0,0,1,2,2,2,2,2,2,3,1,0,0,0,0), (0,0,0,0,1,2,2,2,2,3,1,0,0,0,0,0), (0,0,0,0,0,1,2,2,3,1,0,0,0,0,0,0), (0,0,0,0,0,0,1,3,1,0,0,0,0,0,0,0), (0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ); .icon { width: 20px; height: 20px; @include pixelize($heart, 20px, $heart-colors); }
定義名爲 pixelize
的 mixin,把像素畫的矩陣($heart
)像素點的大小(20px
)顏色列表($hearts-colors
)傳入其中,便可生成 box-shadow 屬性。
像素畫的矩陣用數字 0~N 表示,0 爲透明,1~n 爲顏色列表對應顏色。
若是有代碼高亮的話,像素畫的圖案就一目瞭然啦。
與原生 CSS 相比,這樣簡單多了吧?
若是這樣都以爲麻煩,可使用 CSS 像素畫生成器~
以前 icon
類直接使用 box-shadow 屬性繪製像素畫,在製做像素動畫時,須要使用 CSS animation。
.mario { width: 8px; height: 8px; animation: jump 1s infinite, sprite 1s infinite; } /* 跳躍動做(上下移動) */ @keyframes jump { from, 25%, 75%, to { transform: translateY(0); } 50% { transform: translateY(calc(8px * -8)); } } /* 普通狀態和跳躍狀態的像素畫 */ @keyframes sprite { /* 對比 animation-timing-function: steps(n) * 使用百分比能夠更細緻的調整動畫時間 */ from, 24%, 76%, to { box-shadow: /* 普通狀態的像素畫 */ } 25%, 75% { box-shadow: /* 跳躍狀態的像素畫 */ } }
使用 CSS 動畫修改 box-shadow 和元素的位置,看起來就像是跳起來同樣。
詳細代碼能夠在 github 倉庫中瞭解
https://github.com/BcRikko/cs...