马黑黑 发表于 2022-7-31 23:46

大十字回文诗JS代码解释

先分析一下实现思路:

一、大十字回文诗(红影作品)



二、字串处理

通过分析,可以考虑诗文的取字采用横竖方式,竖行取字时重复的“汗”字不要,得出一个字串:

轻衫浸汗热流倾凌威暑珠飘坠

然后将以上字串逐字拆分赋值给数组 strAr :

let strAr = '轻衫浸汗热流倾凌威暑珠飘坠'.split('');

这样,每一个字都有自己的下标,下面是单字和下标示意:

0|轻1|衫2|浸3|汗4|热5|流6|倾7|凌8|威9|暑10|珠11|飘12|坠

构建读法时,给出(诗句)读法数组就是用下标表示,比如第一种读法,左中上方向,,最后一个字重复一次,以配合函数完好圈字;其他读法一词组建数组。

字串在帖子上的排列,单字下标除以 6 小于等于 1 时,是原作品横向排列的字,我们只需设置它们的左边值(left)即可,文字所在的span标签我们设置为60px*60px,所以横向的各个字的 left 值为 下标值*60 px;纵向的 top 值不好计算,我们可以给出一个数组,然后通过读取数组得到 后面六个字的top值:

0,60,120,240,300,360]

前面七个字的top值无关紧要,我们不用到,随便填0或其他值;第八个字,即下标为 7 的“凌”字,top 是 0(最顶端),第九个字(下标是8)加60(60是对应于span的高度值)得60,第十个字(下表是9)加60得120,第十一个字要跳一个字(就是汗字)加两个60得240,后面剩下的两个字都加60后分别得300和360。

实现代码(注释说明,发布帖子前应去除注释以提升代码运行效能):

<script>
//idx : 读法标识 step : 圈子标识 spans : 单字载体数组(即span标签数组)
let idx = 0, step = 0, spans = [];
//横、纵排列 纵向不要重复的汗字。字串拆分为单字并放入数组 strAr
let strAr = '轻衫浸汗热流倾凌威暑珠飘坠'.split(''),
        //诗句读法数据(下标依据,末字重复一次),可添加读法
        sentences = [
                ,
                ,
                ,
                ,
        ],
        ttAr = 0,60,120,240,300,360]; //纵向排列Top数据:前面7个随意填,未用到
let aud = new Audio(); //创建音频对象
//指定音频源
aud.src = 'https://music.163.com/song/media/outer/url?id=1818276770.mp3';
aud.loop = true; //音频重复播放
aud.autoplay = true; //音频自动播放

let num = (min, max) => Math.floor(Math.random() * (max-min+1)) + min; //在两个数间随机取整数

//大十字回文诗布局
for(let x in strAr) {
        let ele = document.createElement('span'); //创建 span 标签
        ele.className = 'txt'; //指定标签类名称 class="txt"
        ele.innerText = strAr; //从 strAr 数组中取单字
        if(parseInt(x) / 6 <= 1) { //单字下标除以6若大于等于1 (前面七个字)
                ele.style.left = (x * 60) + 'px'; // left值一次排列 0*60 至 6 * 60
        } else { //不然的话
                ele.style.left = '180px'; //left值通通为 180px(横向第四个字的left值)
                ele.style.top = ttAr + 'px'; //top值读取 ttAr 数组里的数据
        }
        mama.appendChild(ele); //id="mama"的div追加 span 标签
        spans.push(ele); //把 span 标签加入到 spans 数组(以便将来变色、画圈操作之用)
}

txtColor(); //运行一次变色函数
txtCircle(); //运行一次画圈函数

mama.onclick = () => aud.paused ? aud.play() : aud.pause(); //音乐控制

//文本变色函数
function txtColor() {
        for(let y of spans) { // 读取每一个 spans 标签数组的元素
                y.style.color = 'snow'; //将所有的背景色设置为 snow(雪白)
                y.style.border = 'none'; //把已画好的圈圈去除
        }
        //根据当前读法标识 idx 的值给诗句每一个字上色
        for(let x of sentences) spans.style.color = `rgb(${num(0,255)},${num(0,255)},${num(0,255)})`;
        sMsg.innerText = idx + 1; // 第几句诗句提示
}

//文本画圈函数:从 0 画到 7(末字是重复一次的)
function txtCircle() {
        let x = sentences; //当前句(idx)第 step 个字
        spans.style.border = '1px solid lightgreen'; //设置边框值
        step ++; //步数自增
        if(step > 7) { //步数自增大于7时
                step = 0; //步数恢复到0
                idx ++; //诗句标识自增
                if(idx > sentences.length - 1) idx = 0; //诗句标识自增到大于总读法减1时 idx 恢复到 0
                txtColor(); //调用变色函数(开始下一个诗句)
        }
        setTimeout(txtCircle, 1500); //定时器递归调用(从而循环往复)
}
</script>

樵歌 发表于 2022-8-1 06:48

早上好{:4_190:}辛苦了。还没整明白。{:4_203:}

樵歌 发表于 2022-8-1 06:50

我那和红影的读法走向不一样,不知道怎么改动?另外,音乐添加是在惚云里去找鼓劲的地址吧?

马黑黑 发表于 2022-8-1 07:23

本帖最后由 马黑黑 于 2022-8-1 07:24 编辑

樵歌 发表于 2022-8-1 06:50
我那和红影的读法走向不一样,不知道怎么改动?另外,音乐添加是在惚云里去找鼓劲的地址吧?
第一,读法:根据我所示意的单字下标制定 sentences 诗句读法数组。再举例说明如下:

比如全诗有五个字,以及它们的对应下标是:

一二三四五
01 23 4

数组则这么建立(末字重复一次):

读“一二三”:
读“四三二”:
读“四四三三”:

第二:音频

音频地址只要能用(就是人家不防盗链),在哪找都行,也可以自己上传(问问小辣椒)

红影 发表于 2022-8-1 09:35

这个真不容易,取字需要建立一个数组,要是没有0|轻1|衫2|浸3|汗4|热5|流6|倾7|凌8|威9|暑10|珠11|飘12|坠
这个说明,都不知道那些数字都代表什么的。
其次是排列文字成大十字,也挺费脑筋的,
最后还有画圈的过程,要严格按照设定的方向去画出了取消,重复不同的循环。

红影 发表于 2022-8-1 09:36

樵歌 发表于 2022-8-1 06:50
我那和红影的读法走向不一样,不知道怎么改动?另外,音乐添加是在惚云里去找鼓劲的地址吧?

师兄,在sentences = [
                ,
                ,
                ,
                ,
      ],
这个里面改动对应的字,就能实现从不同的走向读了。

红影 发表于 2022-8-1 10:03

奇怪,我完全用你的那帖子的代码,只替换成樵歌的文字,为什么圆圈没有了?

红影 发表于 2022-8-1 10:03

<style>
#papa { left: -214px; width: 1024px; height: 640px; background: gray url('/data/attachment/forum/202207/31/213753z9ymmpyynczpeesj.jpg') no-repeat center/cover; box-shadow: 4px 4px 24px #000; position: relative; }
#mama { position: absolute; right: 110px; top: calc(50% - 215px); display: grid; place-items: center; width: 420px; height: 420px; cursor: pointer; }
#mama::before { position: absolute; content: ''; width: inherit; height: inherit; box-shadow: 2px 2px 12px #000; transform: rotate(45deg); }
#tit { position: absolute; left: 210px; top: 26px; font: bold 30px / 30px sans-serif; color: white; text-shadow: 1px 1px 2px rgba(0,0,0,.8); }
#sMsg { position: absolute; left: 120px; top: 120px; }
.txt { position: absolute; width: 60px; height: 60px; font: bold 40px / 60px sans-serif; text-align: center; text-shadow: 2px 2px 4px rgba(0,0,0,.7); border-radius: 50%; color: snow; }
</style>

<div id="papa">
        <span id="tit">樵歌 - 《三伏消暑回文诗·忙》</span>
        <div id="mama"><span id="sMsg" class="txt"></span></div>
</div>

<script>
let idx = 0, step = 0, milsecs = 1000, spans = [];

let strAr = '雁鸣忙去远山苍江流退黯怀乡'.split(''),
        sentences = [ //诗句读法:可添加
                ,
                ,
                ,
                ,
        ],
        ttAr = ; //纵向排列Top数据
