新增需求,客户需要类似PPT的剥离效果用于WEB页面翻页,查找资料后,参考下方的掘金博主的文章,并将HTML修改成vue的页面进行使用。其中宽度、高度改成了变量,样式style中的属性与宽高的关系整理成了公式进行动态计算。
宽高比例建议不超过2倍,否则样式就会有问题。如果有极限值出现的情况,建议把rotateBox的border显示,进行调整时各个div之间的关系看得更清晰。
【完整代码】
<template>
<div class="container">
<article>
<div class="book">
<div class="rotateBox" :style="rotateBoxStyles">
<div class="pageItem front" :style="[pageItemStyles,frontStyle]">
<figure>
<img src="https://cdn.pixabay.com/photo/2023/11/22/18/13/beach-8406104_640.jpg" alt="">
<figcaption>Page 1</figcaption>
</figure>
</div>
<div class="pageItem back" :style="[pageItemStyles, backStyle]">
<figure>
<img src="https://cdn.pixabay.com/photo/2023/07/07/15/51/sea-8112910_640.jpg" alt="">
<figcaption>Page 2</figcaption>
</figure>
</div>
</div>
<div class="pageItem" :style="pageItemStyles">
<figure>
<img src="https://cdn.pixabay.com/photo/2021/11/26/17/26/dubai-desert-safari-6826298_640.jpg" alt="">
<figcaption>Page 3</figcaption>
</figure>
</div>
</div>
</article>
</div>
</template>
<script>
export default {
data() {
return {
pageWidth: 400,
pageHeight: 200,
}
},
computed: {
pageItemStyles() {
return {
width: this.pageWidth + 'px',
height: this.pageHeight + 'px',
}
},
rotateBoxStyles() {
return {
width: this.pageWidth * 2 + this.pageHeight * 0.5 + 'px',
height: this.pageWidth * 2 + this.pageHeight * 0.5 + 'px',
bottom: -this.pageWidth * 2 + 'px',
transformOrigin: '0 ' + (this.pageWidth * 2 + this.pageHeight * 0.5) + 'px',
transform: 'rotate(-'+ Math.atan((2*this.pageWidth - this.pageHeight)/this.pageWidth)* (180 / Math.PI) +'deg)',
}
},
frontStyle() {
return {
bottom: (2*this.pageWidth - this.pageHeight) + 'px',
// bottom: 0.5*(this.pageWidth * 2 + this.pageHeight * 0.5) + 'px',
// bottom: this.pageHeight * 0.5+ 'px',
transformOrigin: '0 ' + (this.pageWidth * 2) + 'px',
transform: 'rotate('+ Math.atan((2*this.pageWidth - this.pageHeight)/this.pageWidth)* (180 / Math.PI) +'deg)',
}
},
backStyle() {
return {
bottom: (2*this.pageWidth - this.pageHeight) + 'px',
// bottom: 0.5*(this.pageWidth * 2 + this.pageHeight * 0.5) + 'px',
// bottom: this.pageHeight * 0.5+ 'px',
left: - this.pageWidth + 'px',
transformOrigin: this.pageWidth + 'px' +' ' + (this.pageWidth * 2) + 'px',
transform: 'rotate('+ (180 - Math.atan((2*this.pageWidth - this.pageHeight)/this.pageWidth)* (180 / Math.PI)) +'deg)',
}
},
},
}
</script>
<style scoped lang="less">
.container {
position: relative;
margin-top: 100px;
}
.book {
background-color: cornflowerblue;
position: relative;
}
article {
position: relative;
width: 500px;
height: 400px;
// padding: 40px 80px 40px 380px;
margin: auto;
// box-shadow: 2px 3px 5px 6px #3f1300;
// background-image: url(https://cdn.pixabay.com/photo/2016/12/18/09/05/trees-1915245_1280.jpg);
}
.pageItem {
position: absolute;
overflow: hidden;
// width: 500px; // w
// height: 400px; // h
font-size: 32px;
text-align: center;
box-shadow: 0 0 11px rgba(0, 0, 0, .5);
}
.rotateBox {
overflow: hidden;
position: absolute;
z-index: 10;
// width: 1200px; // 2w+0.5h
// height: 1200px; // 2w+0.5h
// bottom: -1000px; // -2w
// transform-origin: 0px 1200px; // 0 2w+0.5h
border: 1px dashed #b0b0b0;
//transform: rotate(-50.19deg); // -arctan((2w-h)/w)
transition: 1s;
// background: pink;
}
.front {
// bottom: 600px; // 2w-h
// transform-origin: 0 1000px; // 0 2w
// transform: rotate(50.19deg); // arctan((2w-h)/w)
transition: 1s;
}
.back {
// bottom: 600px; // 2w-h
// left: -500px; // -w
// transform-origin: 500px 1000px; // w 2w
// transform: rotate(129.81deg); // 180 - arctan((2w-h)/w)
transition: 1s;
}
figure img {
width: 100%;
height: 100%;
aspect-ratio: 3/4;
object-fit: cover;
}
figure figcaption {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-wrap: nowrap;
color: #fff;
background-color: rgba(255, 255, 255, .5);
padding: 1em;
border: 4px double #fff;
}
article:hover .rotateBox {
transform: rotate(-90deg) !important;
}
article:hover .front {
transform: rotate(90deg) !important;
}
article:hover .back {
transform: rotate(90deg) !important;
}
</style>
【参考文章】
CSS实现翻页效果