共计 4290 个字符,预计需要花费 11 分钟才能阅读完成。
在这个系列里分享一些简单,但是很有意思的交互效果~
思想思路:
- 监听滚动,添加对应加载的 class(比如
loaded
) - 巧用 animation 实现文字和遮罩层的动画效果
- 文字动画:
opacity 0 -> 1
; - 遮罩层动画: 首先
width 0 -> 100%
, 然后把width 100% -> 0
且left 0 -> 100%
,这样就实现了遮罩层的进场和退出效果;
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:
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:
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);
正文完
发表至: javascript
2019-06-03