马黑黑 发表于 2022-4-27 20:00

黑书

本帖最后由 马黑黑 于 2022-4-27 22:32 编辑

上一个版本,我们的 CSS+JS 翻书程序虽然稚嫩,好歹也解决了一些最基本的问题,能顺畅来回翻页,文本也不再是反镜像的样纸,看着还挺像那么一回事。如果它是个孩纸,那可算是幼儿园小盆友了吧?要不开开恩进学前班也成,我没意见。

顺便提一下,我们这本书既然到了这个程度,总得有个名字,就叫黑书吧。

言归正传。我们必须面对现实,黑书还有很多问题,还需要继续长大。

现实中的书本,掀开封面,看到的是扉页与第一页,再翻则是第二页与第三页,翻到最后一页后会看到内封与它在一块,最后就是封底了。我们的书完全不是酱紫呢,这得改改。

解决思路:每一个书页 page 带两个子元素,其中一个正常显示,另一个隐藏,翻页时让它们俩的显示状态对调一下。其原理好理解,书页有两面,每一面各有自己的内容;只是,用代码实现它,根据代码流原理,封面和扉页是在同一页的,二、三页则对应真实书本的一二页,内封和封底也在代码中同一页,这个逻辑我们要处理。

这个版本,我们不再使用 span 作为 page 的子元素,我们用div,这样更便于发布每一页的内容。记住它们是一对双胞胎,以子元素的形态出现在每一个 page 页里,CSS 这样设定它们:

.page div:nth-child(1) {}
.page div:nth-child(2) { display: none; }

HTML代码改进为:

<div class="book">
      <div class="page">
                <div>封面</div>
                <div>扉页</div>
      </div>
      <div class="page">
                <div>第一页</div>
                <div>第二页</div>
      </div>
      <div class="page">
                <div>第三页</div>
                <div>第四页</div>
      </div>
      <div class="page">
                <div>内封</div>
                <div>封底</div>
      </div>
</div>

HTML盒子结构还是三层结构,与上一个版本不同的是,page 的子层元素是一对并列的div 标签,分别装载各自的内容——当然支持HTML代码了,可以发布文字与图片什么的。

以上HTML结构的变化必然会导致原先的 JS 代码不能完全胜任翻页的工作,也必须改进,需要改动的部分是前翻与后翻的动作,就是书本点击操作事件部分的代码:

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

前翻与后翻动作,分别处理一些逻辑问题,一是那对双胞胎 div 标签谁隐藏谁显示,二是谁需要倒转,就酱,逻辑很清晰,好像没啥特别复杂的,代码多出四行而已。

至此,黑氏书本页码结构的问题完满解决,可以跳级读小一了吧?改天找校长谈谈。

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

