【譯】只用 CSS 就能作到的像素畫/像素動畫

原文連接:box-shadowを使ってCSSだけでドット絵を描き、アニメーションさせるcss

做者推特:bc_rikkohtml

做者的推特里面有很多例子,有能力的同窗能夠看一下html5

這篇文章將會介紹只用 CSS 就能製做像素畫·像素動畫的方法。雖然說純 CSS 就能作到,可是爲了更高的可維護性,也會順便介紹使用 Sass 的製做方法。git

clipboard.png

clipboard.png

上面的馬里奧和 Minecraft 方塊都沒有使用 JavaScript,單純使用 CSS 動畫製做。github

關於 box-shadow 屬性

繪製像素點能夠藉助 box-shadow 屬性。sass

本來 box-shadow 屬性用於製做陰影效果,先介紹一下基本用法。動畫

該屬性的寫法有幾種:ui

  • box-shadow: offset-x offset-y color
  • box-shadow: offset-x offset-y blur-radius color
  • box-shadow: offset-x offset-y blur-radius spread-radius color
  • box-shadow: inset offset-x offset-y color

offset-xoffset-y 用於指定陰影偏移位置。以元素的左上角爲原點,指定 XY 軸移動的位置。spa

color 字面意思,指定陰影顏色。.net

blur-radius 指定模糊效果的半徑。跟 border-radius 差很少。

spread-raduis 模糊範圍的擴大與縮小。

inset 關鍵字能夠使陰影效果顯示在元素內則。

文字說明或許不夠形象,咱們能夠直接看效果:

jsfiddle.net/bc_rikko/0b…

實際效果以下,每一個值會形成什麼影響應該能很直觀地看懂。

基礎:描繪一個像素點

box-shadow 基礎都明白了,就能夠進入下一步:描繪一個像素點。

對一個邊長 100px 的正方形使用 box-shadow

<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>
複製代碼

clipboard.png

如圖所示,使用 box-shadow 描繪了一個與元素相同大小的陰影。代碼的意思是把一個 100px 的方形的影子放到 (100px, 100px) 的位置。

進階:用 box-shadow 屬性繪製像素畫

完成預想圖

完成預想圖
這兩個都是 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:
     /* 列&emsp;行 色 */
     /* 第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 類的大小決定,因此把 widthheight設定爲 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;
}
複製代碼

應用:使用 Sass 編寫可維護像素畫

上面寫的幾個例子,至少我是沒什麼信心去維護好他們。5x5 的像素畫要寫 25 次屬性值,通常的 16x16 則是多達 256 個值。

因此,咱們能夠使用 Sass 編寫可維護像素畫。

Sass 環境搭建能夠參考如下文章(日語)

kuroeveryday.blogspot.com/2018/10/set…

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 像素畫生成器~

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 倉庫中瞭解

github.com/BcRikko/css…

相關文章
相關標籤/搜索