马黑黑 发表于 2025-7-8 12:09

CSS+TWEEN创意3d粒子

<style>
    #papa { margin: 20px auto; left: calc(50% - 81px); transform: translate(-50%); width: 1024px; height: 640px; border: 1px solid gray; perspective: 3000px; transform-style: preserve-3d; overflow: visible; display: grid; place-items: center; position: relative; }
    .son { position: absolute; width: 30px; height: 30px; border-radius: 50%; background: linear-gradient(35deg, green, skyblue); filter: drop-shadow(2px 4px 8px gray); opacity: 0; transform: rotateZ(var(--a)) translate3d(var(--x), var(--y), var(--z)); --x: 0; --y: 0; --z: 0; --a: 0; }
</style>

<div id="papa"></div>

<script type="module">
    import TWEEN from 'https://638183.freep.cn/638183/3dev/examples/jsm/libs/tween.module.js';

    const total = 60, sons = [];

    Array.from({length: total}).forEach(son => {
      son = document.createElement('div');
      son.className = 'son';
      son.style.background = `
      linear-gradient(
            35deg,
            #${Math.random().toString(16).substring(2, 8)},
            #${Math.random().toString(16).substring(2, 8)}
      )
      `;
      sons.push(son);
      papa.appendChild(son);
      const begin = {
            x: papa.clientWidth / 4 - Math.random() * papa.clientWidth / 2,
            y: papa.clientHeight / 4 - Math.random() * papa.clientHeight / 2,
            z: -5000,
            a: 0
      };
      const end = {
            x: 0,
            y: [-papa.clientHeight / 1.5, papa.clientHeight / 3],
            z: [-2000, 600],
            a:
      };
      const tween = new TWEEN.Tween(begin)
            .to(end, Math.random() * 5000 + 8000)
            .onUpdate( () => {
                son.style.setProperty('--x', begin.x + 'px');
                son.style.setProperty('--y', begin.y + 'px');
                son.style.setProperty('--z', begin.z + 'px');
                son.style.setProperty('--a', begin.a + 'deg');
            })
            .onStart( () => son.style.opacity = '1')
            .delay(Math.random() * 5000)
            .repeat(Infinity)
            .repeatDelay(Math.random() * 5000)
            .easing(TWEEN.Easing.Exponential.Out)
            .yoyo(Math.random() * 10000)
            .start();
    });

    const animate = () => {
      requestAnimationFrame(animate);
      TWEEN.update();
    };

    animate();
</script>

马黑黑 发表于 2025-7-8 12:10

代码:

<style>
    #papa { margin: 20px auto; width: 1024px; height: 640px; border: 1px solid gray; perspective: 3000px; transform-style: preserve-3d; overflow: visible; display: grid; place-items: center; position: relative; }
    .son { position: absolute; width: 30px; height: 30px; border-radius: 50%; background: linear-gradient(35deg, green, skyblue); filter: drop-shadow(2px 4px 8px gray); opacity: 0; transform: rotateZ(var(--a)) translate3d(var(--x), var(--y), var(--z)); --x: 0; --y: 0; --z: 0; --a: 0; }
</style>

<div id="papa"></div>

<script type="module">
    import TWEEN from 'https://638183.freep.cn/638183/3dev/examples/jsm/libs/tween.module.js';

    const total = 60, sons = [];

    Array.from({length: total}).forEach(son => {
      son = document.createElement('div');
      son.className = 'son';
      son.style.background = `
      linear-gradient(
            35deg,
            #${Math.random().toString(16).substring(2, 8)},
            #${Math.random().toString(16).substring(2, 8)}
      )
      `;
      sons.push(son);
      papa.appendChild(son);
      const begin = {
            x: papa.clientWidth / 4 - Math.random() * papa.clientWidth / 2,
            y: papa.clientHeight / 4 - Math.random() * papa.clientHeight / 2,
            z: -5000,
            a: 0
      };
      const end = {
            x: 0,
            y: [-papa.clientHeight / 1.5, papa.clientHeight / 3],
            z: [-2000, 600],
            a:
      };
      const tween = new TWEEN.Tween(begin)
            .to(end, Math.random() * 5000 + 8000)
            .onUpdate( () => {
                son.style.setProperty('--x', begin.x + 'px');
                son.style.setProperty('--y', begin.y + 'px');
                son.style.setProperty('--z', begin.z + 'px');
                son.style.setProperty('--a', begin.a + 'deg');
            })
            .onStart( () => son.style.opacity = '1')
            .delay(Math.random() * 5000)
            .repeat(Infinity)
            .repeatDelay(Math.random() * 5000)
            .easing(TWEEN.Easing.Exponential.Out)
            .yoyo(Math.random() * 10000)
            .start();
    });

    const animate = () => {
      requestAnimationFrame(animate);
      TWEEN.update();
    };

    animate();
