利用JavaScript实现简单3D开关书本模型

 更新时间:2023年11月03日 11:27:10   作者:sAnL1ng散陵  
这篇文章主要为大家详细介绍了如何利用JavaScript实现简单3D开关书本模型的效果,文中的实现代码讲解的非常详细,具有一定参考价值,感兴趣的同学可以动手尝试一下

序言

今天我们不聊干货,来看一些用JS也能实现的轻松有趣的小Demo,首先我们先看实验效果图。

看完这张图后 直接把代码附上!

HTML代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css" rel="external nofollow"  rel="external nofollow" >
</head>
<body>
    <div class="book p3d">

        <div class="front-cover p3d">
          <div class="inside page p3d flip">
            <p>瓦罗兰特(VALORANT)是一款第一人称FPS游戏。
                与传统FPS游戏不同,游戏中每个角色都拥有其不一样的技能,小队角色之间的技能互相搭配进攻能发挥更强的作用。
                背景设定:在近未来的地球世界里,全球范围遭遇了一个重要的事件,名为First Light(原初之光),这个事件改变了地球,带来了生命、科技和政府运行的大转变。
                部分地球人在这个事件中获得了超能力,这些拥有超能力的人们被称为“Radiants(辐射人)”,意味着他们是被原初之光辐射从而获得了超能力。</p>
          </div>
          <div class="outside page"></div>
        </div>
        <div class="back-cover p3d">
            <div class="outside page p3d">
                <div class="inside page p3d">
                    <div class="shadow"></div>
                    <div class="card"></div>
                </div>
            </div>
        </div>
    </div>
    <script src="index.js"></script>
</body>
</html>

CSS代码

*{
    margin: 0;
    padding: 0;
    border: 0;
    vertical-align: baseline;
    box-sizing: border-box;  /*将容器声明成IE模型*/
}

html{
    height: 100%;
}

body{
    height: 100%;
    font: 100% / 1.25 Helvetica,arial,sans-serif;
    perspective: 1000px;
    background-color: #444;
    background-image: linear-gradient(to bottom,#444,#999);
}

.p3d{
    transform-style: preserve-3d;
}

.book{
    width: 300px;
    height: 300px;
    position: absolute;
    left: 50%;
    top: 50%;
    /* transform: translateY(-50%); */
    margin-top: -150px;
    color: #fff;
    -webkit-transform: rotateX(60deg);
    -moz-transform: rotateX(60deg);
    -o-transform: rotateX(60deg);
    user-select: none;
}

.front-cover{
    cursor: move;
    transform-origin: 0 50%;
    transform: rotateY(0deg);

}

.page{
    width: 300px;
    height: 300px;
    padding: 1em;/*相对父容器大小*/
    position: absolute;/*脱离文档流*/
    left: 0;
    top: 0;
    text-indent: 2em;
}


.inside{
    background-color: #2a0303;
}

.outside{
    background-color: #fff;
}

.front-cover .outside{
    background-image: url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.nga.178.com%2Fattachments%2Fmon_202006%2F02%2FjoQ5-38t6XlZ5pT3cS2yo-1o0.png&refer=http%3A%2F%2Fimg.nga.178.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1700461884&t=fb89517f74280d519c31d1b97adb1af3);
    background-repeat: no-repeat;
    background-size: cover;
    transform: translateZ(3px);
  }

.flip{
    transform: rotateY(180deg);
}

.back-cover .outside{
    transform: translateZ(-3px);
}

.back-cover .inside{
    background-color: #1e0000;
}

.card,
.shadow{
    width: 196px;
    height: 132px;
    position: absolute;
    left: 60px;
    top: 60px;
    transform-origin: 0 100%;
}

.shadow{
    background-color: rgba(0,0,0,0.5);
}

