马黑黑 发表于 2024-9-12 12:31

js+svg绘制多重动画六边形

<style>
.artbox { position: relative; }
.artbox > p { position: relative; margin: 10px 0; font: normal 18px / 26px sans-serif; }
.artbox mark { color: black; background: lightblue; padding: 2px 4px; }
.textRed { color: red; }
.textMid { text-align: center; }
.showDiv { position: relative; display: grid; place-items: center; }
.artbox mark { background: lightblue; padding: 0 6px; }
#codebox { display: none; }
#text { width: 98%; height: 360px; padding: 8px; font-size: 16px; border: 3px solid lightblue; border-radius: 6px; resize: none; tab-size: 4; }
</style>

<div class="artbox">
        <p>在单个 <span class="textRed">svg path</span> 路径六边形动画基础上加以改进:① 每一个 <span class="textRed">path</span> 包裹之下的两个 <span class="textRed">animate</span> 动画,<span class="textRed">begin</span> 属性除第一组动画为 0s 即立即执行外,其余的动画均等上一个动画开始后加 1s 开始执行。② &lt;user&gt; 标签变为 <mark>6*6=36</mark> 个,6个一组,每一组对标一个路径;旋转分两种情形,1、3、5 按 <mark>60度*序号</mark> 获取角度值,2、4、6 按 <mark>60度*序号+30</mark> 获取角度值。以下是实现代码和演示效果、XML svg代码:</p>

<div class="hE"><pre id="code">
&lt;svg id="hsvg" width="320" height="320" viewBox="0 0 320 320" fill="none" stroke="#008000" stroke-linecap="round"&gt;&lt;/svg&gt;

&lt;script&gt;
drawHexagon = (total) =&gt; {
        let pathstr = '\n\t&lt;defs&gt;', usestr = '';
        Array(total).fill(0).forEach((id,idx) =&gt; {
                id = idx + 1;
                let bstr = idx === 0 ? '0s' : `p1.begin+${idx}s`;
                pathstr += `
                &lt;path id="r${id}"&gt;
                        &lt;animate id="p${id}" attributeName="d" values="m160,160l0,0 0,0;m130,110l30,-17 30,17;m130,60l30,-17 30,17;m160,20l0,0 0,0" dur="6s" repeatCount="indefinite" begin="${bstr}"/&gt;
                        &lt;animate attributeName="stroke-width" values="0;4;4;4;0" dur="6s" repeatCount="indefinite" begin="${bstr}"/&gt;
                &lt;/path&gt;`;
                Array(total).fill(0).forEach((u,k) =&gt; {
                        u = k + 1;
                        let angle = id % 2 === 0 ? 360 / total * k + 30 : 360 / total * k;
                        usestr += `\n\t&lt;use xlink:href="#r${id}" transform="rotate(${angle} 160 160)"&gt;&lt;/use&gt;`;
                });
        });
        pathstr += '\n\t&lt;/defs&gt;\n';
        return pathstr + usestr + '\n';
};

hsvg.innerHTML = drawHexagon(6);
&lt;/script&gt;
</pre></div>

        <p><button id="btn1" type="button" value="1">点击查看效果</button></p>
        <div id="sbox1" class="showDiv"></div>
        <div id="codebox">
                <p>XML代码:</p>
                <p><textarea id="text"></textarea></p>
        </div>
</div>

<script>
var sc = document.createElement('script');
sc.chartset = 'utf-8';
sc.src = 'https://638183.freep.cn/638183/web/js2024/helight.js';
document.body.appendChild(sc);

var runCodes = (str,ele) => {
        let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
        let js_str, html_str;
        if(str.match(reg) !== null) {
                js_str = str.match(reg);
                html_str = str.replace(js_str, '').trim();
                js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
        } else {
                js_str = '';
                html_str = str.trim();
        }
        ele.innerHTML = html_str;
        let myfunc = new Function(js_str);
        myfunc();
};

btn1.onclick = () => {
        runCodes(code.innerText, sbox1);
        btn1.disabled = true;
        text.value = sbox1.innerHTML;
        codebox.style.display = 'block';
}
</script>

梦江南 发表于 2024-9-12 13:27

谢谢老师分享!辛苦了!{:4_190:}

红影 发表于 2024-9-12 15:59

“除第一组动画为 0s 即立即执行外,其余的动画均等上一个动画开始后加 1s 开始执行”
这个还需要把时间算好,然后就变成连绵不绝的绽放了呢{:4_187:}

红影 发表于 2024-9-12 16:08

看帖子里,好像是全部画完了才开始旋转的,原来画这个动态图也需要点时间的。

红影 发表于 2024-9-12 16:17

let angle = id % 2 === 0 ? 360 / total * k + 30 : 360 / total * k;
简单地就分出了135和246{:4_173:}

马黑黑 发表于 2024-9-12 18:31

红影 发表于 2024-9-12 16:17
let angle = id % 2 === 0 ? 360 / total * k + 30 : 360 / total * k;
简单地就分出了135和246

公式是有必要的:万一改变了总数,不用去重新计算

马黑黑 发表于 2024-9-12 18:33

红影 发表于 2024-9-12 16:08
看帖子里,好像是全部画完了才开始旋转的,原来画这个动态图也需要点时间的。

不是酱紫理解的,这个绘制所需时间我们是感觉不到的。你的错觉原因是:线条粗细实际上开始时是0,看不见,它慢慢变大,达到一定程度才看见。然后线条粗细有往小里变。

红影 发表于 2024-9-12 20:18

马黑黑 发表于 2024-9-12 18:31
公式是有必要的:万一改变了总数,不用去重新计算

是的,这个无论总数多少,都直接判断了奇偶。

红影 发表于 2024-9-12 20:19

马黑黑 发表于 2024-9-12 18:33
不是酱紫理解的,这个绘制所需时间我们是感觉不到的。你的错觉原因是:线条粗细实际上开始时是0,看不见 ...

哦,原来是这样变化带来的错觉,还以为是绘制导致的{:4_173:}

马黑黑 发表于 2024-9-12 20:19

红影 发表于 2024-9-12 20:18
是的,这个无论总数多少,都直接判断了奇偶。

对的

马黑黑 发表于 2024-9-12 20:20

红影 发表于 2024-9-12 20:19
哦,原来是这样变化带来的错觉,还以为是绘制导致的

绘制这么简单的东东根本不需要时间

红影 发表于 2024-9-12 21:06

马黑黑 发表于 2024-9-12 20:19
对的

厉害了{:4_187:}

红影 发表于 2024-9-12 21:07

马黑黑 发表于 2024-9-12 20:20
绘制这么简单的东东根本不需要时间

就算需要,也是人感受不到的一刹那。

马黑黑 发表于 2024-9-12 22:14

红影 发表于 2024-9-12 21:07
就算需要,也是人感受不到的一刹那。

是的。

大数据运算会耗时间。比方说求素数,在四位数级别上完成,那会感觉不到花多少时间,但是,设定的范围越广,所花的时间就会感知得到,甚至会很漫长。当前,有很多计算机参与到求素数的行列中来,现在一年中可能也找不到下一个最大的素数。

红影 发表于 2024-9-13 10:40

马黑黑 发表于 2024-9-12 22:14
是的。

大数据运算会耗时间。比方说求素数,在四位数级别上完成,那会感觉不到花多少时间,但是,设定 ...

计算机速度那么快,在一年中都找不到下一个素数之最,这个浩渺得太无法想象了。
页: [1]
查看完整版本: js+svg绘制多重动画六边形