本帖最后由 马黑黑 于 2022-4-27 20:06 编辑 <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 div:nth-child(1) {}
.page div:nth-child(2) { display: none; }
@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">
                <div>封面</div>
                <div>扉页</div>
        </div>
        <div class="page">
                <div>第一页</div>
                <div>第二页</div>
        </div>
        <div class="page">
                <div>第三页</div>
                <div>第四页</div>
        </div>
        <div class="page">
                <div>内封</div>
                <div>封底</div>
        </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.display = "none";
                page.children.style.display = "block";
                page.children.style.transform = "rotateY(-180deg)";
                currentPage ++;
                if(currentPage == all){
                        idx = 1;
                        currentPage = all - 1;
                }
        } else { //后翻
                page.style.animation = "rot2 .5s linear forwards";
                page.children.style.display = "none";
                page.children.style.display = "block";
                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 20:07

全部代码:
<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 div:nth-child(1) {}
.page div:nth-child(2) { display: none; }
@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">
                <div>封面</div>
                <div>扉页</div>
        </div>
        <div class="page">
                <div>第一页</div>
                <div>第二页</div>
        </div>
        <div class="page">
                <div>第三页</div>
                <div>第四页</div>
        </div>
        <div class="page">
                <div>内封</div>
                <div>封底</div>
        </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.display = "none";
                page.children.style.display = "block";
                page.children.style.transform = "rotateY(-180deg)";
                currentPage ++;
                if(currentPage == all){
                        idx = 1;
                        currentPage = all - 1;
                }
        } else { //后翻
                page.style.animation = "rot2 .5s linear forwards";
                page.children.style.display = "none";
                page.children.style.display = "block";
                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 20:14

现在,这个可以正常工作了。要编写一本书,要做的事情是给每一页装载多少文字,太多太少都不好,要自己编排一下。

要将自己的内容塞进黑书里,看好HTML代码,红色的部分是自己的内容,可以是文本,可以是图片:

<div class="book">
      <div class="page">
                <div>封面</div>
                <div>扉页</div>
      </div>
      <div class="page">
                <div>第一页</div>
                <div>第二页</div>
      </div>
      <div class="page">
                <div>第三页</div>
                <div>第四页</div>
      </div>
      <div class="page">
                <div>内封</div>
                <div>封底</div>
      </div>
</div>


还可以自己决定一本小黑书有多少页,或添或减都没问题,只要不破坏HTML的内部结构。

红影 发表于 2022-4-27 20:26

我刚做了个原来版本的,黑黑就改进了。我的学习没跟上趟{:4_173:}

红影 发表于 2022-4-27 20:28

要不,我把刚学的发出来,后面改进的算改进的?{:4_173:}

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

红影 发表于 2022-4-27 20:26
我刚做了个原来版本的,黑黑就改进了。我的学习没跟上趟

这个没关系的。我也是有时间就琢磨琢磨,改进版啥时候出来也说不准

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

红影 发表于 2022-4-27 20:28
要不,我把刚学的发出来,后面改进的算改进的?

都可以的

加林森 发表于 2022-4-27 23:46

我已经学会了。谢谢老黑,明天制作出来!实际上我已经制作出来了!谢谢老黑!{:4_199:}

马黑黑 发表于 2022-4-27 23:49

加林森 发表于 2022-4-27 23:46
我已经学会了。谢谢老黑,明天制作出来!实际上我已经制作出来了!谢谢老黑!

队长好厉害

加林森 发表于 2022-4-27 23:52

马黑黑 发表于 2022-4-27 23:49
队长好厉害

不是的,你教得好啊!

红影 发表于 2022-4-28 11:15

马黑黑 发表于 2022-4-27 22:30
这个没关系的。我也是有时间就琢磨琢磨,改进版啥时候出来也说不准

空了我把改进版也学着做一个{:4_187:}

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

红影 发表于 2022-4-28 11:15
空了我把改进版也学着做一个

记得替换一下 setzIdx() 函数

红影 发表于 2022-4-29 20:46

马黑黑 发表于 2022-4-28 12:50
记得替换一下 setzIdx() 函数

哦哦,就是说要用后面一个代码?

马黑黑 发表于 2022-4-29 22:43

红影 发表于 2022-4-29 20:46
哦哦,就是说要用后面一个代码?

最好用最新最简洁的那个,专门优化过的

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

马黑黑 发表于 2022-4-29 22:43
最好用最新最简洁的那个,专门优化过的

嗯嗯,黑黑辛苦了{:4_187:}

马黑黑 发表于 2022-4-30 22:55

红影 发表于 2022-4-30 21:27
嗯嗯,黑黑辛苦了

闹着玩的

红影 发表于 2022-5-2 09:00

马黑黑 发表于 2022-4-30 22:55
闹着玩的

这种玩可以长本事的呢。

马黑黑 发表于 2022-5-2 09:16

红影 发表于 2022-5-2 09:00
这种玩可以长本事的呢。

应该可以

红影 发表于 2022-5-2 10:35

马黑黑 发表于 2022-5-2 09:16
应该可以

肯定可以{:4_173:}
页: [1] 2
查看完整版本: 黑书