Skip to main content

[JS30] Day05: Flex Panels Image Gallery

這一次的挑戰主要是學習flex-box屬性和transition動畫,以及 JS 加入動畫結束時的屬性

CSS

在母層.panels 加入display: flex,子層就可以設定flex,來達到寬度一致的部分(每個.panel 的 flex-grow 目前都為 1),而.panel 也可以再設定display: flex,加上flex-direction: column變成縱向排列。

.panels {
display: flex;
}

.panel {
flex: 1;
display: flex;
flex-direction: column;
}

在每個.panel 裡面有三個 p tag,目前為縱向排列,我們透過align-items: centerjustify-content: center讓 paragraph 水平和垂直置中。

/* Selects all <p> elements where the parent is a .panel element */
.panel > * {
transition: transform 0.5s;
/* Three values: flex-grow | flex-shrink | flex-basis */
flex: 1 0 auto;
display: flex;
align-items: center;
justify-content: center;
}

flex: https://developer.mozilla.org/en-US/docs/Web/CSS/flex

JavaScript

在點擊.panel 時,會增加.open 的 class,在.open 的動畫結束時,才會呼叫toggleActive,加上.open-active 的 class。

const panels = document.querySelectorAll(".panel");
function toggleClick() {
this.classList.toggle("open");
}
function toggleActive(e) {
if (e.propertyName.includes("flex")) {
this.classList.toggle("open-active"); // toggle after .open animation
}
}
panels.forEach((panel) => {
panel.addEventListener("click", toggleClick);
panel.addEventListener("transitionend", toggleActive);
});

.open 使得頁面放大

.panel.open {
flex: 5;
font-size: 40px;
}

.open-active 使得上下文字滑入

.panel p:first-child {
transform: translateY(-100%);
}

.panel.open-active p:first-child {
transform: translateY(0);
}

.panel p:last-child {
transform: translateY(100%);
}

.panel.open-active p:last-child {
transform: translateY(0);
}

延伸思考

transitionend的事件適合用在連續的動畫,而且不用事先規劃好動畫的時間。