在這個系列裏分享一些簡單,可是頗有意思的交互效果~
附上demo地址和github地址javascript
滾動,添加對應加載的class(好比loaded
)css
opacity 0 -> 1
;width 0 -> 100%
,而後把width 100% -> 0
且left 0 -> 100%
,這樣就實現了遮罩層的進場和退出效果;html:html
<div class="main"> <ul class="inner"> <li> <p data-js="reveal">SANDWICHES & PANCAKE</p> <p data-js="reveal">GARDEN</p> <p data-js="reveal">MORNING & TOMORROW & FRIEND</p> <p data-js="reveal"> ORANGE & BIRD & SHEEP & CUP & BUS</p> <p data-js="reveal">APPLE & FRUIT & CAR</p> <p data-js="reveal">CAKE & PICTURE & CAT & STAMP</p> <p data-js="reveal"> PLANE & BOOK & RACKET & GLASS & BED</p> </li> <li> <p data-js="reveal">APPLE<br>BANANA & PINE APPLE & SHEEP</p> <p data-js="reveal">BANANA & PINE APPLE</p> </li> <li> <p data-js="reveal">PUMPKIN & TARO & CARROT</p> </li> <li> <p data-js="reveal">HORSERADISH & LETTUCE</p> <p data-js="reveal">PUMPKIN & TARO & CARROT</p> <p data-js="reveal">HORSERADISH & LETTUCE</p> <p data-js="reveal">POTATO & BURDOCK</p> </li> <li> <p data-js="reveal"> EGG & BAG & ROSE & CHAIR & BAT</p> <p data-js="reveal"> FISH & NOTEBOOK & PENCIL & DOG & DESK</p> <p data-js="reveal">WATCH & MITT & MILK & FLOWER</p> <p data-js="reveal">DOOR & BOAT & PIANO & </p> </li> <li> <p data-js="reveal">POTATO & BURDOCK</p> <p data-js="reveal">APPLE<br>BANANA & PINE APPLE</p> <p data-js="reveal">LETTER<br>CAP & TAPE & MAIL & BOX</p> </li> <li> <p data-js="reveal">APPLE<br>BANANA & PINE APPLE</p> <p data-js="reveal">TURNIP & OKRA & PEA</p> </li> <li> <p data-js="reveal">SHIITAKE & BEEFSTEAK PLANT</p> </li> </ul> </div>
css:java
body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; background-color: #000; } main { padding: 10vw 0; } ul { width: 100%; max-width: 70%; margin: 0 auto; } li { margin: 10vw 0; text-align: left; } p { display: block; color: #fff; font-family: 'Lato', sans-serif; font-size: 2vw; font-weight: 900; line-height: 1.2; } p+p { margin-top: 10px; } li:first-child { margin-top: 0; } li:last-child { margin-bottom: 0; } li:nth-child(even) { text-align: right; } a { color: #fff; } a:hover { text-decoration: none; } [data-reveal="content"] { display: inline-block; position: relative; } [data-reveal="cover"] { position: absolute; top: 0; left: 0; width: 0; height: 100%; z-index: 1; } [data-reveal="text"] { opacity: 0; } @keyframes reveal-cover { 0% { width: 0; left: 0; } 44% { width: 100%; left: 0; } 54% { width: 100%; left: 0; } 100% { width: 0; left: 100%; } } @keyframes reveal-text { 0% { opacity: 0; } 44% { opacity: 0; } 54% { opacity: 1; } } [data-js="reveal"].loaded [data-reveal="cover"] { animation: reveal-cover 1.5s ease-in-out; } [data-js="reveal"].loaded [data-reveal="text"] { opacity: 1; animation: reveal-text 1.5s ease-in-out; }
javascript:git
const COLOR_LIST = ['#7f00ff', '#ff00ff', '#0000ff', '#007fff', '#00ffff']; let $targetList; const init = () => { $targetList = document.querySelectorAll('[data-js="reveal"]'); setup(); window.addEventListener('scroll', onScroll, false); window.dispatchEvent(new Event('scroll')); } // 隨機獲取數組項 const getArrayRandomValue = (array) => array[Math.floor(Math.random() * array.length)]; const setup = () => { for (const $target of $targetList) { const content = $target.innerHTML; const color = 'revealColor' in $target.dataset ? $target.dataset.revealColor : getArrayRandomValue(COLOR_LIST); $target.innerHTML = `<span data-reveal="content"><div data-reveal="cover" style="background-color:${color}"></div><span data-reveal="text">${content}</span></span>`; } } const onScroll = () => { const windowH = window.innerHeight; const scrollTop = document.documentElement.scrollTop || document.body.scrollTop; const isMostScroll = document.body.clientHeight <= scrollTop + windowH; for (const $target of $targetList) { if ($target.classList.contains('loaded')) continue; const rect = $target.getBoundingClientRect(); const top = rect.top + scrollTop; if (isMostScroll || top <= scrollTop + (windowH * .8)) $target.classList.add('loaded'); } } document.addEventListener('DOMContentLoaded', init, false);