分類彙整:Uncategorized

flex#7 align-content

注意事項

  • flex-wrap需要為wrap
  • 只考慮與cross-axis的關係

範例

align-content: stretch (default)

效果:填滿cross-axis

.container
 .box.box1 1
 .box.box2 
  |2
  br
  |:)
 .box.box3 3
 .box.box4 4
 .box.box5 5
 .box.box6 6
 .box.box7 7
 .box.box8 8
 .box.box9 9
 .box.box10 10
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 30%

.container
  display: flex
  border: 10px solid mistyrose
  height: 100vh
  flex-wrap: wrap
  align-content: stretch
1
2
🙂
3
4
5
6
7
8
9
10

align-content: flex-start

集中於上方

.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 30%

.container
  display: flex
  border: 10px solid mistyrose
  height: 100vh
  flex-wrap: wrap
  align-content: flex-start
1
2
🙂
3
4
5
6
7
8
9
10

align-content: flex-end

集中於下方

.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 30%

.container
  display: flex
  border: 10px solid mistyrose
  height: 100vh
  flex-wrap: wrap
  align-content: flex-end
1
2
🙂
3
4
5
6
7
8
9
10

align-content: space-between

平均分散

.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 30%

.container
  display: flex
  border: 10px solid mistyrose
  height: 100vh
  flex-wrap: wrap
  align-content: space-between
1
2
🙂
3
4
5
6
7
8
9
10

align-content: center

集中於中間

.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 30%

.container
  display: flex
  border: 10px solid mistyrose
  height: 100vh
  flex-wrap: wrap
  align-content: center
1
2
🙂
3
4
5
6
7
8
9
10

補充:讓「10」也可以水平置中

使用justify-content: center

.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 30%

.container
  display: flex
  border: 10px solid mistyrose
  height: 100vh
  flex-wrap: wrap
  align-content: center
  justify-content: center
1
2
🙂
3
4
5
6
7
8
9
10

flex#6 align-items

定義
justify-content會沿著cross-axis對齊

快速複習

  • 【預設】flex-direction: row,cross-axis為由由上至下↓↓↓
  • flex-direction: column,cross-axis為左至右→→→

重點

  • 外層wrapper要有足夠的空間(否則align-items沒空間發揮)
  • 每個item嘗試使用不同的高度(以便看出效果差異)

cross-axis為由上至下時(預設)

align-items: stretch(預設)

效果:填滿

.container
  display: flex
  border: 10px solid mistyrose
  height: 400px
  align-items: stretch

.box1
  font-size: 30px
 
.box3
  font-size: 150px
1
2
3
4
5
6
7
8
9
10

align-items: center

集中在中間

.container
  display: flex
  border: 10px solid mistyrose
  height: 400px
  align-items: center
1
2
3
4
5
6
7
8
9
10

align-items: flex-end

集中於下方

.container
  display: flex
  border: 10px solid mistyrose
  height: 400px
  align-items: flex-end
1
2
3
4
5
6
7
8
9
10

align-items: flex-start

集中於上方(貼齊上緣)

.container
  display: flex
  border: 10px solid mistyrose
  height: 400px
  align-items: flex-start
1
2
3
4
5
6
7
8
9
10

align-items: baseline

集中於上方(items自己置中對齊)

.container
  display: flex
  border: 10px solid mistyrose
  height: 400px
  align-items: baseline
1
2
3
4
5
6
7
8
9
10

cross-axis為由左至右時(flex-direction: column)

align-items: stretch(預設)

填滿

.box
  color: white
  font-size: 20px
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  align-items: stretch

.box1
  font-size: 30px
 
.box3
  font-size: 40px
 
.box4
  font-size: 50px
1
2
3
4
5
6
7
8
9
10

align-items: center

集中於中間

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  align-items: center
1
2
3
4
5
6
7
8
9
10

align-items: flex-end

集中於右側(貼齊右側)

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  align-items: flex-end
1
2
3
4
5
6
7
8
9
10

align-items: flex-start

集中於左側(貼齊左側)

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  align-items: flex-start
1
2
3
4
5
6
7
8
9
10

flex#5 justify-content

定義

justify-content會沿著main-axis對齊

快速複習

  • 【預設】flex-direction: row,main-axis為由左至右→→→
  • flex-direction: column,main-axis為由上至下↓↓↓

main-axis為由左至右的情況下(Default)

justify-content: flex-start (default)

items會擠在左邊

