如何用CSS繪製插圖(下)

Bonnie Shih
✨ 黑洞創造 BlackHole Creative ✨
18 min readJun 20, 2022

還沒看過上集的人可以點擊這裡前往:如何用CSS繪製插圖(上)

上一篇我們繪製了怪物的基本外型,現在我們要為他加上手槍並製作動畫,下方是最終希望呈現的樣子。

(在Medium看動畫速度會比較慢,下載後觀看GIF是正常速度)

首先,我們先做出手部,為了之後做動畫方便,要先創造一個透明的框arm,所以我們在CSS接著寫下:

.arm {
height: 32px;
width: 71px;
position: absolute;
left: 325px;
bottom: 135px;
}
.hand {
height: 32px;
width: 71px;
background-color: #9e3ecc;
position: absolute;
border-radius: 0px 10px 10px 0px;
}
.sleeve {
height: 32px;
width: 47px;
background-color: #3c0f51;
position: absolute;
}

因為要把手藏在最後方,所以我們把手部寫在HTML的jacket-back上方。

<div class="arm">
<div class="hand"></div>
<div class="sleeve"></div>
</div>

結果會是這樣(截圖會有色差):

手槍

接下來我們來做手槍,把手槍放在手前面的話,實際會是這個樣子,因為將手槍置於手的後方時,把手會被擋住,所以在此省略。為了動畫方便,我們要將手槍寫在arm裡🔫

CSS:

.gun{
width:50px;
height:24px;
position:absolute;
left:49px;
bottom:22px;
}
.bullet{
width: 6px;
height: 6px;
background-color: #ffffff;
border-radius: 50%;
position: absolute;
top: 6px;
left: 0px;
}
.gun-top,.gun-mid{
width:50px;
height:8px;
position:absolute;
}
.gun-top{
background-color:#561574;
top:0px;
}
.gun-mid{
background-color:#3c0f51;
top:8px;
}
.gun-1,.gun-2,.gun-3 {
background-color: #9e3ecc;
width: 2px;
height: 10px;
position: absolute;
}
.gun-1 {
left: 4px;
}
.gun-2 {
left: 8px;
}
.gun-3 {
left: 12px;
}
.trigger-1{
background-color:#3c0f51;
width:10px;
height:8px;
left:16px;
bottom:0px;
position:absolute;
}
.trigger-2{
background-color:#45dde7;
width:6px;
height:4px;
left:16px;
bottom:4px;
position:absolute;
}

HTML在<div class=”arm”>之中、<div class=”hand”></div>上方寫下:

<div class="gun">
<div class="bullet"></div>
<div class="gun-top"></div>
<div class="gun-mid"></div>
<div class="gun-1"></div>
<div class="gun-2"></div>
<div class="gun-3"></div>
<div class="trigger-1"></div>
<div class="trigger-2"></div>
</div>

結果會是這樣:

然後我們先把整隻手藏到身體後方,就會變成上集成果看起來的樣子。

.arm{
height: 32px;
width: 71px;
position: absolute;
left: 233px;
bottom: 110px;
}

動畫

接著到了動畫的部分,若是有使用過動畫相關軟體的經驗,一定知道「關鍵幀」吧!在CSS做動畫時也需要這個概念。我們預計做的動態會應用在「pupil」、「arm」、「bullet」三個元件上。

開始前,先規劃動畫呈現與秒數如下圖。

首先是pupil,在CSS接著寫下:

@keyframes change-pupil {
10% {
left: 18px;
}
30% {
left: 33px;
}
70% {
left: 33px;
}
90% {
left: 18px;
}
}
.pupil-animation {
animation-name: change-pupil;
animation-duration: 5s;
animation-iteration-count: infinite;
}

並在HTML的pupil-r、pupil-l後加上pupil-animation,為了方便理解,放上整段程式:

<div class="eye-r">
<div class="pupil-r pupil-animation"></div>
<div class="eyelid-r"></div>
</div>
<div class="eye-l">
<div class="pupil-l pupil-animation"></div>
<div class="eyelid-l"></div>
</div>