.card{
    background-image: url(https://images.9k9k.com/m/gamelib/202011/90947_zkyz.jpg);
    background-size: cover;
    transform-origin: 0 100%;
}

JS代码

var front = document.getElementsByClassName('front-cover')[0]
var book = document.getElementsByClassName('book')[0]
var card = document.getElementsByClassName('card')[0]
var shadow = document.getElementsByClassName('shadow')[0]

var hlod = false
var clamp = function(val,min,max){
    return Math.max(min,Math.min(val,max))
}

//鼠标是否按下
front.onmousedown = function(){
    hlod = true
}

//在window上监听鼠标松开
window.onmouseup = function(){
    hlod = false
}

window.onmousemove = function(e){
    if(hlod){
        //修改左半边书的角度,卡片旋转,阴影倾斜
        var deg = clamp((window.innerWidth / 2 - e.x + 300) / 300 * -90, -180, 0)
        front.style.transform = `rotateY(${deg}deg)`
        //整本书立起来 60 + deg / 8
        book.style.transform = `rotateX(${60 + deg / 8}deg)`
        //卡片 deg / 2
        card.style.transform = `rotateX(${deg / 3}deg)`
        //阴影倾斜 deg / 8 (css样式倾斜)
        shadow.style.transform = `skew(${deg / 8}deg)`

    }
}

console.log(front);

var front = document.getElementsByClassName('front-cover')[0]
var book = document.getElementsByClassName('book')[0]
var card = document.getElementsByClassName('card')[0]
var shadow = document.getElementsByClassName('shadow')[0]

var hlod = false
var clamp = function(val,min,max){
    return Math.max(min,Math.min(val,max))
}

//鼠标是否按下
front.onmousedown = function(){
    hlod = true
}

//在window上监听鼠标松开
window.onmouseup = function(){
    hlod = false
}

window.onmousemove = function(e){
    if(hlod){
        //修改左半边书的角度,卡片旋转,阴影倾斜
        var deg = clamp((window.innerWidth / 2 - e.x + 300) / 300 * -90, -180, 0)
        front.style.transform = `rotateY(${deg}deg)`
        //整本书立起来 60 + deg / 8
        book.style.transform = `rotateX(${60 + deg / 8}deg)`
        //卡片 deg / 2
        card.style.transform = `rotateX(${deg / 3}deg)`
        //阴影倾斜 deg / 8 (css样式倾斜)
        shadow.style.transform = `skew(${deg / 8}deg)`

    }
}

console.log(front);

代码解释

html部分

引入文件

我们创建的CSS和js文件都需要引入到html文件中

在头部标记里用link方法引入css文件

<head>
<link rel="stylesheet" href="style.css" rel="external nofollow"  rel="external nofollow" >
</head>

在body里用< script >标签引入js文件

<body>
<script src="index.js"></script>
</body>

HTML框架构建(BEM命名法)

我们将整本书分成了多个部分,总体就是一个book,然后根据想要实现的效果或者其功能将其划分成不同子块

<div class="book p3d">
        <div class="front-cover p3d">
          <div class="inside page p3d flip">
            <p>
          </div>
          <div class="outside page"></div>
        </div>
        <div class="back-cover p3d">
            <div class="outside page p3d">
                <div class="inside page p3d">
                    <div class="shadow"></div>
                    <div class="card"></div>
                </div>
            </div>
        </div>
    </div>

结构划分完了剩下的交给CSS样式编写就可以了。

CSS样式编写

*{
    margin: 0;
    padding: 0;
    border: 0;
    vertical-align: baseline;
    box-sizing: border-box;  /*将容器声明成IE模型*/
}

浏览器默认会给body加一个内外边距,所以我们将其设置为0,之前文章我们了解知道了,CSS中有两种盒模型,我们现在将其设置为box-sizing:border-box IE盒模型,为了让页面效果更完美的展现出来。

-webkit-transform: rotateX(60deg);
    -moz-transform: rotateX(60deg);
    -o-transform: rotateX(60deg);

-webkit-transform、-moz-transform、-o-transform分别是针对不同浏览器的前缀,以兼容不同浏览器。在现代浏览器中,大多数已经支持transform属性并可以省略前缀。

这里我们是将元素绕X轴旋转60度,但需要注意编写的时候具体怎么设置角度,我们需要还要根据页面呈现效果和其他样式属性来确定。

.page{
    width: 300px;
    height: 300px;
    padding: 1em;
    position: absolute;
    left: 0;
    top: 0;
    text-indent: 2em;
}

padding: 1em; em是指相对父容器大小

position: absolute;会导致其脱离文档流

JS交互功能编写

在这段JS代码中,主要是用来实现当我们通过鼠标拖拽前封面(front)时,会触发相应的事件,从而控制页面元素的旋转角度,实现一个交互效果。

var front = document.getElementsByClassName('front-cover')[0]
var book = document.getElementsByClassName('book')[0]
var card = document.getElementsByClassName('card')[0]
var shadow = document.getElementsByClassName('shadow')[0]

具体来说,首先通过document.getElementsByClassName()方法获取了front、book、card、shadow四个元素。

front.onmousedown = function(){
    hlod = true
}

并定义了hlod变量表示鼠标是否按下。

front.onmousedown = function(){
    hlod = true
}

window.onmouseup = function(){
    hlod = false
}

接下来,代码通过给front元素绑定mousedown事件来监听鼠标按下的动作,当鼠标按下时,将hlod设为true。然后,通过给window绑定mousemove和mouseup事件来监听鼠标移动和松开的动作。当鼠标移动时,如果hlod为true,就计算出deg的值,其值由用户当前鼠标位置决定。clamp()函数用于限制deg变量的取值范围在-180到0之间。随后,代码通过修改相应元素的transform属性来实现立体旋转的效果:front元素绕Y轴旋转deg度,book元素绕X轴旋转60 + deg / 8度,card元素绕X轴旋转deg / 3度,shadow元素skew倾斜deg / 8度。其中,模板字面量语法被用来构建包含变量的字符串,方便设置transform的属性值。

最后,console.log()函数用于输出front元素的信息用于检查调整。

以上就是利用JavaScript实现简单3D开关书本模型的详细内容,更多关于JavaScript 3D开关书本的资料请关注脚本之家其它相关文章!

相关文章

  • JavaScript父子窗体间的调用方法

    JavaScript父子窗体间的调用方法

    这篇文章主要介绍了JavaScript父子窗体间的调用方法,涉及javascript调用窗体的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • JavaScript常用代码书写规范的超全面总结

    JavaScript常用代码书写规范的超全面总结

    这篇文章给大家全面总结了JavaScript常用代码的书写规范,分别利用推荐和不推荐的两种示例代码让大家更能直接的了解书写规范,其实关于javascript代码规范我们应该遵循古老的原则:“能做并不意味着应该做”,好了,下面我们就来一起看看吧。
    2016-09-09
  • JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法

    JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法

    这篇文章主要介绍了JS在Chrome浏览器中showModalDialog函数返回值为undefined的解决方法,涉及javascript针对谷歌浏览器事件判定相关操作技巧,需要的朋友可以参考下
    2016-08-08
  • 使用window.print()前端实现网页打印超详细教程(含代码示例)

    使用window.print()前端实现网页打印超详细教程(含代码示例)

    前端实现打印功能的方法有很多,大家在网上随便一搜就是一大堆,下面这篇文章主要给大家介绍了关于使用window.print()前端实现网页打印的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-06-06
  • JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作实例

    JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作实例

    在本篇文章里小编给大家分享的是关于利用JS代码屏蔽F12,右键,粘贴,复制,剪切,选中,操作,需要的朋友们学习下。
    2019-09-09
  • js使用removeChild方法动态删除div元素

    js使用removeChild方法动态删除div元素

    本节为大家介绍了js使用removeChild方法动态删除div元素,需要的朋友可以参考下
    2014-08-08
  • 深入了解JavaScript的逻辑运算符(与、或)

    深入了解JavaScript的逻辑运算符(与、或)

    本篇文章分享的是 JS 当中的逻辑运算符与、或,也就是 && 、 || ,没错,别看这简简单单的几个运算符,虽然这是最基础的知识,但其中隐藏的奥秘却十分耐人寻味,接下来本文就为大家一一揭开这简单的运算符背后的奇妙之处。
    2016-12-12
  • bootstrap flask登录页面编写实例

    bootstrap flask登录页面编写实例

    这篇文章主要为大家详细介绍了bootstrap flask登录页面编写实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-11-11
  • js鼠标跟随运动效果

    js鼠标跟随运动效果

    这篇文章主要为大家详细介绍了js鼠标跟随运动效果的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03
  • 深入学习JavaScript执行上下文

    深入学习JavaScript执行上下文

    这篇文章主要介绍了深入学习JavaScript执行上下文,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的朋友可以参考一下,希望对你的学习有所帮助
    2022-08-08

最新评论