.container
  display: flex
  border: 10px solid mistyrose
  justify-content: flex-start
1
2
3
4
5
6
7
8
9
10

justify-content: flex-end

items會擠在右邊

.container
  display: flex
  border: 10px solid mistyrose
  justify-content: flex-end
1
2
3
4
5
6
7
8
9
10

justify-content: center

items會擠中間

.container
  display: flex
  border: 10px solid mistyrose
  justify-content: center
1
2
3
4
5
6
7
8
9
10

justify-content: space-between

第1個item擠在左邊,最後1個item擠在右邊,中間的items均分

.container
  display: flex
  border: 10px solid mistyrose
  justify-content: space-between
1
2
3
4
5
6
7
8
9
10

justify-content: space-around

手法近似於每個item得到一樣的margin-left跟margin-right。
由於第2-9個item的兩邊會重疊鄰居的margin,所以空隙為2倍。
第1個與第10個item的margin沒有鄰居加持,所以與邊界的空隙只有1倍。

.container
  display: flex
  border: 10px solid mistyrose
  justify-content: space-around
1
2
3
4
5
6
7
8
9
10

main-axis為由上至下的情況下(flex-direction: column)

2個注意事項

  • 需要指定min-height
  • 每個item不能給太高(加總高須低於min-height)

justify-content: flex-start

items都擠在上方

.box
  color: white
  font-size: 20px
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  min-height: 700px
  justify-content: flex-start
1
2
3
4
5
6
7
8
9
10

justify-content: flex-end

items都擠在下方

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  min-height: 700px
  justify-content: flex-end
1
2
3
4
5
6
7
8
9
10

justify-content: center

items都擠在中間(狀似孤島)

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  min-height: 700px
  justify-content: center
1
2
3
4
5
6
7
8
9
10

justify-content: space-between

首尾貼緊上下的均分

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  min-height: 700px
  justify-content: space-between
1
2
3
4
5
6
7
8
9
10

justify-content: space-around

上下等距的均分

.container
  display: flex
  border: 10px solid mistyrose
  flex-direction: column
  min-height: 700px
  justify-content: space-around
1
2
3
4
5
6
7
8
9
10

【GCP】introduction to APIs

目的

利用GCP建立一個API

建立JSON檔案

開啟GCP平台,打開Cloud Shell

輸入以下指令,編輯value.json

nano values.json

進入編輯模式後,貼上以下內容
※<YOUR_BUCKET_NAME>請換成自訂的任意名字,命名須遵守這篇文章

{  "name": "<YOUR_BUCKET_NAME>",
   "location": "us",
   "storageClass": "multi_regional"
}

結束編輯模式:Ctrl+X
確定儲存:Y
結束:Enter

取得API認證

OAuth 2.0 playground
選擇「Cloud Storage JSON API V1」
並選擇之下的「https://www.googleapis.com/auth/devstorage.full_control」

選好後,按下藍色按鈕「Authorize APIs」

接者,完成Step2跟Step3,並複製Access token序號

建立Cloud Storage Bucket

回到GCP Cloud Shell,輸入以下指令

ls

會看到回傳2份檔案:README-cloudshell.txt values.json

繼續輸入以下指令
※<YOUR_TOKEN>請貼上剛剛複製的OAuth Access token序號

export OAUTH2_TOKEN=<YOUR_TOKEN>

輸入以下指令
※<YOUR_PROJECT_ID>請貼上專案ID

export PROJECT_ID=<YOUR_PROJECT_ID>

執行以下程式,建立bucket

curl -X POST --data-binary @values.json \
    -H "Authorization: Bearer $OAUTH2_TOKEN" \
    -H "Content-Type: application/json" \
    "https://www.googleapis.com/storage/v1/b?project=$PROJECT_ID"

檢視建立好的Cloud Storage Bucket

選單→Storage→Browser

並點選專案名,就可看到建立好的Cloud Storage Bucket