這樣瞳孔就會從中間移動到右邊了👀

再來是手臂伸出來的動畫,我們在CSS寫下:

@keyframes change-arm {
10% {
left: 233px;
bottom: 110px;
}
30% {
left: 325px;
bottom: 135px;
}
70% {
left: 325px;
bottom: 135px;
}
90% {
left: 233px;
bottom: 110px;
}
}
.arm-animation {
animation-name: change-arm;
animation-duration: 5s;
animation-iteration-count: infinite;
}

HTML:

<div class="arm arm-animation"></div>

這樣手臂伸出來的動態也完成了!最後是子彈的部分,這邊比較特別,因為本次的動畫要做loop效果,所以透過增加一個控制透明度的change-bullet2來幫助我們以純CSS完成。

CSS:

@keyframes change-bullet {
0% {
left: 0px;
}
100% {
left: 150px;
}
}
@keyframes change-bullet2 {
29% {
opacity: 0;
}
30% {
opacity: 100;
}
70%{
opacity: 100;
}
71% {
opacity: 0;
}
}
.bullet-animation {
animation-name: change-bullet, change-bullet2;
animation-duration: 0.1s, 5s;
animation-iteration-count: infinite, infinite;
animation-delay: 1.5s, 0s;
}

HTML:

<div class=”bullet bullet-animation”></div>

然後記得將前面bullet的不透明度改為0:

.bullet {
width: 6px;
height: 6px;
background-color: #ffffff;
border-radius: 50%;
position: absolute;
top: 6px;
left: 0px;
opacity:0;
}

這樣我們的loop動畫就完成了🌟

程式統整

CSS:

