Flex Panel Gallery

講者:琪雅

時間:2019/12/4

OUTLINE

  • HTML

  • CSS

  • JavaScript

HTML 

  1. 寫一個網頁,由一個大div包著五個小div,每個div都要設置class名稱。

  2. 大div的class名稱設為panels

  3. div的class名稱設為panel panel1,依序往下編碼

  4. 每個div裡面用p寫三段文字

 

HTML 

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Flex Panel Gallery</title>
</head>
<body>
	<div class="panels">
        <div class="panel panel1">
            <p>Hey</p>
            <p>Let's</p>
            <p>Dance</p>
        </div>
        <div class="panel panel2">
            <p>Give</p>
            <p>Take</p>
            <p>Receive</p>
        </div>
        <div class="panel panel3">
            <p>Experience</p>
            <p>It</p>
            <p>Today</p>
        </div>
        <div class="panel panel4">
            <p>Give</p>
            <p>All</p>
            <p>You can</p>
        </div>
        <div class="panel panel5">
            <p>Life</p>
            <p>In</p>
            <p>Motion</p>
        </div>
    </div>

</body>
</html>

css 

  • 用style標籤寫進head裡面,以background-image: url(); 的方式在5個小div的地方分別插入五種不同的圖片
<style>    
    .panel1 {
        background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
    }
    .panel2 {
        background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
    }
    .panel3 {
        background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
    }
    .panel4 {
        background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
    }
    .panel5 {
        background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
    }
</style> 

css 

<style>
    html {
        box-sizing: border-box;
    }
    body {
        margin: 0; /*定義一個區域(例如DIV 或span)的外邊界距離,俗稱外距*/
    }
    .panel1 {
        background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
    }
    .panel2 {
        background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
    }
    .panel3 {
        background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
    }
    .panel4 {
        background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
    }
    .panel5 {
        background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
    }
</style>
  • 針對html、body做區塊調整

  • box-sizing: 用來調整區塊的內距與邊框

    • border-box包含內容寬度、內距與邊框寬度。

    • content-box設定的寬度僅為內容寬度,而內距與邊框額外加上去。

    • inherit繼承至父層的 broder-sizing 設定値。

  • 利用margin (外距) 使div區塊的圖片充滿網頁頁面

css 

<style>
    html {
        box-sizing: border-box; 
    }
    body {
        margin: 0; /*定義一個區域(例如DIV 或span)的外邊界距離,俗稱外距*/
    }
    .panels {
        min-height: 100vh; /*最低高度值*/
        overflow: hidden; /*元素超過某個範圍的時候該如何呈現 hidden自動隱藏超出的文字或圖片*/
        display: flex; /*宣告*/
    }
    .panel {
        color: white;
        text-align: center;
        align-items: center;
        /* Safari transitionend event.propertyName === flex */
        /* Chrome + FF transitionend event.propertyName === flex-grow */
        transition: font-size 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), flex 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), background 0.2s;
        /* transition: property duration timing-function delay;
            property用來定義可以產生 transition 屬性效果的屬性名稱,例如寬度、背景顏色 ...。
            duration用來定義 transition 屬性發生的時間,單位為秒。
            timing-function用來定義 transition 效果的發生速度。
            delay用來定義多久之後開始發生 transition 效果。*/
        font-size: 20px; /*字的大小*/
        background-size: cover;
        background-position: center;
        flex: 1;
        justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
        display: flex; 
        flex-direction: column; /*改變軸線方向 column垂直從上往下排列*/
    }
    .panel1 {
        background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
    }
    .panel2 {
        background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
    }
    .panel3 {
        background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
    }
    .panel4 {
        background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
    }
    .panel5 {
        background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
    }
</style>

設定div區塊

css 

