马黑黑 发表于 2022-4-26 23:54

何故不翻书

基本功能有所改进:

① 可以加页了;
② 可以真正翻页了;
③ 翻页后倒转镜像的现象处理了;
④ 书页子元素的z-index问题弄好了……

诸多的算法,尽在JS里,代码的复杂度比想象的不那么吓人:

何故不翻书 (animpen.com)

马黑黑 发表于 2022-4-26 23:55

本帖最后由 马黑黑 于 2022-4-27 07:30 编辑

代码:<style>
.book {
        margin: auto;
        display: flex;
        align-items: center;
        width: 1024px;
        height: 600px;
        perspective: 1000px;
        cursor: pointer;
        padding: 10px;
        position: relative;
        background: rgba(0,0,0,.8);
}
.page {
        background: #ccc;
        padding: 20px;
        width: 310px;
        height: 400px;
        left: 50%;
        border-left: 1px solid #dcdcdc ;
        transform-origin: left;
        box-shadow: inset 0px 0px 2px rgba(0,0,0,.5), 1px 1px 12px rgba(255,255,255,.8);
        transform-style: preserve-3d;
        position: absolute;
}
.page span { display: block; }
@keyframes rot1{
        from { transform: rotateY(0deg); }
        to { transform: rotateY(-180deg); }
}
@keyframes rot2{
        from { transform: rotateY(-180deg); }
        to { transform: rotateY(0deg); }
}
</style>

<div class="book">
        <div class="page"><span>1</span></div>
        <div class="page"><span>2</span></div>
        <div class="page"><span>3</span></div>
        <div class="page"><span>4</span></div>
</div>

<script>

let page = document.querySelectorAll(".page");
let idx = 0;
let all = page.length;
let currentPage = 0;

setzIdx();

document.querySelector(".book").onclick = function(){
        if(idx == 0){ //前翻
                page.style.animation = "rot1 .5s linear forwards";
                page.children.style.transform = "rotateY(-180deg)";
                currentPage ++;
                if(currentPage == all){
                        idx = 1;
                        currentPage = all - 1;
                }
                setzIdx();
        } else { //后翻
                page.style.animation = "rot2 .5s linear forwards";
                page.children.style.transform = "rotateY(0deg)";
                currentPage --;
                if(currentPage < 0){
                        idx = 0;
                        currentPage = 0;
                }
                setzIdx();
        }
}

function setzIdx(){
        for(j=currentPage; j<all; j++){
                page.style.zIndex = all - j;
        }
        for(j=0; j<currentPage;j++) {
                page.style.zIndex = j + 1;
        }
        if(currentPage == all - 1) page.style.zIndex = all;
}

</script>

马黑黑 发表于 2022-4-26 23:55

本帖最后由 马黑黑 于 2022-4-27 07:32 编辑 <br /><br /><style>
.book {
        left: -214px;
        display: flex;
        align-items: center;
        width: 1024px;
        height: 600px;
        perspective: 1000px;
        cursor: pointer;
        padding: 10px;
        position: relative;
        background: rgba(0,0,0,.8);
}
.page {
        background: #ccc;
        padding: 20px;
        width: 310px;
        height: 400px;
        left: 50%;
        border-left: 1px solid #dcdcdc ;
        transform-origin: left;
        box-shadow: inset 0px 0px 2px rgba(0,0,0,.5), 1px 1px 12px rgba(255,255,255,.8);
        transform-style: preserve-3d;
        position: absolute;
}
.page span { display: block; }
@keyframes rot1{
        from { transform: rotateY(0deg); }
        to { transform: rotateY(-180deg); }
}
@keyframes rot2{
        from { transform: rotateY(-180deg); }
        to { transform: rotateY(0deg); }
}
</style>

<div class="book">
        <div class="page"><span>1</span></div>
        <div class="page"><span>2</span></div>
        <div class="page"><span>3</span></div>
        <div class="page"><span>4</span></div>
</div>

<script>

let page = document.querySelectorAll(".page");
let idx = 0;
let all = page.length;
let currentPage = 0;

setzIdx();

document.querySelector(".book").onclick = function(){
        if(idx == 0){ //前翻
                page.style.animation = "rot1 .5s linear forwards";
                page.children.style.transform = "rotateY(-180deg)";
                currentPage ++;
                if(currentPage == all){
                        idx = 1;
                        currentPage = all - 1;
                }
                setzIdx();
        } else { //后翻
                page.style.animation = "rot2 .5s linear forwards";
                page.children.style.transform = "rotateY(0deg)";
                currentPage --;
                if(currentPage < 0){
                        idx = 0;
                        currentPage = 0;
                }
                setzIdx();
        }
}

function setzIdx(){
        for(j=currentPage; j<all; j++){
                page.style.zIndex = all - j;
        }
        for(j=0; j<currentPage;j++) {
                page.style.zIndex = j + 1;
        }
        if(currentPage == all - 1) page.style.zIndex = all;
}

</script>

马黑黑 发表于 2022-4-27 08:01

当前翻书代码的一些说明:

一、CSS

①.book 类选择器作为翻书的场所,尺寸变得更大,背景色也变了。它还以弹性布局的方式令一级子元素及书页垂直居中;

②.page 类选择器,即书页样式,略作加工,主要是令其有一些阴影;

③添加了 span 元素选择器,隶属于 .page,作为 .page 当前演示所用的第一级子元素,用以装载文本,稍后在JS里通过对它的翻转令文本正位。

其他细节修饰尚未操作。

二、HTML

现在主体结构是三层,外层是书的展示场景,第二层是书页,每个书页各带一个子层,也就是第三层 span(将来可能或可以会考虑换成其他的)。

三、JS

JS依然保持简洁,但完善了一些功能:

① 新增过程公用两个变量:all 用于获取 .page 即书页的总量,便于翻页边界操作;currentPage 是当前页,具体指当前接收翻页操作的页序号,它是确定翻页的接收对象、翻页边界判断等的依据;

② 增设一个自定义函数 setzIdx,意为 set z-index,即设置书页的层秩序,相当于洗牌。这个函数一开始就会被调用,让书页按预设的顺序摆放。每一次的翻页动作,都要调用一次该函数,重新洗牌。该函数的洗牌依据之一是 currentPage,当前页肯定得到一个相对大的 z-index 值,其余依次减小此值。函数用了两此 for 语句,分别针对当前页往前、往后进行对书页“洗牌”;

③ 书本单击事件重新改写,依然依据变量 idx 判断前翻/后翻,并做相应的“洗牌”、边界判断处理等工作。和重置书页 z-index 秩序一样,这里也体现着算法的精妙。

此翻页版本,基本功能业已实现,它能用了。细节方面可根据用途修改完善。

红影 发表于 2022-4-27 09:09

原来这里也有,看到一楼就直接跑去那边了{:4_173:}

红影 发表于 2022-4-27 09:13

试了一下,可以随便加了。这个竟然不需要设置z向了啊,现在想加多少就加多少了。黑黑厉害{:4_199:}

加林森 发表于 2022-4-27 10:53

好漂亮的制作,老黑你真好!{:4_190:}

马黑黑 发表于 2022-4-27 12:53

加林森 发表于 2022-4-27 10:53
好漂亮的制作,老黑你真好!

一般般一般般,班里倒数第三

马黑黑 发表于 2022-4-27 12:56

红影 发表于 2022-4-27 09:09
原来这里也有,看到一楼就直接跑去那边了

这里早上放上去的

马黑黑 发表于 2022-4-27 13:01

红影 发表于 2022-4-27 09:13
试了一下,可以随便加了。这个竟然不需要设置z向了啊,现在想加多少就加多少了。黑黑厉害

Z轴是否使用还要看情况吧,也不是现在关注的事情。功能完善才是首要任务。作为书籍模拟,大致的功能要先能实现,比如翻页我们是弄好了,可是,打开封面,进去的是扉页和第一页,然后再翻,依次是第二、三页,后面呢,是最后一页和内封,然后是封底,这些情节要考虑进去,不是给个页码那么简单。作为演示,我们先到这一步,这就是本帖能实现的项目。

加林森 发表于 2022-4-27 13:28

马黑黑 发表于 2022-4-27 12:53
一般般一般般,班里倒数第三

又来了。。。{:4_172:}

马黑黑 发表于 2022-4-27 19:30

加林森 发表于 2022-4-27 13:28
又来了。。。

名人名言

加林森 发表于 2022-4-27 20:00

马黑黑 发表于 2022-4-27 19:30
名人名言

好的好的,你说了算。{:4_172:}

红影 发表于 2022-4-27 21:14

马黑黑 发表于 2022-4-27 12:56
这里早上放上去的

那里去传代码的都是大咖啊。

红影 发表于 2022-4-27 21:15

马黑黑 发表于 2022-4-27 13:01
Z轴是否使用还要看情况吧,也不是现在关注的事情。功能完善才是首要任务。作为书籍模拟,大致的功能要先 ...

黑黑说的,是按照常规的书本的排布习惯,考虑得很周全呢{:4_187:}

马黑黑 发表于 2022-4-27 22:19

红影 发表于 2022-4-27 21:15
黑黑说的,是按照常规的书本的排布习惯,考虑得很周全呢

这个好像是必须的吧

马黑黑 发表于 2022-4-27 22:19

红影 发表于 2022-4-27 21:14
那里去传代码的都是大咖啊。

可以不是的

红影 发表于 2022-4-28 10:17

马黑黑 发表于 2022-4-27 22:19
这个好像是必须的吧

在黑黑这里,万物皆可模拟{:4_173:}

红影 发表于 2022-4-28 10:18

马黑黑 发表于 2022-4-27 22:19
可以不是的

没两把刷子谁敢去啊{:4_173:}

马黑黑 发表于 2022-4-28 12:58

红影 发表于 2022-4-28 10:18
没两把刷子谁敢去啊

那里就是用来测试和保留代码的
页: [1] 2 3
查看完整版本: 何故不翻书