效果:
代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport"
content="width=device-width, viewport-fit=cover,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>翻书效果</title>
</head>
<body>
<span class="pager" onclick="handlePrev()" id="prev">上一页</span><span class="pager" id="next" onclick="handleNext()">下一页</span>
<div class="book" id="book">
<div class="cover page">
<div class="piece front">封面</div>
<div class="piece back">封面反面</div>
</div>
<div class="page inner">
<div class="piece front">第一页正面</div>
<div class="piece back">第一页反面</div>
</div>
<div class="page inner">
<div class="piece front">第二页正面</div>
<div class="piece back">第二页反面</div>
</div>
<div class="page inner">
<div class="piece front">第三页正面</div>
<div class="piece back">第三页反面</div>
</div>
<div class="page inner">
<div class="piece front">第四页正面</div>
<div class="piece back">第四页反面</div>
</div>
</div>
</body>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
html,body {
width: 100%;
height: 100%;
}
body {
background: #000;
}
.pager {
margin-left: 10px;
cursor: pointer;
user-select: none;
display: inline-block;
margin-top: 20px;
color: #fff;
}
.pager~.pager {
margin-left: 40px;
}
.book {
perspective: 800px;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
margin: auto;
width: 306px;
height: 470px;
user-select: none;
transition: transform .3s linear;
}
.showPager {
transform: translateX(10%);
}
.cover {
position: absolute;
left: 0;
top:0;
width: 306px;
height: 470px;
z-index: 3;
}
.page {
width:100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
transition: transform .4s linear;
transform-style: preserve-3d;
}
.page .front {
overflow: hidden;
border-top-right-radius: 18px;
border-bottom-right-radius: 18px;
border-bottom-left-radius: 8px;
}
.page .back {
overflow: hidden;
border-top-left-radius: 18px;
border-bottom-left-radius: 18px;
border-bottom-right-radius: 8px;
}
.page .piece {
position:absolute;
left: 0;
top:0;
width: 100%;
height: 100%;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
.page .front {
z-index: 2;
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
.page img {
width: 100%;
height: 100%;
}
.page .front {
}
.page .back {
z-index: 1;
transform: scaleX(-1);
background:url(book-back.png) no-repeat left center;
background-size: cover;
/* background: #fff; */
}
.page .front {
background:url(./front.png) no-repeat center top;
background-size: cover;
}
.cover .front {
background:url(./cover.png) no-repeat center top;
background-size: cover;
}
.page.inner .front {
background:url(./front.png) no-repeat center right;
background-size: auto 100%;
}
.flip-left {
transform-origin: left center;
transform: rotateY(-180deg);
z-index: 1;
}
.flip-right {
z-index: 2;
transform-origin: left center;
transform: rotateY(0deg);
}
</style>
<script>
var animating = false;
var index = -1;
var maxIndex = document.querySelectorAll(".page").length-1;
for(let i= 0; i <= maxIndex; i++){
document.querySelectorAll(".page")[i].style.zIndex = maxIndex-i;
document.querySelectorAll(".page")[i].setAttribute("origin-index", maxIndex - i);
}
function handlePrev(){
var tmpIndex = index-1;
if(tmpIndex<-1){
tmpIndex = -1
}
handleFlipPage('right', tmpIndex)
}
function handleNext(){
var tmpIndex = index+1;
if(tmpIndex>maxIndex-1){
tmpIndex = maxIndex-1;
}
handleFlipPage('left', tmpIndex)
}
function handleFlipPage(dir, tmpIndex){
console.log(dir, tmpIndex);
if(animating){
return false;
}
animating = true
index = tmpIndex
if(dir == 'left'){
document.querySelectorAll(".page")[index].classList.remove("flip-right")
document.querySelectorAll(".page")[index].classList.add("flip-left")
setTimeout(() => {
document.querySelectorAll(".page")[index].style.zIndex = index;
}, 200)
if (index == 0){
document.querySelector("#book").classList.add("showPager")
}
}else{
document.querySelectorAll(".page")[index+1].classList.add("flip-right")
document.querySelectorAll(".page")[index+1].classList.remove("flip-left")
setTimeout(() => {
document.querySelectorAll(".page")[index+1].style.zIndex = document.querySelectorAll(".page")[index + 1].getAttribute("origin-index")
}, 200)
if (index == -1) {
document.querySelector("#book").classList.remove("showPager")
}
}
setTimeout(() => {
animating = false;
}, 410)
}
</script>
</html>
素材: