本文将带大家来实现一个非常有趣的案例——打开书本效果。我们平常冲浪时是不是看过一些学校高级的录取通知书,翻开通知书就能看见里面的内容,呈现出逼真的3D效果!
先来看效果图:
首先是一本书,用class="book"
的容器装全部,里面分右半本书和左半本书——分别用class="back-cover"
、class="front-cover"
的div容器表示。右半本书分内壳和外壳——class="page front"
、class="page back"
,同理左半本书也分内壳和外壳,也分别用相同类名。右半本书中放卡片和阴影,分别用class="shadow"、class="card"
的div装。而左半本书内壳放一些文字,为了方便,给一些盒子加上公共类名。具体如下:
<div> <!-- 右半本 --> <div> <div></div> <div> <div></div> <div></div> </div> </div> <!-- 左半本 --> <div> <div> <p>Solutions to over 1000 popular algorithm problems. All problems are from leetcode.com. Solutions include: - Problem statement - Python code with comments - Description of solution s trategy - Time and space complexity Does not require internet connection. Forward solutions by email. Please let me have your comments, correctio…</p> </div> <div></div> </div> </div>
1)设置背景颜色,实现渐变效果。
body { height: 100%; font: 100%/1.25 Arial, Helvetica, sans-serif;//字体类型 color: #fff; perspective: 1000px; //必不可少! background: #444; background-image: linear-gradient(to bottom, #444, #999); }
tips: perspective——定义了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果,值越大看到的东西越小,不设置看不出translateZ轴移动的近大远小的感觉。perspective-origin——相当于人的眼睛看哪里,默认是父元素中间地方。这两个属性都是设置在父元素身上。
2)设置最外层容器book的样式:宽高设置具体值并使它们在屏幕中间显示——主要利用定位position:absolute
实现,top、left的值都为50%,再让它们的左外边距和上外边距为自身宽高的负一半可以实现垂直居中显示。
.book { width: 300px; height: 300px; position: absolute; top: 50%; left: 50%; margin-top: -150px; margin-left: -150px; }
3)设置左半本书和右半本书里面的页面的宽高——和书一样大小,并利用定位——脱离文档流,让这些页面在同一个位置,同时设置内壳背景色为红色,外壳为白色(方便放背景图),让左半本书绕着Y轴旋转。同时设置3D立体效果
.book .page { width: 300px; height: 300px; padding: 1em; position: absolute; left: 0; top: 0; text-indent: 2em; } .book .front { background-color: #d93e2b; } .book .back { background-color: #fff; } .book .front-cover { cursor: move; //鼠标放上去呈十字架形状 transform-origin: 0 50%; //transform:rotateY(-160deg) //可以利用这个看看旋转的效果 } .p3d { transform-style: preserve-3d; }
4)设置左半本书外层的封面以及右半书的外壳向Z轴平移(解决书的外层布局)
.book .front-cover .back { background-image: url("https://preview.qiantucdn.com/58pic/35/01/38/55A58PICaUy8sV83Dd78m_PIC2018.jpg%21w1024_new_3072"); background-repeat: no-repeat; background-size: cover; transform: translateZ(3px); } .book .back-cover .back { transform: translateZ(-3px); }
5)此时你会发现里面的文字反了,解决办法是让那页反着的页面旋转180度就能正常了。到此为止左半本就完成了!
.book .flip { transform: rotateY(180deg); }
6)设置右半本书的竖起来的卡片和倒影的位置、大小、颜色,起初两者重叠。
.book .shadow, .book .card { width: 196px; height: 132px; position: absolute; top: 60px; left: 60px; transform-origin: 0 100%; //设置旋转起点 } .book .card { background: url("https://preview.qiantucdn.com/58pic/35/01/38/55A58PICaUy8sV83Dd78m_PIC2018.jpg%21w1024_new_3072"); background-size: cover; } .book .shadow { background-color: rgba(0,0,0,0.5); }
1)引入js文件到html中
<script src="./index.js"></script>
2)获取到需要的元素。先拿到整本书,再拿到左半本书、卡片、阴影.
let book=document.querySelector('.book'), leftPage=document.querySelector('.front-cover'), card=document.querySelector('.card'), shadow=document.querySelector('.shadow')
3)鼠标点击到前半本书移动时开始触发监听事件,可以再window身上设置
window.onmousemove = function(event){}
4)用一个变量表示鼠标的状态是点击、移动还是松开,类似于一个开关变量。默认是松开状态。
let hold=false //鼠标是按住的状态 leftPage.onmousedown=function(){ hold=true } window.addEventListener('mouseup',function(){ //鼠标不一定在page身上松开可能在其他地方松开,所以在window身上设置监听事件 hold=false })
5)设置移动事件。监听此时鼠标按下去的那一刻点的X坐标以及移动中的X轴上的变化,从而设置一个合理的值,让它绕Y轴旋转。让书、前半本书、卡片、阴影都能旋转移动角度。
window.onmousemove = function(event){ if(hold){ console.log(event.pageX); var angle= clamp((window.innerWidth/2 - event.pageX + 300)/300* -90,-180,0) //300为书的宽度 //该angle公式中的值不固定,可以设置其他 // leftPage.style.transform='rotate('+angle+'deg)' leftPage.style.transform=`rotateY(${angle}deg)` card.style.transform=`rotateX(${angle/2}deg)` shadow.style.transform=`skewX(${angle/10}deg)` book.style.transform=`rotateX(${60+angle/8}deg)` } }
tips:
skewX()
:指定对象绕X轴斜切扭曲。6)设置给定3个值中取中间值的函数
let clamp=function(val,min,max) { return Math.max(min,Math.min(val,max)) }
到此为止,动态翻书效果案例结束啦!有没有觉得一种恍然大悟的感觉!说不定以后会用上哟!
到此这篇关于JS+CSS实现超漂亮的动态翻书效果的文章就介绍到这了,更多相关js动态翻书效果内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!