公司某部分业务有截图功能,设计师觉得 点击按钮->截图完成 太单调
然后就使用css结合vue的<transition>做了一个组件式的截图小动画。
直接引用<screenshotAnimate :image="BASE64" /> 传入一个BASE64即可
效果预览(好像gif压缩的太狠了。。。有点模糊 但是不耽误预览效果)
预览.gif
<template>
<transition name="screenshot" @after-enter="enterCancelled">
<div v-if="screenshotState" :class="[classState ? 'minimize' : 'maximization' , 'screenshot']">
<div class="title">
<span class="close" @click.stop="closePreview">关闭</span>
<span class="iconfont icon-download" @click.stop="downLoadImg"></span>
</div>
<img width="100%" :src="image" alt="">
</div>
</transition>
</template>
<script>
export default {
name: "screenshot",
props: {
image: '',
},
data() {
return {
screenshotState: false,
classState: false,
}
},
methods: {
enterCancelled() {
this.classState = true;
},
closePreview() {
this.$emit('close');
this.screenshotState = false;
this.classState = false;
},
downLoadImg() {
let fileName = '归档';
let aLink = document.createElement('a');
let blob = this.base64ToBlob(this.image);
let events = document.createEvent("HTMLEvents");
events.initEvent("click", true, true);
aLink.download = fileName;
aLink.href = URL.createObjectURL(blob);
aLink.click();
URL.revokeObjectURL(aLink.href);
this.closePreview();
}
base64ToBlob (code) {
let imgData = code.split(';base64,');
let imgType = imgData[0].split(':')[1];
let raw = window.atob(imgData[1]);
let rawLength = raw.length;
let uInt8Array = new Uint8Array(rawLength);
for(let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: imgType});
};
},
watch: {
image(n,o) {
if (n != '') {
this.screenshotState = true;
}
}
}
}
</script>
<style lang="stylus" scoped rel="stylesheet/stylus">
@keyframes screenshotAnimate {
10% {
transform: scale3d(0.9, 0.9, 0.9) translate3d(0, -50px, 0);
}
100% {
transform: scale3d(0.1, 0.1, 0.1);
transform-origin: bottom right;
}
}
.screenshot-enter-active {
animation-name: screenshotAnimate;
animation-duration: 0.7s;
animation-fill-mode: both;
animation-timing-function: cubic-bezier(0.55, 0.055, 0.7, 0.2);
}
.screenshot {
position: fixed;
z-index: 999;
overflow: hidden;
background-color: #FFFFFF;
box-shadow:0 1px 3px 0 rgba(0,21,41,0.12);
border-radius:4px 4px 0 0;
}
.screenshot.maximization {
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: 8px;
img {
height: 100%;
}
.title {
display none;
}
}
.screenshot.minimize {
bottom: 0;
right: 0;
width: 306px;
height: 231px;
padding: 3px;
.title {
display block;
padding: 0 16px;
width: 100%;
height: 32px;
line-height: 32px;
span:hover {
opacity 0.8;
}
.close {
cursor pointer;
font-weight: 500;
color: rgba(0,0,0,0.85);
font-size: 12px;
}
.iconfont {
cursor pointer;
float: right;
color: rgba(0,0,0,0.85);
}
}
img {
height: calc(100% - 32px);
}
}
</style>