iT邦幫忙

2021 iThome 鐵人賽

DAY 15
0
Modern Web

30天30個前端任務系列 第 19

#19. 3D Background Boxes

這次的任務是透過偽元素來打造立體盒子,同時利用background position屬性來做出方塊組成的效果。有點像幼兒會玩的立體方塊拼圖。

https://ithelp.ithome.com.tw/upload/images/20210923/201305343FUa3abmkj.png

讓我們先看一下成果:CodePen


實作方法

讓我們來了解一下圖片是如何被拼起來的:
https://ithelp.ithome.com.tw/upload/images/20210923/20130534c6RZhYZAfO.png

從上圖可以見到,一幅完整的小小兵圖像,實際上是由16個拼起來的,而每個所顯示的圖像區塊,則透過background-position來指定。由於外層div.boxes的寬高是500px,分割給16個div.box,每個div.box的寬高便是125px,在background-position的位移,也就會以125px為一個單位來移動。

https://ithelp.ithome.com.tw/upload/images/20210923/20130534GfTloVdASf.png

當我們按下Magic按鈕,則透過Javascript在div#boxes如果再加上了big選擇器,這時候div#boxes的寬高就變成600px,而內層的16個div.box高寬不變,這時使用flexbox的justify-content: space-around分配剩餘空間,就會整齊地將16個div.box分開。在這之前,要注意兩個屬性

  1. flex-wrap要設定成wrap,讓內層div.box佔滿一行後自動跳到下一行。
  2. 外層div#boxes的寬度必須要在624px以內,否則第五個方塊就會擠到第一行。

最後再利用偽元素做出右下方的border,就會產生立體方塊的視覺效果


程式碼部分

Javascript

const boxesContainer = document.getElementById('boxes')
const btn = document.getElementById('btn')

// 點擊按鈕,toggle big選擇器
btn.addEventListener('click', () => boxesContainer.classList.toggle('big'))

// 利用雙層迴圈產生16個div.box,放入boxesContainer當中,同時利用迴圈將backgroundPosition的屬性設定好。
function createBoxes() {
  for (let i = 0; i < 4; i++) {
    for (let j = 0; j < 4; j++) {
      const box = document.createElement('div')
      box.classList.add('box')
      box.style.backgroundPosition = `${-j * 125}px ${-i * 125}px`
      boxesContainer.appendChild(box)
    }
  }
}

createBoxes()

CSS

.boxes {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-around;
  height: 500px;
  width: 500px;
  position: relative;
  transition: 0.4s ease;

  &.big {
    width: 624px;
    height: 624px;
    .box {
      transform: rotateZ(180deg);
    }
  }
}

.box {
  background-image: url('https://media.giphy.com/media/EZqwsBSPlvSda/giphy.gif');
  background-repeat: no-repeat;
  background-size: 500px 500px;
  position: relative;
  height: 125px;
  width: 125px;
  transition: 0.4s ease;

  /* 利用偽元素做出box的立體面 */
  &::after {
    content: '';
    background-color: #f6e58d;
    position: absolute;
    top: 8px;
    right: -15px;
    height: 100%;
    width: 15px;
    transform: skewY(45deg);
  }
  
  &::before {
    content: '';
    background-color: #f9ca24;
    position: absolute;
    bottom: -15px;
    left: 8px;
    height: 15px;
    width: 100%;
    transform: skewX(45deg);
  }
}

上一篇
#18. Fixed Navbar(原生JS版)
系列文
30天30個前端任務19

尚未有邦友留言

立即登入留言