马黑黑 发表于 2022-7-18 07:13

在帖子中使用跟随的小鸟

<style>
#papa {
        left: -214px;
        width: 1024px;
        height: 640px;
        background: linear-gradient(180deg, #0C003C 0%, #BFFFAF 100%), linear-gradient(165deg, #480045 25%, #E9EAAF 100%), linear-gradient(145deg, #480045 25%, #E9EAAF 100%), linear-gradient(300deg, rgba(233, 223, 255, 0) 0%, #AF89FF 100%), linear-gradient(90deg, #45EBA5 0%, #45EBA5 30%, #21ABA5 30%, #21ABA5 60%, #1D566E 60%, #1D566E 70%, #163A5F 70%, #163A5F 100%);
        background-blend-mode: overlay, overlay, overlay, multiply, normal;
        box-shadow: 4px 4px 28px #000;
        position: relative;
}
#bird {
        position: absolute;
        width: 73px;
        height: 83px;
        left: 50%;
        top: 500px;
        transition: left 2s, top 2s;
}
</style>

<div id="papa">
        <img id="bird" src="/data/attachment/forum/202207/17/112951jm0vqgv98w8z3h3z.gif" alt="" />
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=5268746.mp3" autoplay="autoplay" loop="loop"></audio>
</div>

<script>

let lastX = 0;
document.addEventListener('click', (e) => {
        e = event || window.event;
        let x = e.pageX, y = e.pageY,
                w = document.body.clientWidth, h = document.body.clientHeight,
                bw = bird.offsetWidth, bh = bird.offsetHeight;
        x = x - offset(papa, 'left');
        y = y - offset(papa, 'top');
        if(x + bw >= w) x = w - bw;
        if(y + bh >= h) y = h - bh;
        bird.style.transform = x > lastX ? 'rotateY(180deg)' : 'rotateY(0deg)';
        lastX = x;
        bird.style.left = x + 'px';
        bird.style.top = y + 'px';
});

function offset(obj,direction){//偏移总量
        let offsetDir = "offset" + direction.toUpperCase()+direction.substring(1);
        let realNum = obj;
        let positionParent = obj.offsetParent;
        while(positionParent != null){
                realNum += positionParent;
                positionParent = positionParent.offsetParent;
        }
        return realNum;
}

</script>

马黑黑 发表于 2022-7-18 07:26

之前,小鸟是脱离于帖子父元素的,与父元素并列存在。这是考虑了减少偏移计算节约代码,但它显然依赖于合适的环境:发帖节点之上没有其他元素使用过定位的父辈及以上辈分的元素。

昨天小辣椒说过期待我的发帖,其实说的就是把能够跟随鼠标点击的小鸟能用于帖子。虽然此前的方案(即img与帖子父元素并列)也可以,但大家可能不习惯,认为小鸟应该是帖子的组成部分。

这就要加入偏移量的计算。小鸟放入帖子作为子元素后,帖子的父元素是有定位的,小鸟又是依托父元素而存在,计算小鸟应移动的距离就得考虑帖子父框和更高层备份的可能偏移总量。关于计算指定节点以上的父辈元素的偏移总量,以前做播放器进度控制时弄过,代码重用即可,就是用递归的方法计算全部的父辈元素的偏移总和。

一楼的效果,代码放在后面的回复。

马黑黑 发表于 2022-7-18 07:26

一楼代码:
<style>
#papa {
        margin: auto;
        width: 1024px;
        height: 640px;
        background: linear-gradient(180deg, #0C003C 0%, #BFFFAF 100%), linear-gradient(165deg, #480045 25%, #E9EAAF 100%), linear-gradient(145deg, #480045 25%, #E9EAAF 100%), linear-gradient(300deg, rgba(233, 223, 255, 0) 0%, #AF89FF 100%), linear-gradient(90deg, #45EBA5 0%, #45EBA5 30%, #21ABA5 30%, #21ABA5 60%, #1D566E 60%, #1D566E 70%, #163A5F 70%, #163A5F 100%);
        background-blend-mode: overlay, overlay, overlay, multiply, normal;
        box-shadow: 4px 4px 28px #000;
        position: relative;
}
#bird {
        position: absolute;
        width: 73px;
        height: 83px;
        left: 50%;
        top: 500px;
        transition: left 2s, top 2s;
}
</style>