上傳媒體檔案至API

  1. 找一張圖片,儲存為demo-image.pn
  2. 點選Cloud Sheel右上角的「…」menu處,選擇「upload file」
  3. 執行以下程式,找尋媒體路徑,並且複製回傳的絕對路徑
    realpath demo-image.png
  4. 執行以下指令
    ※<DEMO_IMAGE_PATH>請代換成剛剛複製貼上的路徑

    export OBJECT=<DEMO_IMAGE_PATH>
  5. 執行以下指令
    ※<YOUR_BUCKET>代換成這隻Bucket的名稱(value.json裡面的name)

    export OBJECT=<YOUR_BUCKET>
  6. 執行以下指令,上傳媒體至Cloud Storage Bucket
    ※<YOUR_BUCKET>代換成這隻Bucket的名稱(value.json裡面的name)

    curl -X POST --data-binary @$OBJECT \
        -H "Authorization: Bearer $OAUTH2_TOKEN" \
        -H "Content-Type: image/png" \
        "https://www.googleapis.com/upload/storage/v1/b/$BUCKET_NAME/o?uploadType=media&name=demo-image"
  7. 接者,可以在預覽主畫面上,看到上傳成功的媒體

flex#4 flex-order

說明

  • 預設值:order: 0
  • order的數字只具相對意義,order5的會排在order10的前面。但是當頁面上只存在一個order時,給定order1的效力等同於order50
  • 指定order後,畫面上的順序雖然被改變了,但是滑鼠反藍選取的順序依舊會照html排列,所以會看到選取的地方被中斷

order為正數時:會排到右邊

.container
  display: flex

.box
  flex: 1 // 填滿一行

.box3
  order: 1

.box7
  order: 2
1
2
3
4
5
6
7
8
9
10

order為負數時:會排到左邊

.container
  display: flex

.box
  flex: 1 // 填滿一行

.box3
  order: -1

.box7
  order: -2
1
2
3
4
5
6
7
8
9
10

flex#3 flex-wrap

flex-wrap: nowrap (預設)

不拆行(所有flex item擠在一排裡面)
即便指定了寬度,flex container也會以擠在一起為原則,盡量達成指定的寬度

.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: nowrap
 
.box
  color: white
  font-size: 100px
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 300px
1
2
3
4
5
6
7
8
9
10

flex-wrap: wrap

拆行(flex item超過寬度的話會掉下來)
會遵守width

.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 300px
1
2
3
4
5
6
7
8
9
10

flex-wrap: wrap-reverse

反轉cross-axis
本來是由上到下↓↓↓
現變成由下到上↑↑↑

.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap-reverse
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  width: 300px
1
2
3
4
5
6
7
8
9
10

讓flex-item可以無縫填滿外層

  • 寬度算好
  • 使用box-sizing: border-box
.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  box-sizing: border-box
  width: 33.33%
1
2
3
4
5
6
7
8
9
10

flex-item之間留個空隙

  • 空隙用margin指定
  • 寬度用calc算好
.container
  display: flex
  border: 10px solid goldenrod
  flex-wrap: wrap
 
.box
  color: white
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px
  margin: 10px
  box-sizing: border-box
  width: calc(33.33% - 20px)
1
2
3
4
5
6
7
8
9
10

flex#2 flex-direction

flex-direction: row (預設)

main axis: 由左至右 →→→
cross axis: 由上至下 ↓↓↓

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: row
1
2
3
4
5
6
7
8
9
10

flex-direction: column

main axis: 由上至下 ↓↓↓
cross axis: 由左至右 →→→

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: column
1
2
3
4
5
6
7
8
9
10

flex-direction: row-reverse

main axis: 由右至左 ←←←

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: row-reverse
1
2
3
4
5
6
7
8
9
10

flex-direction: column-reverse

main axis: 由下至上 ↑↑↑

.container
  display: flex
  border: 10px solid goldenrod
 flex-direction: column-reverse
1
2
3
4
5
6
7
8
9
10

flex#1 CSS flexbox

無使用flex時

.container
 .box.box1 1
 .box.box2 2
 .box.box3 3
 .box.box4 4
 .box.box5 5
 .box.box6 6
 .box.box7 7
 .box.box8 8
 .box.box9 9
 .box.box10 10
.box
  color: white
  font-size: 100px
  text-align: center
  text-shadow: 4px 4px 0 rgba(0, 0, 0, 0.1)
  padding: 10px

.box1
  background: #1abc9c
.box2
  background: #3498db
.box3
  background: #9b59b6
.box4
  background: #34495e
.box5
  background: #f1c40f
.box6
  background: #e67e22
.box7
  background: #e74c3c
.box8
  background: #bdc3c7
.box9
  background: #2ecc71
.box10
  background: #16a085

Display

1
2
3
4
5
6
7
8
9
10

使用display: flex

外層元素會拉成一列
內層元素會變成flex-item

.container
  display: flex
  border: 10px solid goldenrod