body {
background-color: #a2edf2;
}
.container {
height: 500px;
width: 500px;
background-color: #45dde7;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
margin: auto;
display: flex;
align-items: center;
justify-content: center;
}
.jacket-back {
height: 80px;
width: 200px;
background-color: #3c0f51;
border-radius: 100px 100px 0px 0px;
position: absolute;
bottom: 110px;
}
.monster {
position: relative;
height: 280px;
width: 152px;
background-color: #9e3ecc;
border-radius: 20px 20px 0px 0px;
}
.jacket {
position: absolute;
bottom: 0px;
left: -10px;
width: 171px;
height: 134px;
}
.jacket-l,.jacket-r {
width: 85px;
height: 85px;
background: #3c0f51;
top: 0px;
position: absolute;
}
.jacket-l{
-webkit-clip-path: polygon(0% 42%, 12% 100%, 100% 100%);
left: 0px;
}
.jacket-r {
-webkit-clip-path: polygon(100% 42%, 0% 100%, 89% 100%);
right: 0px;
}
.jacket-front {
height: 50px;
width: 152px;
background-color: #3c0f51;
position: absolute;
bottom: 0px;
left: 10px;
}
.eye-r,
.eye-l {
height: 60px;
width: 60px;
background-color: white;
border-radius: 50%;
position: absolute;
top: 100px;
}
.eye-r {
left: 16px;
}
.eye-l {
left: 76px;
}
.pupil-r,.pupil-l {
height: 24px;
width: 24px;
background-color: #3c0f51;
border-radius: 50%;
position: absolute;
top: 18px;
left: 18px;
}
.eyelid-r {
height: 30px;
width: 60px;
background-color: #cf90ed;
border-radius: 30px 30px 0px 0px;
position: absolute;
top: 0px;
left: 0px;
}
.eyelid-l {
height: 30px;
width: 60px;
background-color: #cf90ed;
border-radius: 30px 30px 0px 0px;
position: absolute;
top: 0px;
left: 0px;
}
.mouth {
height: 4px;
width: 24px;
background-color: white;
position: absolute;
top: 166px;
left: 64px;
}
.hat {
position: absolute;
top: 0px;
left: -12px;
}
.hat-top {
height: 52px;
width: 152px;
background-color: #3c0f51;
position: absolute;
top: 0px;
left: 12px;
border-radius: 20px 20px 0px 0px;
}
.hat-mid {
height: 10px;
width: 152px;
background-color: #45dde7;
position: absolute;
top: 42px;
left: 12px;
}
.hat-bottom {
height: 28px;
width: 176px;
background-color: #3c0f51;
position: absolute;
top: 52px;
left: 0px;
}
.arm {
height: 32px;
width: 71px;
position: absolute;
left: 233px;
bottom: 110px;
}
.hand {
height: 32px;
width: 71px;
background-color: #9e3ecc;
position: absolute;
border-radius: 0px 10px 10px 0px;
}
.sleeve {
height: 32px;
width: 47px;
background-color: #3c0f51;
position: absolute;
}
.gun {
width: 50px;
height: 24px;
position: absolute;
left: 49px;
bottom: 22px;
}
.bullet {
width: 6px;
height: 6px;
background-color: #ffffff;
border-radius: 50%;
position: absolute;
top: 6px;
left: 0px;
opacity:0;
}
.gun-top,.gun-mid{
width:50px;
height:8px;
position:absolute;
}
.gun-top{
background-color:#561574;
top:0px;
}
.gun-mid{
background-color:#3c0f51;
top:8px;
}
.gun-1,.gun-2,.gun-3 {
background-color: #9e3ecc;
width: 2px;
height: 10px;
position: absolute;
}
.gun-1 {
left: 4px;
}
.gun-2 {
left: 8px;
}
.gun-3 {
left: 12px;
}
.trigger-1 {
background-color: #3c0f51;
width: 10px;
height: 8px;
left: 16px;
bottom: 0px;
position: absolute;
}
.trigger-2 {
background-color: #45dde7;
width: 6px;
height: 4px;
left: 16px;
bottom: 4px;
position: absolute;
}
@keyframes change-arm {
10% {
left: 233px;
bottom: 110px;
}
30% {
left: 325px;
bottom: 135px;
}
70% {
left: 325px;
bottom: 135px;
}
90% {
left: 233px;
bottom: 110px;
}
}
.arm-animation {
animation-name: change-arm;
animation-duration: 5s;
animation-iteration-count: infinite;
}
@keyframes change-pupil {
10% {
left: 18px;
}
30% {
left: 33px;
}
70% {
left: 33px;
}
90% {
left: 18px;
}
}
.pupil-animation {
animation-name: change-pupil;
animation-duration: 5s;
animation-iteration-count: infinite;
}
@keyframes change-bullet {
0% {
left: 0px;
}
100% {
left: 150px;
}
}
@keyframes change-bullet2 {
29% {
opacity: 0;
}
30% {
opacity: 100;
}
70%{
opacity: 100;
}
71% {
opacity: 0;
}
}
.bullet-animation {
animation-name: change-bullet, change-bullet2;
animation-duration: 0.1s, 5s;
animation-iteration-count: infinite, infinite;
animation-delay: 1.5s, 0s;
}

HTML:

<div class="container">
<div class="arm arm-animation">
<div class="gun">
<div class="bullet bullet-animation"></div>
<div class="gun-top"></div>
<div class="gun-mid"></div>
<div class="gun-1"></div>
<div class="gun-2"></div>
<div class="gun-3"></div>
<div class="trigger-1"></div>
<div class="trigger-2"></div>
</div>
<div class="hand"></div>
<div class="sleeve"></div>
</div>
<div class="jacket-back"></div>
<div class="monster">
<div class="jacket">
<div class="jacket-front"></div>
<div class="jacket-l"></div>
<div class="jacket-r"></div>
</div>
<div class="eye-r">
<div class="pupil-r pupil-animation"></div>
<div class="eyelid-r"></div>
</div>
<div class="eye-l">
<div class="pupil-l pupil-animation"></div>
<div class="eyelid-l"></div>
</div>
<div class="mouth"></div>
<div class="hat">
<div class="hat-top"></div>
<div class="hat-mid"></div>
<div class="hat-bottom"></div>
</div>
</div>
</div>

--

--