<link href='https://fonts.googleapis.com/css?family=Amatic+SC' rel='stylesheet' type='text/css'>
<style>
    html {
        box-sizing: border-box; 
    }
    body {
        margin: 0; /*定義一個區域(例如DIV 或span)的外邊界距離,俗稱外距*/
    }
    .panels {
        min-height: 100vh; /*最低高度值*/
        overflow: hidden; /*元素超過某個範圍的時候該如何呈現 hidden自動隱藏超出的文字或圖片*/
        display: flex; /*宣告*/
    }
    .panel {
        color: white;
        text-align: center;
        align-items: center;
        /* Safari transitionend event.propertyName === flex */
        /* Chrome + FF transitionend event.propertyName === flex-grow */
        transition: font-size 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), flex 0.7s cubic-bezier(0.61, -0.19, 0.7, -0.11), background 0.2s;
        /* transition: property duration timing-function delay;
            property用來定義可以產生 transition 屬性效果的屬性名稱,例如寬度、背景顏色 ...。
            duration用來定義 transition 屬性發生的時間,單位為秒。
            timing-function用來定義 transition 效果的發生速度。
            delay用來定義多久之後開始發生 transition 效果。*/
        font-size: 20px; /*字的大小*/
        background-size: cover;
        background-position: center;
        flex: 1;
        justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
        display: flex; 
        flex-direction: column; /*改變軸線方向 column垂直從上往下排列*/
    }
    .panel1 {
        background-image: url(https://source.unsplash.com/gYl-UtwNg_I/1500x1500);
    }
    .panel2 {
        background-image: url(https://source.unsplash.com/1CD3fd8kHnE/1500x1500);
    }
    .panel3 {
        background-image: url(https://images.unsplash.com/photo-1465188162913-8fb5709d6d57?ixlib=rb-0.3.5&q=80&fm=jpg&crop=faces&cs=tinysrgb&w=1500&h=1500&fit=crop&s=967e8a713a4e395260793fc8c802901d);
    }
    .panel4 {
        background-image: url(https://source.unsplash.com/ITjiVXcwVng/1500x1500);
    }
    .panel5 {
        background-image: url(https://source.unsplash.com/3MNzGlQM7qs/1500x1500);
    }

    /* Flex Items */
    .panel>* {
        margin: 0;
        width: 100%;
        transition: transform 0.5s; /*transition屬性實現簡單旋轉效果*/
        flex: 1 0 auto; 
        /*flex-grow flex-shrink flex-basis
          flex-grow: 元件的伸展性
          flex-shrink: 元件的收縮性
          flex-basis: 元件的基準值*/
        display: flex;
        justify-content: center; /* 確定項目位於容器中心(可用於留白的語法)*/
        align-items: center; /*交錯軸的對齊設定*/
    }

    /* :first-child() & :last-child()
        CSS的:偽類別,分別可以選取first(第一個)/last(最後一個)子元素*/
    .panel>*:first-child {
        transform: translateY(-100%);  /*translateY(y)   定義 Y 軸方向的 2D 轉換*/
    }
    .panel.open-active>*:first-child {
        transform: translateY(0);
    }
    .panel>*:last-child {
        transform: translateY(100%);
    }
    .panel.open-active>*:last-child {
        transform: translateY(0);
    }
    .panel p {
        text-transform: uppercase; /*控制文章中的文字字母大小寫*/
        font-family: 'Amatic SC', cursive;
        text-shadow: 0 0 4px rgba(0, 0, 0, 0.72), 0 0 14px rgba(0, 0, 0, 0.45);  /*X 軸方向的陰影 Y 軸方向的陰影 模糊範圍 陰影顏色*/
        font-size: 2em;
    }
    .panel p:nth-child(2) {
        font-size: 4em;
    }
    .panel.open {
        flex: 5;
        font-size: 40px;
    }
</style>

設定動畫

JavaScript

  1. 宣告取得所有的div 區塊

  2. 宣告一個上次點擊的Panel,預設先給他panels

let panels = document.querySelectorAll('.panel');

let lastClickPanel = document.querySelector('.panels');

JavaScript

  1. 寫一個函式,使每次點擊都是一個聚焦效果(關閉其他已展開的)

    1. 用if 檢查進入的element與上次進入的element是不是相同

    2. 若不相同,則把上次點擊的element移除open效果

    3. 再把lastClickPanel指向為這次的elment

  2. 用.classList.toggle觸發這個動畫class

function toggleOpen() {
    if (this !== lastClickPanel) {
    lastClickPanel.classList.remove('open');
    lastClickPanel = this;
    }
this.classList.toggle('open');
}

JavaScript

  • 寫一個函式,使點擊後會動畫展開的圖片展示效果

    1. ​e.propertyName可以抓到觸發transitionend的屬性

    2. 利用.includes('flex')來判斷, 只要e.property`有包含到flex的字串就使其通過判斷,加入動畫效果。

    3. 用.classList.toggle觸發這個動畫class

function toggleActive(e) {
    console.log(e.propertyName);
    if (e.propertyName.includes('flex')) {
    	this.classList.toggle('open-active');
    }
}

JavaScript

  • 用panels.forEach設定所有的panel都能用click觸發addEventLinstner中的toggleOpen以及觸發了transitionend來作動toggleActive。

panels.forEach(panel => panel.addEventListener('click', toggleOpen));
panels.forEach(panel => panel.addEventListener('transitionend', toggleActive));

參考來源

Flex Panel Gallery hackmd:https://hackmd.io/JZMu13B2Rp-roHcEfqjKrw?view

Thank you for listening.

 

Flex Panel Gallery

By q8745912

Flex Panel Gallery

  • 136