1.交错动画
有时候,我们需要给多个元素添加同一个动画,播放后,不难发现它们会一起运动,一起结束,这样就会显得很平淡无奇。
那么如何将动画变得稍微有趣一点呢?很简单,既然它们都是同一时刻开始运动的,那么让它们不在同一时刻运动不就可以了吗。如何让它们不在同一时刻运动呢?注意到CSS动画有延迟(delay)这一属性。
举个栗子,比如有十个元素播放十个动画,将第二个元素的动画播放时间设定为比第一个元素晚0.5秒(也就是将延迟设为0.5秒),其他元素以此类推,这样它们就会错开来,形成一种独特的视觉效果。
html
<div class="loading">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
css
.loading {
display: flex;
animation-delay: 1s;
$colors: #7ef9ff, #89cff0, #4682b4, #0f52ba, #000080;
.dot {
position: relative;
width: 2em;
height: 2em;
margin: .8em;
border-radius: 50%;
&::before {
position: absolute;
width: 100%;
height: 100%;
content: '';
animation: wave 2s ease-out infinite;
border-radius: inherit;
background: inherit;
}
@for $i from 1 through 5 {
&:nth-child(#{$i}) {
background: nth($colors, $i);
&::before {
animation-delay: $i * .2s;
}
}
}
}
}
@keyframes wave {
50%,
75% {
transform: scale(2.5);
}
80%,
100% {
opacity: 0;
}
}
2.用JS分割文本
一般我们都是从第一个元素开始交错的。但如果要从中间元素开始交错的话,就要给当前元素的延时各加上一个值,这个值就是中间元素的下标到当前元素的下标的距离(也就是下标之差的绝对值)与步长的乘积,即:delay + Math.abs(i - middle) * step,其中中间元素的下标middle = letters.filter(e => e !== “”).length / 2
html
<div id="reveal" class="reveal"></div>
css
//文本动画
.reveal {
font-family: Raleway, sans-serif;
font-size: 2em;
position: relative;
display: flex;
white-space: pre;
letter-spacing: 3px;
text-transform: uppercase;
color: #6ee1f5;
}
.reveal span {
transform: scale(0);
animation: fadeIn 2.4s forwards;
opacity: 0;
}
.reveal::before,
.reveal::after {
position: absolute;
top: 0;
bottom: 0;
width: 2px;
height: 100%;
content: '';
transform: scale(0);
opacity: 0;
background: white;
}
.reveal::before {
left: 50%;
animation: slideLeft 1.5s cubic-bezier(.7, -.6, .3, 1.5) forwards;
}
.reveal::after {
right: 50%;
animation: slideRight 1.5s cubic-bezier(.7, -.6, .3, 1.5) forwards;
}
@keyframes fadeIn {
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes slideLeft {
to {
left: -6%;
transform: scale(.9);
opacity: 1;
}
}
@keyframes slideRight {
to {
right: -6%;
transform: scale(.9);
opacity: 1;
}
}
js
let anmitionWords = {
revealTimer:null,
init : function(str){
let duration = 0.8;
let delay = 0.3;
let revealText = document.querySelector(".reveal");
let letters = str.split("");
revealText.textContent = "";
let middle = letters.filter(e => e !== " ").length / 2;
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${delay + Math.abs(i - middle) * 0.1}s`;
revealText.append(span);
});
},
clear:function(){
let dom = document.getElementById("reveal");
dom.innerHTML = '';
},
setInter:function(str){
if(this.revealTimer){
clearInterval(revealTimer);
}
this.revealTimer = setInterval(() => {
this.clear();
this.init(str);
}, 5000);
}
}
anmitionWords.init("动态文字跳跃展示");
anmitionWords.setInter("动态文字跳跃展示");
3.随机粒子
我们可以实现一种更疯狂的效果:给几百个粒子添加交错动画,并且交错时间随机,位置大小也都是随机。如此一来我们就能用纯CSS模拟出下雪的效果。
html
<div id="snow" class="snow-box"></div>
css
//下雪
.snow-box {
width: 100%;
height: 200px;
}
@function random_range($min, $max) {
$rand: random();
$random_range: $min + floor($rand * (($max - $min) + 1));
@return $random_range;
}
.snow {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
background: white;
$total: 200;
@for $i from 1 through $total {
$random-x: random(1000000) * .0001vw;
$random-offset: random_range(-100000, 100000) * .0001vw;
$random-x-end: $random-x + $random-offset;
$random-x-end-yoyo: $random-x + ($random-offset / 2);
$random-yoyo-time: random_range(30000, 80000) / 100000;
$random-yoyo-y: $random-yoyo-time * 50vh;
$random-scale: random(10000) * .0001;
$fall-duration: random_range(10, 30) * 1s;
$fall-delay: random(30) * -1s;
&:nth-child(#{$i}) {
transform: translate($random-x, -10px) scale($random-scale);
animation: fall-#{$i} $fall-duration $fall-delay linear infinite;
opacity: random(10000) * .0001;
}
@keyframes fall-#{$i} {
#{percentage($random-yoyo-time)} {
transform: translate($random-x-end, $random-yoyo-y) scale($random-scale);
}
to {
transform: translate($random-x-end-yoyo, 50vh) scale($random-scale);
}
}
}
}
js
//下雪
let snow = {
init:function(n){
if (!n || n<1) return;
let dom = document.getElementById("snow");
for(let i = 0;i<=n;i++){
let cud = document.createElement("div");
cud.className = "snow";
dom.append(cud);
}
}
}
snow.init(100);
4.发光文本
html
<div style="height:200px;text-align: center">
<h1 class="glowIn">Hi I'm cc</h1>
<p class="glowIn"></p>
</div>
css
//发光文字
@import url('https://fonts.googleapis.com/css?family=Lora:400,400i,700');
p {
margin: 0 5em 4em 5em;
}
.glowIn {
font-family: Lora, serif;
line-height: 1.8;
text-align: center;
color: white;
span {
animation: glowIn .8s ease both;
}
}
@keyframes glowIn {
from {
opacity: 0;
}
65% {
opacity: 1;
text-shadow: 0 0 25px white;
}
75% {
opacity: 1;
}
to {
opacity: .7;
}
}
js
let glowInTextsAnmi = {
init:function(text){
let glowInTexts = document.querySelectorAll(".glowIn");
glowInTexts.forEach(glowInText => {
let letters = text.split("");//glowInText.textContent.split("");
glowInText.textContent = "";
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i * 0.05}s`;
glowInText.append(span);
});
});
}
}
glowInTextsAnmi.init("努力学习css特效,为项目体验锦上添花,为你的人生丰富多彩!");
5. 3d 文字
html
<div style="text-align: center; height:200px">
<div class="three">大家好,我是cc</div>
</div>
css
//3d文字
@import url('https://fonts.googleapis.com/css?family=Baloo+Bhaijaan&display=swap');
@function float-text-3d($shadow-color: #bbb, $depth: 10, $floating: false) {
$shadows: ();
// When dropped, it will shrink like a spring. When floating, it grows into its shape.
@for $i from 1 to $depth {
$shadows: append($shadows, 0 ($i * 1px) $shadow-color, comma);
@if ($floating == false and $i > $depth / 2) {
$shadow-color: transparent;
}
}
// When dropped, the shadow reveals. When floating, the shadow fades.
@if ($floating == false) {
$shadows: append($shadows, 0 10px 10px rgba(0, 0, 0, .4), comma);
} @else {
$shadows: append($shadows, 0 50px 25px rgba(0, 0, 0, .2), comma);
}
@return $shadows;
}
.three {
font-family: 'Baloo Bhaijaan', cursive;
font-size: 5em;
display: flex;
text-transform: uppercase;
color: white;
span {
transform: translateY(20px);
animation: bounce .3s ease infinite alternate;
text-shadow: float-text-3d($floating: false);
}
}
@keyframes bounce {
to {
transform: translateY(-20px);
text-shadow: float-text-3d($floating: true);
}
}
js
let threeText = {
init:function(text){
let three = document.querySelector(".three");
let letters = text.split("");//three.textContent.split("");
three.textContent = "";
letters.forEach((letter, i) => {
let span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i / 10}s`;
three.append(span);
});
}
}
threeText.init("大家好,我是cc");
6 视屏背景混合文字
利用滤色模式(screen)实现文本视频蒙版效果
html
<div style="text-align: center; height:100px">
<video autoplay muted loop preload poster="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/oceanshot.jpg">
<source src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/ocean-small.webm" />
<source src="http://thenewcode.com/assets/videos/ocean-small.mp4" />
</video>
<h2>I'm CC</h2>
</div>
css
//视频混合背景文字
@font-face {
font-family: Biko;
src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/biko-black.woff');
}
video,
h2 {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100px;
margin: 0;
}
video {
object-fit: cover;
}
h2 {
font-family: Biko, sans-serif;
font-size: 12vw;
font-weight: 700;
line-height: 100px;
text-align: center;
text-transform: uppercase;
background: #d4cfcf;
mix-blend-mode: screen;
}
画面效果:
源码地址:
下载地址
(https://download.csdn.net/download/weixin_40073115/12115875)