JS+CSS實(shí)現(xiàn)超漂亮的動(dòng)態(tài)翻書效果(思路詳解)
前言
本文將帶大家來(lái)實(shí)現(xiàn)一個(gè)非常有趣的案例——打開書本效果。我們平常沖浪時(shí)是不是看過(guò)一些學(xué)校高級(jí)的錄取通知書,翻開通知書就能看見里面的內(nèi)容,呈現(xiàn)出逼真的3D效果!
先來(lái)看效果圖:
思路準(zhǔn)備
- 把這本書看成是2個(gè)容器組成——左半本書和右半本書,左半本書有外表面和內(nèi)表面,右半本書也有自己的內(nèi)表面和外表面,相當(dāng)于兩個(gè)小矩形。
- 當(dāng)鼠標(biāo)點(diǎn)擊書本向左移動(dòng)時(shí)實(shí)現(xiàn)翻開效果,也就是只有左半本書可以翻動(dòng)——繞著y軸旋轉(zhuǎn)。
- 同時(shí)右半本書的卡片會(huì)豎起來(lái),陰影也會(huì)隨之傾斜,整本書也會(huì)旋轉(zhuǎn)一定角度。
正文
一、CSS實(shí)現(xiàn)
1、搭建基本框架
首先是一本書,用class="book"
的容器裝全部,里面分右半本書和左半本書——分別用class="back-cover"
、class="front-cover"
的div容器表示。右半本書分內(nèi)殼和外殼——class="page front"
、class="page back"
,同理左半本書也分內(nèi)殼和外殼,也分別用相同類名。右半本書中放卡片和陰影,分別用class="shadow"、class="card"
的div裝。而左半本書內(nèi)殼放一些文字,為了方便,給一些盒子加上公共類名。具體如下:
<div class="book p3d"> <!-- 右半本 --> <div class="back-cover p3d"> <div class="page back flip"></div> <div class="page front p3d"> <div class="shadow"></div> <div class="card"></div> </div> </div> <!-- 左半本 --> <div class="front-cover p3d"> <div class="page front flip p3d"> <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 class="page back"></div> </div> </div>
2、編寫CSS
1)設(shè)置背景顏色,實(shí)現(xiàn)漸變效果。
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 平面的距離,使具有三維位置變換的元素產(chǎn)生透視效果,值越大看到的東西越小,不設(shè)置看不出translateZ軸移動(dòng)的近大遠(yuǎn)小的感覺。perspective-origin——相當(dāng)于人的眼睛看哪里,默認(rèn)是父元素中間地方。這兩個(gè)屬性都是設(shè)置在父元素身上。
2)設(shè)置最外層容器book的樣式:寬高設(shè)置具體值并使它們?cè)谄聊恢虚g顯示——主要利用定位position:absolute
實(shí)現(xiàn),top、left的值都為50%,再讓它們的左外邊距和上外邊距為自身寬高的負(fù)一半可以實(shí)現(xiàn)垂直居中顯示。
.book { width: 300px; height: 300px; position: absolute; top: 50%; left: 50%; margin-top: -150px; margin-left: -150px; }
3)設(shè)置左半本書和右半本書里面的頁(yè)面的寬高——和書一樣大小,并利用定位——脫離文檔流,讓這些頁(yè)面在同一個(gè)位置,同時(shí)設(shè)置內(nèi)殼背景色為紅色,外殼為白色(方便放背景圖),讓左半本書繞著Y軸旋轉(zhuǎn)。同時(shí)設(shè)置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; //鼠標(biāo)放上去呈十字架形狀 transform-origin: 0 50%; //transform:rotateY(-160deg) //可以利用這個(gè)看看旋轉(zhuǎn)的效果 } .p3d { transform-style: preserve-3d; }
4)設(shè)置左半本書外層的封面以及右半書的外殼向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)此時(shí)你會(huì)發(fā)現(xiàn)里面的文字反了,解決辦法是讓那頁(yè)反著的頁(yè)面旋轉(zhuǎn)180度就能正常了。到此為止左半本就完成了!
.book .flip { transform: rotateY(180deg); }
6)設(shè)置右半本書的豎起來(lái)的卡片和倒影的位置、大小、顏色,起初兩者重疊。
.book .shadow, .book .card { width: 196px; height: 132px; position: absolute; top: 60px; left: 60px; transform-origin: 0 100%; //設(shè)置旋轉(zhuǎn)起點(diǎn) } .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); }
二、JS實(shí)現(xiàn)
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)鼠標(biāo)點(diǎn)擊到前半本書移動(dòng)時(shí)開始觸發(fā)監(jiān)聽事件,可以再window身上設(shè)置
window.onmousemove = function(event){}
4)用一個(gè)變量表示鼠標(biāo)的狀態(tài)是點(diǎn)擊、移動(dòng)還是松開,類似于一個(gè)開關(guān)變量。默認(rèn)是松開狀態(tài)。
let hold=false //鼠標(biāo)是按住的狀態(tài) leftPage.onmousedown=function(){ hold=true } window.addEventListener('mouseup',function(){ //鼠標(biāo)不一定在page身上松開可能在其他地方松開,所以在window身上設(shè)置監(jiān)聽事件 hold=false })
5)設(shè)置移動(dòng)事件。監(jiān)聽此時(shí)鼠標(biāo)按下去的那一刻點(diǎn)的X坐標(biāo)以及移動(dòng)中的X軸上的變化,從而設(shè)置一個(gè)合理的值,讓它繞Y軸旋轉(zhuǎn)。讓書、前半本書、卡片、陰影都能旋轉(zhuǎn)移動(dòng)角度。
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公式中的值不固定,可以設(shè)置其他 // 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:
- clamp函數(shù)中——min:-180deg,max:0deg,中間值:(window.innerWidth/2 - event.pageX + 300)/300* -90??傊@樣設(shè)置是為了旋轉(zhuǎn)角度比較契合,你也可以設(shè)置其他值。該值是在-180~0之間
skewX()
:指定對(duì)象繞X軸斜切扭曲。- 這些旋轉(zhuǎn)的角度都可以設(shè)置其他值,不過(guò)得設(shè)置的比較符合。
6)設(shè)置給定3個(gè)值中取中間值的函數(shù)
let clamp=function(val,min,max) { return Math.max(min,Math.min(val,max)) }
到此為止,動(dòng)態(tài)翻書效果案例結(jié)束啦!有沒有覺得一種恍然大悟的感覺!說(shuō)不定以后會(huì)用上喲!
完整代碼可以點(diǎn)擊js/OPENBOOK · nry/first_demo這里下載喲!
總結(jié)
到此這篇關(guān)于JS+CSS實(shí)現(xiàn)超漂亮的動(dòng)態(tài)翻書效果的文章就介紹到這了,更多相關(guān)js動(dòng)態(tài)翻書效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
[Web]防止用戶復(fù)制頁(yè)面內(nèi)容和另存頁(yè)面的方法
原理就是利用js控制一些復(fù)制等事件,但破解也簡(jiǎn)單,這里就不說(shuō)了。2009-02-02原生js?XMLhttprequest請(qǐng)求onreadystatechange執(zhí)行兩次的解決
這篇文章主要介紹了原生js?XMLhttprequest請(qǐng)求onreadystatechange執(zhí)行兩次的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02Javascript模擬scroll滾動(dòng)效果腳本
項(xiàng)目需要寫了一段模擬Scroll滾動(dòng)代碼,分享的同時(shí),我有些疑問(wèn),希望大家能幫忙解決,代碼如下2008-09-09JavaScript利用canvas實(shí)現(xiàn)星空效果
Canvas對(duì)于我們前端來(lái)說(shuō)是一個(gè)非常強(qiáng)大的工具,它可以實(shí)現(xiàn)各種復(fù)雜的圖形和動(dòng)畫效果,我們?nèi)绻軌蚴炀氄莆账?我們就可以做很多炫酷的效果,本文就給大家介紹了用canvas畫出一片星空的方法,需要的朋友可以參考下2023-11-11javascripit實(shí)現(xiàn)密碼強(qiáng)度檢測(cè)代碼分享
這篇文章主要介紹了javascripit實(shí)現(xiàn)密碼強(qiáng)度檢測(cè),大家參考使用吧2013-12-12JS 實(shí)現(xiàn)導(dǎo)航菜單中的二級(jí)下拉菜單的幾種方式
這篇文章主要介紹了JS 實(shí)現(xiàn)導(dǎo)航菜單中的二級(jí)下拉菜單的幾種方式的相關(guān)資料,這里提供了三種方式,和實(shí)例代碼,需要的朋友可以參考下2016-10-10javascript字符串循環(huán)匹配實(shí)例分析
這篇文章主要介紹了javascript字符串循環(huán)匹配,實(shí)例分析三種常用的字符串循環(huán)匹配的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07