马黑黑 发表于 2025-2-14 13:46

No Happy Endings(scroll版)

本帖最后由 马黑黑 于 2025-2-14 23:41 编辑 <br /><br /><style>
        #papa { margin: 30px 0 30px calc(50% - 681px); width: 1200px; height: 720px; background: url('https://638183.freep.cn/638183/t24/webp3/ims.webp') no-repeat center/cover; box-shadow: 3px 3px 8px black; display: grid; place-items: center; position: relative; }
        #stage { position: absolute; width: 460px; height: 600px; font-size: 0; border-radius: 50%; overflow: hidden; white-space: nowrap; cursor: pointer; }
        #stage img { width: 100%; height: 100%; mask: radial-gradient(red, transparent); }
        #stage img:hover { mask: unset; }
        #btnplay { --state: running; position: absolute; bottom: 10px;; width: 30px; height: 30px; color: white; display: grid; place-items: center; cursor: pointer; }
        #btnplay::before { position: absolute; content: ''; width: 100%; height: 100%; border: 2px dashed cyan; border-radius: 50%; animation: rot 8s linear infinite var(--state); }
        #btnplay:hover::before { border-style: dotted; }
        @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
        <div id="stage">
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji01.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji02.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji03.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji04.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji05.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji06.jpg" />
        </div>
        <div id="btnplay">1</div>
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=27770747" autoplay loop></audio>
</div>

<script>
var lastIdx = 0, pTimer;
var images = stage.querySelectorAll('img');
var mState = () => {
        btnplay.style.setProperty('--state', aud.paused ? 'paused' : 'running');
        btnplay.title = stage.title = aud.paused ? '点击播放' : '点击暂停';
        aud.paused ? clearTimeout(pTimer) : turn2();
};
var turn2 = (idx) => {
        idx = Math.floor(Math.random() * images.length);
        if(idx === lastIdx) idx = (idx+1) % images.length;
        lastIdx = idx;
        btnplay.innerText = idx + 1;
        stage.scroll({left: idx * 460, top: 0, behavior: 'smooth'});
        if(pTimer) clearTimeout(pTimer);
        pTimer = setTimeout(turn2, 3000);
};
aud.onpause = aud.onplaying = () => mState();
stage.onclick = btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
papa.scrollIntoView(true);
</script>

马黑黑 发表于 2025-2-14 13:47

本帖最后由 马黑黑 于 2025-2-14 23:40 编辑

代码:

<style>
      #papa { margin: 30px 0 30px calc(50% - 681px); width: 1200px; height: 720px; background: url('https://638183.freep.cn/638183/t24/webp3/ims.webp') no-repeat center/cover; box-shadow: 3px 3px 8px black; display: grid; place-items: center; position: relative; }
      #stage { position: absolute; width: 460px; height: 600px; font-size: 0; border-radius: 50%; overflow: hidden; white-space: nowrap; cursor: pointer; }
      #stage img { width: 100%; height: 100%; mask: radial-gradient(red, transparent); }
      #stage img:hover { mask: unset; }
      #btnplay { --state: running; position: absolute; bottom: 10px;; width: 30px; height: 30px; color: white; display: grid; place-items: center; cursor: pointer; }
      #btnplay::before { position: absolute; content: ''; width: 100%; height: 100%; border: 2px dashed cyan; border-radius: 50%; animation: rot 8s linear infinite var(--state); }
      #btnplay:hover::before { border-style: dotted; }
      @keyframes rot { to { transform: rotate(360deg); } }
</style>

<div id="papa">
      <div id="stage">
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji01.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji02.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji03.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji04.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji05.jpg" />
                <img alt="" src="https://638183.freep.cn/638183/t24/biu/ji06.jpg" />
      </div>
      <div id="btnplay">1</div>
      <audio id="aud" src="https://music.163.com/song/media/outer/url?id=27770747" autoplay loop></audio>
</div>

<script>
var lastIdx = 0, pTimer;
var images = stage.querySelectorAll('img');
var mState = () => {
      btnplay.style.setProperty('--state', aud.paused ? 'paused' : 'running');
      btnplay.title = stage.title = aud.paused ? '点击播放' : '点击暂停';
      aud.paused ? clearTimeout(pTimer) : turn2();
};
var turn2 = (idx) => {
      idx = Math.floor(Math.random() * images.length);
      if(idx === lastIdx) idx = (idx+1) % images.length;
      lastIdx = idx;
      btnplay.innerText = idx + 1;
      stage.scroll({left: idx * 460, top: 0, behavior: 'smooth'});
      if(pTimer) clearTimeout(pTimer);
      pTimer = setTimeout(turn2, 3000);
};
aud.onpause = aud.onplaying = () => mState();
stage.onclick = btnplay.onclick = () => aud.paused ? aud.play() : aud.pause();
</script>