let aud = new Audio();
aud.src = 'https://music.163.com/song/media/outer/url?id=1818276770.mp3';
aud.loop = true;
aud.autoplay = true;

let num = (min, max) => Math.floor(Math.random() * (max-min+1)) + min;

for(let x in strAr) {
        let ele = document.createElement('span');
        ele.className = 'txt';
        ele.innerText = strAr;
        if(parseInt(x) / 6 <= 1) {
                ele.style.left = (x * 60) + 'px';
        } else {
                ele.style.left = '180px';
                ele.style.top = ttAr + 'px';
        }
        mama.appendChild(ele);
        spans.push(ele);
}

txtColor()
txtCircle();

mama.onclick = () => aud.paused ? aud.play() : aud.pause();

function txtColor() {
        for(let y of spans) {
                y.style.color = 'snow';
                y.style.border = 'none';
        }
        for(let x of sentences) spans.style.color = `rgb(${num(0,255)},${num(0,255)},${num(0,255)})`;
        sMsg.innerText = idx + 1;
}

function txtCircle() {
        let x = sentences;
        spans.style.border = '1px solid lightgreen';
        step ++;
        if(step > 7) {
                step = 0;
                idx ++;
                if(idx > sentences.length - 1) idx = 0;
                txtColor();
        }
        setTimeout(txtCircle, 1500);
}
</script>

马黑黑 发表于 2022-8-1 11:14

红影 发表于 2022-8-1 10:03
奇怪,我完全用你的那帖子的代码,只替换成樵歌的文字,为什么圆圈没有了?

你的 sentences 数组不对。全诗13个字,下标最大是12,你的读法数组里有13,肯定不对的。

重新设定读法 sentences 数组,必须记住:下标 0 对应 第一个字,下标 12 对应 第十三个字,其余依此类推。

加林森 发表于 2022-8-1 12:22

来学习。真看得冒汗了。。。。

红影 发表于 2022-8-1 13:11

马黑黑 发表于 2022-8-1 11:14
你的 sentences 数组不对。全诗13个字,下标最大是12,你的读法数组里有13,肯定不对的。

重新设定读 ...

嗯嗯,知道了。之前还记着第一个字下标是0 ,之后就又混了,从第一个字数过来了{:4_173:}

红影 发表于 2022-8-1 16:27

马黑黑 发表于 2022-8-1 11:14
你的 sentences 数组不对。全诗13个字,下标最大是12,你的读法数组里有13,肯定不对的。

重新设定读 ...

嗯嗯,我后面的字的序数按从1开始排列了,应该从0开始的{:4_173:}

马黑黑 发表于 2022-8-1 18:11

红影 发表于 2022-8-1 16:27
嗯嗯,我后面的字的序数按从1开始排列了,应该从0开始的

是的,数组的下标总是从0开始

马黑黑 发表于 2022-8-1 18:22

红影 发表于 2022-8-1 13:11
嗯嗯,知道了。之前还记着第一个字下标是0 ,之后就又混了,从第一个字数过来了

13是超越了下标,JS就会出错

红影 发表于 2022-8-1 22:17

马黑黑 发表于 2022-8-1 18:11
是的,数组的下标总是从0开始

嗯嗯,以后要记得这个了{:4_187:}

红影 发表于 2022-8-1 22:18

马黑黑 发表于 2022-8-1 18:22
13是超越了下标,JS就会出错

JS很严密,的确错不得。

马黑黑 发表于 2022-8-1 23:16

红影 发表于 2022-8-1 22:18
JS很严密,的确错不得。
一点点小错也不行

红影 发表于 2022-8-2 19:18

马黑黑 发表于 2022-8-1 23:16
一点点小错也不行

错一次也好,这下彻底记住了{:4_173:}

马黑黑 发表于 2022-8-2 19:51

红影 发表于 2022-8-2 19:18
错一次也好,这下彻底记住了

不过犯错是永恒的额{:5_117:}

红影 发表于 2022-8-2 20:56

马黑黑 发表于 2022-8-2 19:51
不过犯错是永恒的额

那是,学的过程不犯错是不可能的{:4_173:}
页: [1] 2
查看完整版本: 大十字回文诗JS代码解释