炫酷的图片破碎效果
animation的使用
animation-direction的四个值
1.normal:默认值,不进行反方向播放;
2.reverse:全部播放都是用反方向播放;
3.alternate:在奇数次数(1、3、5)的时候正向播放,偶数次数(2、4、6)进行反向播放;
4.alternate-reverse:在偶数次数(1、3、5)的时候正向播放,奇数次数(2、4、6)进行反向播放;
animation-timing-function属性(时间曲线)
`animation-timing-function`属性是为动画制定从开始到结束时的播放速度曲线,比如由快到慢,或者由慢到快等;
animation-timing-function的几个值
1.linear:表示动画一直以匀速进行播放;贝赛尔函数cubic-bezier(0,0,0.25,1)
2.ease:默认值,表示动画先慢后快,在即将结束时再变慢;cubic-bezier(0.25,0.1,0.25,1)
3.ease-in:动画由慢到快直至结束;cubic-bezier(0.42,0,1,1)
4.ease-out:动画由快到慢直至结束;cubic-bezier(0,0,0.58,1)
5.ease-in-out:动画由慢到快再到慢直至结束,与ease不同的是它均等得分为三份,而ease是只在结束时变慢;cubic-bezier(0.42,0,0.58,1)
6.标注时间:也可以直接标注一个时间(以s做单位)来规定动画全称以该速度进行播放;
7.贝赛尔函数:也可以使用贝赛尔函数来对动画的播放时间曲线进行规定;
home页面来设置图片要破碎的个数 代码附上:
<template>
<div class="home">
<div style="margin: 10px">图片破碎效果动画</div>
平方
<input v-model="square" type="text" />
<n-component :square="square" />
</div>
</template>
<script>
import NComponent from "./component.vue";
export default {
name: "Home",
components: {
NComponent,
},
data() {
return {
square: "10",
};
},
};
</script>
component组件文件来实现图片破碎的具体动画效果
原理:
1.先将图片分成一个个小图片
2.点击‘破碎效果’按钮,给每个小图片添加动画效果
3.animationStyle 动画方法,通过四个象限来区别图片运动轨迹
代码附上:
<template>
<div class="page">
<button class="btn" @click="onClick">破碎效果</button>
<div class="container" :style="fragmentStyle">
<div class="fragment">
<div v-for="(item, i) in Number(square)" :key="i">
<div
v-for="(item1, j) in Number(square)"
:key="j"
:class="[{ child: animationStatus }]"
:style="[
childStyle(),
{
'background-position': `-${i * squareWidth}px -${j * squareHeight}px`,
},
{ transform: animationStatus ? animationStyle(i, j) : 'none' },
{ opacity: animationStatus ? '0' : '1' },
]"
/>
</div>
</div>
</div>
</div>
</template>
<script>
import testImg from "./test.jpg";
export default {
data() {
return {
testImg,
imgWidth: null,
imgHeight: null,
squareWidth: null,
squareHeight: null,
animationStatus: false,
};
},
props: {
square: String,
},
computed: {
squareHalf() {
return Number(this.square) / 2;
},
fragmentStyle() {
return {
width: this.imgWidth + "px",
minWidth: this.imgWidth + "px",
height: this.imgHeight + "px",
};
},
},
methods: {
getImgInfo() {
let img = new Image();
img.src = this.testImg;
img.onload = () => {
this.imgWidth = img.width;
this.imgHeight = img.height;
this.squareWidth = Math.floor(img.width / Number(this.square));
this.squareHeight = Math.floor(img.height / Number(this.square));
};
},
onClick() {
this.animationStatus = true;
},
childStyle() {
return {
backgroundImage: `url(${testImg})`,
backgroundRepeat: "no-repeat",
width: this.squareWidth + "px",
height: this.squareHeight + "px",
border: "1px solid greenyellow",
};
},
animationStyle(i, j) {
let size = 700;
let quadrantOneAndThree =
(i < this.squareHalf && j < this.squareHalf) || (i >= this.squareHalf && j < this.squareHalf);
let quadrantOneAndTwo =
(i < this.squareHalf && j < this.squareHalf) || (i < this.squareHalf && j >= this.squareHalf);
let directionX = quadrantOneAndThree ? "+" : "-";
let directionY = quadrantOneAndTwo ? "-" : "+";
return `perspective(100px) translate3d(${
directionX + Math.floor(Math.random() * ((i + 1) * size + (j * 2 + 1) * 3))
}px, ${
directionY + Math.floor(Math.random() * ((i + 1) * size + (j * 4 + 1) * 2))
}px, 50px) rotateY(${Math.floor(Math.random() * (i * j + 20))}deg) rotateX(${Math.floor(
Math.random() > 0.6 ? -i * Math.random() * size : j * Math.random() * size,
)}deg)`;
},
},
watch: {
square(val) {
this.getImgInfo();
},
},
created() {
this.getImgInfo();
},
};
</script>
<style scoped lang="scss">
div,
html,
body {
margin: 0px;
padding: 0px;
}
.btn {
margin: 10px;
background: skyblue;
color: #fff;
padding: 8px 20px;
border: 1px solid skyblue;
border-radius: 4px;
}
.container {
position: fixed;
top: 50%;
left: 50%;
width: 50%;
min-width: 320px;
height: auto;
z-index: 2000;
-webkit-transform: translateX(-50%) translateY(-50%);
-moz-transform: translateX(-50%) translateY(-50%);
-ms-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
.fragment {
display: flex;
flex-wrap: wrap;
}
.child {
transition-property: transform, opacity;
transition-duration: 1s;
transition-delay: 0s;
transition-timing-function: ease-out;
}
}
</style>
附上效果图