白色戏法(测试自适应svg路径动画)
本帖最后由 马黑黑 于 2025-9-1 20:59 编辑 <br /><br /><div class="codebox" data-prev="1"><style>
@import 'https://638183.freep.cn/638183/web/css/tz01.css';
#pa { --offsetX: 0px; --bg: url('https://638183.freep.cn/638183/t24/w5/ground.webp') no-repeat center/cover; --ma-size: 20%; }
#ma { background: url('https://638183.freep.cn/638183/web/svg/sunfl-2.svg') no-repeat center/cover; }
#btnFs { right: 30px; bottom: 30px; color: lightblue; border-color: currentColor!important; }
#svg use { opacity: 1; animation: flash linear 1s var(--delay) infinite alternate var(--state); }
@keyframes flash { to { opacity: 0.5; } }
</style>
<div id="pa">
<audio id="aud" src="https://music.163.com/song/media/outer/url?id=33469659" autoplay loop></audio>
<video class="pd-vid" src="https://img.tukuppt.com/video_show/2629112/00/02/03/5b4f3c0b41744.mp4" autoplay loop muted></video>
<div id="ma" class="brightness"></div>
<svg id="svg" width="100%" height="100%" viewBox="0 00 1600 900">
<defs>
<g id="svgShape" fill="white">
<circle cx="0" cy="0" r="10" stroke-width="0" />
<path d="M0 0 H0 20" stroke-width="3" />
</g>
<path id="motionPath" d="M0 900 Q1500 640,1600 0" />
</defs>
</svg>
</div>
<script type="module">
import { FS } from 'https://638183.freep.cn/638183/web/js/fullscreen.js';
FS(pa,ma);
const createSvgElement = (element, attributes) => {
const elm = document.createElementNS('http://www.w3.org/2000/svg', element);
attributes.forEach(item => elm.setAttribute(item,item));
return elm;
};
const total = 20, fragment = document.createDocumentFragment();
Array.from({length: total}).forEach((_,key) => {
const size = (Math.random() + 0.8).toFixed(2);
const color = '#' + Math.random().toString(16).substring(2,8);
const use = createSvgElement('use', [
['href', '#svgShape'],
['x', 0],
['y', Math.random() * 200 - 150],
['style', `--delay: ${Math.random() * -4}s; transform: scale(${size}); fill: ${color}; stroke: ${color};`]
]);
const motion = createSvgElement('animateMotion', [
['dur', Math.random() * 10 + 10],
['begin', Math.random() - 20],
['repeatCount', 'indefinite'],
['rotate', 'auto']
]);
const mpath = createSvgElement('mpath',[
['href', '#motionPath']
]);
motion.appendChild(mpath);
use.appendChild(motion);
fragment.appendChild(use);
});
svg.appendChild(fragment);
aud.onplaying = aud.onpause = () => aud.paused ? svg.pauseAnimations() : svg.unpauseAnimations();
</script>
</div>
<script type="module">
import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
linenumber();
</script> 这是满天飞舞的棒棒糖么。{:4_173:}好久没来,四处逛逛先。。一会来看代码 svg路径动画即为 animateMotion 动画。此动画需要一个路径,其实就是后来CSS3接纳的 offset-path + offset-diatance 动画。
在 CSS3 的 offset-path 属性中,如果所使用的路径函数不支持百分比,那意味着路径是绝对路径,运动路径不能适配帖子容器的尺寸(包含动态变化的尺寸),这时候就需要 svg 的 animateMotion 来满足自适应帖子容器尺寸的需要。
本帖的设计:
(一)需要创建一个SVG标签,该标签作为帖子容器的子元素存在,宽高均设为帖子容器的 100%,且,非常重要的,应设置一个 viewBox 属性,该属性的值取决于帖子容器的宽高比例,例如上例的16比9的规格;
(二)SVG标签的子元素全部置于 defs 标签内,共两个内容:其一,用 <g> 分组标签创建运动粒子的形状,可以简单可以复杂;其二,创建一个运动路径标签 <path>,基于svg标签的 viewBox 所规定的宽高范围进行设计。注意 g 和 path 标签都有 id,便于 JS 的处理;
(三)如果希望自定义粒子的颜色,可以给 <g> 标签或 <g> 标签内的元素加上 fill 和 stroke 颜色属性,否则,JS会给它们一个随机颜色(事实上JS都给它们随机颜色,但事先设置了 fill 和 stroke 的话JS通过 style 属性为 use 引用所设置的颜色无效);
(四)JS代码中,基于 svg 的处理主要是按照 animateMotion 动画规范设计动画,通过实例化(use)标签加以实现。 本测试还给 use 标签设计了一个 CSS 动画,它不再 JS 的主要处理范畴,但JS给它提供一个 --delay 变量值 粒子是个圆和小线段一起组成而成的。。。
随机出现,从左下角到右上角,
大小随机,位置随机。。
还设置了闪呀闪的效果,
这么多效果集合在一起,感觉这算力大大超出了凡人认知范围。。{:4_173:} 花飞飞 发表于 2025-9-1 21:17
粒子是个圆和小线段一起组成而成的。。。
随机出现,从左下角到右上角,
大小随机,位置随机。。
动画分层面:闪烁是CSS关键帧动画(容易理解),沿路径运动是SVG动画(较难理解) 画面又简洁又清爽,用的是今天实例的背景,
实例是白色小球旋转,这个是粒子周边飞舞
那个实例中间的小播是代码写的图案,这个是SVG图片。。
感觉大不相同啊。。我再去瞅瞅。 花飞飞 发表于 2025-9-1 20:41
这是满天飞舞的棒棒糖么。好久没来,四处逛逛先。。一会来看代码
这是坦克{:4_196:} 花飞飞 发表于 2025-9-1 21:22
画面又简洁又清爽,用的是今天实例的背景,
实例是白色小球旋转,这个是粒子周边飞舞
那个实例中间的小播 ...
两者实现手段不一样 马黑黑 发表于 2025-9-1 21:22
动画分层面:闪烁是CSS关键帧动画(容易理解),沿路径运动是SVG动画(较难理解)
d="M0 900 Q1500 640,1600 0"这个路径起点0 900,左下角,终点是1600 0..中间那个是控制点。。
能让这么多粒子随着这个路径随意出现,这才是计算的厉害之处。
const size = (Math.random() + 0.8).toFixed(2); 这句保证了大小随机。。从取0和1的话,结果就是0.8-1.8的大小
const color = '#' + Math.random().toString(16).substring(2,8);这句颜色随机也比较容易看出来。。
花飞飞 发表于 2025-9-1 21:27
d="M0 900 Q1500 640,1600 0"这个路径起点0 900,左下角,终点是1600 0..中间那个是控制点。。
能让这么 ...
特别需要注意的是svg的 viewBox 设计,路径 d 属性依据它 最难看出来的是位置怎么 设的可以这么满天飞舞。。
20个粒子不是整齐划一的哦,而是出现有延迟,过程有闪烁,
位置也有错落。。
这指挥的粒子简直是太听话了。。没有一个乱跑的。{:4_170:}
我再看看哪句管的 这些粒子是小扇子么,这形状设置得有趣。{:4_173:} 花飞飞 发表于 2025-9-1 21:30
最难看出来的是位置怎么 设的可以这么满天飞舞。。
20个粒子不是整齐划一的哦,而是出现有延迟,过程有闪 ...
综合运作的效果:
(一)animateMotion 的相关属性有 dur(动画时长)、begin(何时开始),它们取值都是随机的,时长关快慢,开始时间管先后(用的是负值,提前运行);
(二)实例化 use 标签为粒子的最终形态,除了大小,还有位置,关位置的是 x、y,x 都设为0,y 则错开一定范围,这样它们在主线上的运动在y方向则是错开那么一点点距离的。 红影 发表于 2025-9-1 21:32
这些粒子是小扇子么,这形状设置得有趣。
这是小坦克,无人坦克 ['x', 0],
['y', Math.random() * 200 - 150],这个Y轴的数据随机啊。。就是可以左右乱偏的,取0和1的话,偏移在-150和50之间,那就可以理解为啥可以错落了。。
['style', `--delay: ${Math.random() * -4}s; transform: scale(${size}); fill: ${color}; stroke: ${color};`]
这句好复杂。。延迟4秒,大小取上面的随机值 ,填充和边框也取随机色。。。(不过也有说明这随机色失效了)
五体投地,佩服。。
这么复杂的东东怎么想出来的。。 马黑黑 发表于 2025-9-1 20:54
本测试还给 use 标签设计了一个 CSS 动画,它不再 JS 的主要处理范畴,但JS给它提供一个 --delay 变量值
这个动画是明暗变化的动画吧。
<svg id="svg" width="100%" height="100%" viewBox="0 00 1600 900">这个整个在背景范围里啊。
这个js设计感觉有点复杂,很多看着都觉得似是而非,前面学的又都忘记了{:4_173:} 花飞飞 发表于 2025-9-1 21:37
['x', 0],
['y', Math.random() * 200 - 150],这个Y轴的数据随机啊。。就是可以左右乱偏的,取0和1的话, ...
懂的用材料和工具,产品就可以生产出来 马黑黑 发表于 2025-9-1 21:36
综合运作的效果:
(一)animateMotion 的相关属性有 dur(动画时长)、begin(何时开始),它们取值 ...
给跪了,这神仙算法,感觉我能看出一丢丢,CPU就快烧坏了。。。{:4_170:} 马黑黑 发表于 2025-9-1 21:22
这是坦克
{:4_170:}小猪猪你设计这么可爱的小坦克,没满月就出来营业了,仔细看还真是的。。。吃一个。。