<div id="papa">
        <img id="bird" src="/data/attachment/forum/202207/17/112951jm0vqgv98w8z3h3z.gif" alt="" />
        <audio id="aud" src="https://music.163.com/song/media/outer/url?id=5268746.mp3" autoplay="autoplay" loop="loop"></audio>
</div>

<script>

let lastX = 0;
document.addEventListener('click', (e) => {
        e = event || window.event;
        let x = e.pageX, y = e.pageY,
                w = document.body.clientWidth, h = document.body.clientHeight,
                bw = bird.offsetWidth, bh = bird.offsetHeight;
        x = x - offset(papa, 'left');
        y = y - offset(papa, 'top');
        if(x + bw >= w) x = w - bw;
        if(y + bh >= h) y = h - bh;
        bird.style.transform = x > lastX ? 'rotateY(180deg)' : 'rotateY(0deg)';
        lastX = x;
        bird.style.left = x + 'px';
        bird.style.top = y + 'px';
});

function offset(obj,direction){//偏移总量
        let offsetDir = "offset" + direction.toUpperCase()+direction.substring(1);
        let realNum = obj;
        let positionParent = obj.offsetParent;
        while(positionParent != null){
                realNum += positionParent;
                positionParent = positionParent.offsetParent;
        }
        return realNum;
}

</script>


马黑黑 发表于 2022-7-18 07:31

小鸟可以在帖子里跟随鼠标的单击,也可以在帖子外跟随。效果和昨天发的元素并列关系的其实一样,不同的是,小鸟现在是帖子里的子元素,是帖子的组成内容。

另外,昨天做的,第一次点击小鸟立即到达,那是因为CSS里使用了默认的left和top值,即没有设定。设定之后,第一次单击也是按 transition 规定的速率运动。

马黑黑 发表于 2022-7-18 07:34

还有一个问题一楼没有处理,那就是小鸟的 z-index 设定。可以给其设定一个大一点的 z-index 值,

    z-index: 999;

这样,页面上的弹出式窗口、浮动元素(比如右边的纵向导航条)也挡不住小鸟

红影 发表于 2022-7-18 11:04

在帖子中点一下,等着小鸟儿蹦蹦跳跳地跑过来,已经成了很有趣的游戏了 {:4_173:}

樵歌 发表于 2022-7-18 11:46

我要购买这个专利,谁也不要和俺抢。

樵歌 发表于 2022-7-18 11:46

第二页能到达吗

樵歌 发表于 2022-7-18 11:47

不要太可爱了

樵歌 发表于 2022-7-18 11:49

害我逗小鸟玩了好久{:4_174:}

马黑黑 发表于 2022-7-18 12:29

樵歌 发表于 2022-7-18 11:49
害我逗小鸟玩了好久

玩完放生哈

马黑黑 发表于 2022-7-18 12:29

樵歌 发表于 2022-7-18 11:46
我要购买这个专利,谁也不要和俺抢。

五毛钱

马黑黑 发表于 2022-7-18 12:30

红影 发表于 2022-7-18 11:04
在帖子中点一下,等着小鸟儿蹦蹦跳跳地跑过来,已经成了很有趣的游戏了

你把手伸进屏幕它会到你手上来

马黑黑 发表于 2022-7-18 12:30

樵歌 发表于 2022-7-18 11:46
第二页能到达吗

不能,但可以再放

樵歌 发表于 2022-7-18 16:35

马黑黑 发表于 2022-7-18 12:29
玩完放生哈

舍不得

樵歌 发表于 2022-7-18 16:36

马黑黑 发表于 2022-7-18 12:29
五毛钱

加点再加点{:4_189:}

樵歌 发表于 2022-7-18 16:37

马黑黑 发表于 2022-7-18 12:30
不能,但可以再放

太好了

马黑黑 发表于 2022-7-18 19:09

樵歌 发表于 2022-7-18 16:37
太好了

当然当然

马黑黑 发表于 2022-7-18 19:10

樵歌 发表于 2022-7-18 16:36
加点再加点

不加。男子汉大丈夫一言九鼎五毛当一万。

马黑黑 发表于 2022-7-18 19:10

樵歌 发表于 2022-7-18 16:35
舍不得

不要太留恋
页: [1] 2 3
查看完整版本: 在帖子中使用跟随的小鸟