1
2
3
4
5
6
7
8
9
10

使用display: inline-flex

外層元素會拉成一列,但不會全部填滿一列
內層元素會變成flex-item

.container
  display: inline-flex
  border: 10px solid goldenrod
1
2
3
4
5
6
7
8
9
10

JavaScript easing

說明

  1. 設定好自訂動畫函數,input固定間隔值的數字,動畫函數的output會是一個動畫曲線
  2. 用setInterval寫動畫執行函數。參數意義如下
    ele:element
    b:before(初期值)
    c:change(終點值)
    t:timing(目前的時間戳)
    d:duration(這個動畫總共要有幾秒)
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
.box
button(onclick="move()") click me
.box
 background: teal
 width: 200px
 height: 100px
 margin: 40px
//easing函數
function easeOut(t, d){
  return 1 - Math.pow(1-(t/d), 5);
}

function smoothScroll(ele, b){
  var c=-ele.scrollTop;
  var start = Date.now();
  var total = 1400; //毫秒
  var d = 1;

  timer = window.setInterval(function() {
    var t = (Date.now() - start) / total;
    var result = easeOut(t, d);
    var y = b + result * c;
    ele.scrollTop = y;
    if (t >= d) { 
      clearInterval(timer);
    }
  }, 16);
}

function move(){
 if(document.body.scrollTop!==0){
  //Safari
  smoothScroll(document.body, pageYOffset)
 }else{
  //Chrome, FF, IE
  smoothScroll(document.documentElement, pageYOffset)
 }
}

easing 函數介紹

easing out類(開始快,結束慢)

easing out by pow (指數)

function easeOutPow(t, d){
  return 1 - Math.pow(1-(t/d), 5);
}

easing  out by quad (2倍)

function easeOutQuad(t) { 
  return t*(2-t)
}

easing  out by cubic (3倍)

function easeOutCubic(t) { 
  return (--t)*t*t+1 
}

easing  out by quart (4倍)

function easeOutQuart(t) {
  return t*t*t*t
}

easing  out by quint (5倍)

function easeOutQuint(t) {
 return 1+(--t)*t*t*t*t
}

easing in類(開始慢,結束快)

easing in by pow (指數)

function easeInPow(t, d){
  return Math.pow((t/d), 5);
}

easing in by quad (2倍)

function easeInQuad(t) { 
  return t*t 
}

easing in by cubic (3倍)

function easeInCubic(t){ 
  return t*t*t 
}

easing in by quart (4倍)

function easeInQuart(t) { 
  return t*t*t*t 
}

easing in by quint (5倍)

function easeInQuint(t) { 
  return t*t*t*t*t 
}

ease in and out類(開始慢,中間快,結束慢)

easing in by pow (指數)

function easeInOutPow(t, d){
  return t<.5 ? Math.pow((t/d)*1.8, 6.5) : 1 - Math.pow((1-(t/d))*1.8, 6.5);
}

easing in by quad (2倍)

function easeInOutQuad(t) { 
  return t<.5 ? 2*t*t : -1+(4-2*t)*t 
}

easing in by cubic (3倍)

function easeInOutCubic(t) { 
  return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1
}

easing in by quart (4倍)

function easeInOutQuart(t) { 
  return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t 
}

easing in by quint (5倍)

function easeInOutQuint(t) { 
  return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t
}

參考資料

SMIL 動態控制

SVG <animate>的動態控制屬性

結束後保持變化後的狀態 fill=”freeze”

效果類似animation-fill-mode: forwards;

svg(viewbox="-50 -50 100 100")
 circle(cx=0,cy=0,r=10)
  animate(attributeName="r" dur="5s" values="10;40" fill="freeze")
svg
 width: 240px
 border: solid 2px

JS控制動畫開始

  1. 用參數控制SVG動畫一開始先停止
  2. 用JS method喚醒動畫
svg(viewbox="-50 -50 100 100")
 circle(cx=0,cy=0,r=10)
  animate#myAni(attributeName="r" dur="2s" values="10;30;10" begin="infinite" repeatCount="indefinite")
button(onclick="myAni.beginElement()") click me
svg
 width: 240px
 border: solid 2px

Safari bug:transform-origin不會生效

若使用CSS Animation Keyframes設定動畫的話,則transform-origin可以在safari正常使用的,
但在SMIL設定<animate>,則safari的transform-origin屬性不知為何沒有作用,會造成動畫扭曲