效果
需求
鼠标按下能翻开,右边小卡片能弹出,且带有阴影
实现
搭建结构
- 搭建过程与上一篇时钟类似,这里不过多赘述。
xml
<div class="book p3d">
<!-- 右半本 -->
<div class="book-cover p3d">
<div class="page back flip"></div>
<div class="page front p3d">
<div class="shadow"></div>
<div class="pic"></div>
</div>
</div>
<!-- 左半本 -->
<div class="front-cover p3d">
<div class="page front flip p3d">
<p>
亲爱的丁社长和铁锤:
恭喜你们迎来人生新的旅程,结婚是爱情的圆满,是幸福的开始。愿你们携手共度人生的每一刻,相互扶持,相互理解,相互包容。
在这个特别的日子里,愿你们的爱情如同新婚的阳光一样灿烂,如同甜蜜的蜜蜂一样温暖。愿你们的爱情,如同永恒的星辰,照耀着彼此的人生。
愿你们的婚姻充满欢笑与快乐,百年好合,幸福美满!
祝福语:
丁社长和铁锤,祝你们于2024年5月1日结婚纪念日快乐!
祝福你们永结同心,白头偕老!
</p>
</div>
<!-- 外壳 -->
<div class="page back"></div>
</div>
</div>
css
background: linear-gradient(to bottom, #444, #999);
背景色调成渐变- 除了上一篇讲的translate平移的方式,我们还可以通过
margin-left: -150px;
调整外边距的方式往回走半个身位,确保位置居中 cursor: pointer;
小手点击图标user-select: none;
禁止用户选中transform: rotateX(60deg);
饶X轴旋转text-indent: 2em;
缩进两个字符transform-origin: 0 50%;
调整坐标起始位置transform-style: preserve-3d;
设置元素的子元素是位于 3D 空间中还是平面中。
css
* {
margin: 0;
padding: 0;
border: 0;
box-sizing: border-box;
}
html {
height: 100%;
}
body {
height: 100%;
font: 100%/1.25 Helvetica, arial, helvetica;
color: #fff;
perspective: 1000px;
background: linear-gradient(to bottom, #444, #999);
}
.book {
width: 300px;
height: 300px;
position: absolute;
left: 50%;
margin-left: -150px;
top: 50%;
margin-top: -150px;
cursor: pointer;
user-select: none;
transform: rotateX(60deg);
}
.page {
width: 300px;
height: 300px;
padding: 1em;
position: absolute;
left: 0;
top: 0;
text-indent: 2em;
}
.front {
background-color: #d93e2b;
}
.back {
background-color: #fff;
}
.front-cover {
transform-origin: 0 50%;
transform: rotateY(0deg);
}
.p3d {
transform-style: preserve-3d;
}
.front-cover .back {
background-image: url(https://img2.baidu.com/it/u=2368431681,4265369131&fm=253&fmt=auto&app=138&f=JPEG?w=595&h=500);
background-size: cover;
transform: translateZ(3px);
}
.flip {
transform: rotateY(180deg);
}
.shadow,
.pic {
width: 196px;
height: 132px;
position: absolute;
left: 60px;
top: 60px;
transform-origin: 0 100%;
}
.pic {
background: url(https://q4.itc.cn/q_70/images03/20240405/39ec09deda3a41d79e03897b0fdf68a0.jpeg);
background-size: cover;
}
.shadow {
background-color: rgba(0, 0, 0, 0.5);
}
JS
document.querySelector
类名方式获取元素var hold = false
提前设置好标记,后续鼠标点住外壳移动时需要改变状态var clamp = function (val, min, max) { return Math.max(min, Math.min(val, max)) }
自己设计一个大概的鼠标拉动时请柬翻转角度- 计算好角度后frontCover.style.transform = rotateY(${angle}deg)`js更改css样式
- 以此类推另外的阴影和pic元素
xml
<script>
var hold = false
var frontCover = document.querySelector('.front-cover')
var shadow = document.querySelector('.shadow')
var pic = document.querySelector('.pic')
var clamp = function (val, min, max) {
return Math.max(min, Math.min(val, max))
}
//鼠标摁住事件
//摁住为ture
frontCover.onmousedown = function () {
hold = true
}
//摁住为false
window.onmouseup = function () {
hold = false
}
//鼠标移动事件
window.onmousemove = function (e) {
//摁住才能执行
if (hold == true) {
var angle = clamp((window.innerWidth / 2 - e.pageX + 300) / 300 * -90, -180, 0)
frontCover.style.transform = `rotateY(${angle}deg)`
//pic 要立起来 绕x轴旋转(angle/2)
pic.style.transform = `rotateX(${angle / 2}deg)`
//shadow 要沿x轴倾斜(angle/8)
shadow.style.transform = `skewX(${angle / 8}deg)`
}
}
</script>