马黑黑 发表于 2025-2-14 13:52

这个版本使用的翻页方法是 scroll,取代后花园演示的 scrollIntoView,特点是不会影响下拉阅读、回复等常规论坛交互操作。

代码变化有两个:

一是04行,图片高度属性 height 不能少,以确保图片完美显示;
二是38行,使用图片父元素滚动(scroll)替代图片自身滚动(scrollIntoView)。

红影 发表于 2025-2-14 14:26

果然,图片父元素滚动(scroll)对回帖没什么影响了。黑黑用两个帖子很直观地展示了两者的不同,真好{:4_199:}

红影 发表于 2025-2-14 14:28

鼠标触动还能让图片的透明度发生变化,底下的小圆圈里还有第几张图图的序号呢{:4_187:}

红影 发表于 2025-2-14 14:37

好吧,看了代码,才知道鼠标触碰不是透明度变化,而是滤镜变化。下面小圆圈鼠标触碰时会改变线型,也很奇妙。{:4_187:}

杨帆 发表于 2025-2-14 17:53

本帖最后由 杨帆 于 2025-2-14 18:04 编辑

这个更实用,完美解决了回帖问题,祝老师节日快乐{:4_191:}

小辣椒 发表于 2025-2-14 19:44

黑黑这个做帖里面的实例出来了{:4_199:}

小辣椒 发表于 2025-2-14 19:45

这个图片自动转换效果漂亮的,看看代码可以直接套用{:4_170:}

马黑黑 发表于 2025-2-14 19:48

小辣椒 发表于 2025-2-14 19:45
这个图片自动转换效果漂亮的,看看代码可以直接套用

完全可以

马黑黑 发表于 2025-2-14 19:49

小辣椒 发表于 2025-2-14 19:44
黑黑这个做帖里面的实例出来了

我就是等你做呢,结果你一直没做{:4_170:}

小辣椒 发表于 2025-2-14 19:49

马黑黑 发表于 2025-2-14 13:52
这个版本使用的翻页方法是 scroll,取代后花园演示的 scrollIntoView,特点是不会影响下拉阅读、回复等常规 ...
04 行 #stage img { width: 100%; height: 100%; mask: radial-gradient(red, transparent); }

黑黑,你这里是100%是指图片实际尺寸还是:

03行 的stage { position: absolute; width: 460px; height: 600px;

马黑黑 发表于 2025-2-14 19:49

杨帆 发表于 2025-2-14 17:53
这个更实用,完美解决了回帖问题,祝老师节日快乐

这两个API各有特点

小辣椒 发表于 2025-2-14 19:50

不管了,现在去自己实际测试一下{:4_170:}

马黑黑 发表于 2025-2-14 19:50

红影 发表于 2025-2-14 14:37
好吧,看了代码,才知道鼠标触碰不是透明度变化,而是滤镜变化。下面小圆圈鼠标触碰时会改变线型,也很奇妙 ...

这些都是CSS处理的,一个基于遮罩,另一个基于border-style(边框样式)

马黑黑 发表于 2025-2-14 19:51

红影 发表于 2025-2-14 14:28
鼠标触动还能让图片的透明度发生变化,底下的小圆圈里还有第几张图图的序号呢

{:4_190:}

马黑黑 发表于 2025-2-14 19:52

红影 发表于 2025-2-14 14:26
果然,图片父元素滚动(scroll)对回帖没什么影响了。黑黑用两个帖子很直观地展示了两者的不同,真好{:4_19 ...

scroll直接操作有滚动条的元素,scrollIntoview操作的是被滚动对象

马黑黑 发表于 2025-2-14 19:56

小辣椒 发表于 2025-2-14 19:50
不管了,现在去自己实际测试一下

{:4_196:}

马黑黑 发表于 2025-2-14 19:56

小辣椒 发表于 2025-2-14 19:49
04 行 #stage img { width: 100%; height: 100%; mask: radial-gradient(red, transparent); }

黑黑 ...

当图片以100%渲染时,指它的父元素的尺寸

马黑黑 发表于 2025-2-14 19:58

小辣椒 发表于 2025-2-14 19:49
04 行 #stage img { width: 100%; height: 100%; mask: radial-gradient(red, transparent); }

黑黑 ...

然后,在JS里,翻动距离数值以父元素的宽度(横向翻页)或高度(纵向翻页)做依据
页: [1] 2 3 4
查看完整版本: No Happy Endings(scroll版)