</script>

杨帆 发表于 2025-7-8 15:24

美妙的效果!谢谢马老师经典讲授与分享{:4_190:}

梦江南 发表于 2025-7-8 15:55

代码如此神奇,能用到篮球、足球中就战无不胜了!

红影 发表于 2025-7-8 16:35

a:
这个导致的回到在下面时是半圆形吧。又是一种小球发散和回归的新效果呢{:4_187:}

红影 发表于 2025-7-8 16:36

CSS+TWEEN创意3d粒子,真是创意无限啊{:4_199:}

马黑黑 发表于 2025-7-8 18:46

红影 发表于 2025-7-8 16:36
CSS+TWEEN创意3d粒子,真是创意无限啊

部分有tween驱动的数据使用了数组。

初学者也可以酱紫设计:不用那么多的属性数据,仅一个旋转、一个平移,然后,给它们都设置目标数组,这样可能更容易把握一些。

马黑黑 发表于 2025-7-8 18:47

红影 发表于 2025-7-8 16:35
a:
这个导致的回到在下面时是半圆形吧。又是一种 ...

这是角度数组。第一个数组元素发生在上方,第二个数组元素影响下方的布局。

马黑黑 发表于 2025-7-8 18:47

梦江南 发表于 2025-7-8 15:55
代码如此神奇,能用到篮球、足球中就战无不胜了!

{:4_191:}

马黑黑 发表于 2025-7-8 18:47

杨帆 发表于 2025-7-8 15:24
美妙的效果!谢谢马老师经典讲授与分享

{:4_190:}

红影 发表于 2025-7-8 21:05

马黑黑 发表于 2025-7-8 18:46
部分有tween驱动的数据使用了数组。

初学者也可以酱紫设计:不用那么多的属性数据,仅一个旋转、一个 ...

是的,那些数组比较难理解些{:4_204:}

红影 发表于 2025-7-8 21:13

马黑黑 发表于 2025-7-8 18:47
这是角度数组。第一个数组元素发生在上方,第二个数组元素影响下方的布局。

嗯嗯,它的数值决定了布局的形式。

马黑黑 发表于 2025-7-8 21:43

红影 发表于 2025-7-8 21:13
嗯嗯,它的数值决定了布局的形式。

多因素综合起来影响运动形态

马黑黑 发表于 2025-7-8 21:44

红影 发表于 2025-7-8 21:05
是的,那些数组比较难理解些

Tween支持使用数组表示要变更的目标数据。这和svg的动画的实现表达方式是一脉相承的

红影 发表于 2025-7-8 22:10

马黑黑 发表于 2025-7-8 21:43
多因素综合起来影响运动形态

有的时候很难直接想到运动状态,尤其多因素下的。只能做出来看了。

红影 发表于 2025-7-8 22:12

马黑黑 发表于 2025-7-8 21:44
Tween支持使用数组表示要变更的目标数据。这和svg的动画的实现表达方式是一脉相承的

主要我两个都没好,没理解透。{:4_173:}

马黑黑 发表于 2025-7-9 14:03

红影 发表于 2025-7-8 22:12
主要我两个都没好,没理解透。

tween应该是最好理解的:仅仅是理解的话,20分钟读完文档就行了。用起来需要慢慢琢磨、体会。

马黑黑 发表于 2025-7-9 14:04

红影 发表于 2025-7-8 22:10
有的时候很难直接想到运动状态,尤其多因素下的。只能做出来看了。

需要对原理、规范都能透彻理解

红影 发表于 2025-7-9 22:42

马黑黑 发表于 2025-7-9 14:03
tween应该是最好理解的:仅仅是理解的话,20分钟读完文档就行了。用起来需要慢慢琢磨、体会。

它的含义和运作方式知道了,怎样操控它,还是有难度。

红影 发表于 2025-7-9 22:42

马黑黑 发表于 2025-7-9 14:04
需要对原理、规范都能透彻理解

是的,这个是必须的{:4_187:}
页: [1] 2 3
查看完整版本: CSS+TWEEN创意3d粒子