马黑黑 发表于 2024-11-12 11:51

svgdr教程·动画

<style>
        .art > p { margin: 12px 0; font: normal 18px/24px sans-serif; }
        .art mark { padding: 2px 6px; background: lightblue; }
        .art svg { outline: 1px solid silver; }
        .tRed { color: red; }
</style>

<div class="art">
        <h2>动画</h2>
        <p>指令:<mark>animate()</mark>
        <p>参数:<mark>name, options</mark>
        <p>语法:<mark>animate(name, options)</mark>
        <p>注意: 本指令返回上文对象,即要运行动画的元素</p>
        <p>参数解释:</p>
        <blockquote>
                ① name - SVG动画名称,必须,共四种:set、animate、animateMotion、animateTransform<br>
                ② options - 动画属性键值对数据集合,以键值对方式组织,例:{ attributeName: 'transfrom', begin: '0s', ... }
                * 凡以 {...} 组织键值对数据,健名若出现短横线(例如 stroke-width)的,均应使用小角单或双引号包裹,这是JS相关规则
        </blockquote>
        <p>下面对四种动画进行演示:</p>

        <p>(一)set 动画 : 为元素的任何属性设定简易动画,效果类似于CSS的<mark>:hover</mark>简单交互</p>
        <div id="di1"><pre id="pr1">
//矩形
dr.rect(10,10,190,100,'gray');
dr.animate('set', {
        attributeName: 'fill', /* 填充色动画 */
        to: 'fuchsia',/* 变为紫红色 */
        dur: '1s',/* 变化过程时长 */
        begin: '2s; click',/* 触发机制 :2秒后、单击 */
});
//圆 :参照矩形理解动画各参数含义
dr.circle(300,60, 40, 'teal').animate('set', {
        attributeName: 'cx',
        to: 750,
        dur: '1s',
        begin: '2s; click',
});
        </pre></div>
        <p>效果演示(打开2秒后运行动画,或单击图像触发动画):</p>
        <svg id="svg1" width="800" height="120"></svg>
        <p>svgdr绘制指令生成的SVG代码:
        <div id="di2"><pre id="pr2"></pre></div>

        <p>(二)animate 动画 :set() 动画的成人版,提供完整的基于元素属性的可控动画,不包含transform形变动画(另开有动画体系)</p>
        <p>svgdr 绘制代码:</p>
        <div id="di3"><pre id="pr3">
dr.rect(10,10,190,100,'gray').animate('animate', {
        attributeName: 'fill',
        to: 'fuchsia',
        dur: '1s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive', /* 重启动画 :always | whenNotActive | never */
});
dr.circle(300, 60, 40, 'tan').animate('animate', {
        attributeName: 'cx',
        values: '300; 750; 300',
        dur: '2s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive',
});
        </pre></div>
        <p>效果(动画结束后可单击重启动画):</p>
        <svg id="svg2" width="800" height="120"></svg>
        <p>最终生成的SVG代码:</p>
        <div id="di4"><pre id="pr4"></pre></div>

        <p>(三)animateTransform 动画 :SVG transform 形变动画,包含 rotate、translate、scale 和 skew</p>
        <p>svgdr 绘制代码:</p>
        <div id="di5"><pre id="pr5">
dr.rect(40,40,100,100,'peru').animate('animateTransform', {
        attributeName: 'transform',/* 动画名称永远是 transform */
        type: 'rotate',/* 动画类型 : translate | rotate | scale | skew */
        from: '0 90 90',/* 旋转原点 :x + width / 2, y + height / 2*/
        to: '360 90 90',
        dur: '3s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive',
});
dr.circle(260, 90, 50, 'peru').animate('animateTransform', {
        attributeName: 'transform',
        type: 'translate',/* 平移 */
        values: '0; 480; 0', /* translate位移距离:从移动0开始,移动480px,再反向移动 */
        dur: '3s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive',
});
        </pre></div>
        <p>效果演示(动画若已停止可点击元素继续):</p>
        <svg id="svg3" width="800" height="180"></svg>
        <p>svgdr 绘制指令生成的SVG代码:</p>
        <div id="di6"><pre id="pr6"></pre></div>

        <p>(四)animateMotion 动画 :路径动画,设置元素沿路径运动</p>
        <p>一个简单的实例效果(动画停止后单击元素重启动画):</p>
        <svg id="svg4" width="800" height="400"></svg>
        <p>svgdr 绘制指令:</p>
        <div id="di7"><pre id="pr7">
//路径 M 指令规定了元素运动起点,元素实际运动时会受到元素初始位置的影响
dr.rect(0,0,30,20,'peru').animate('animateMotion', {
        path: 'M100 100 V320 H400 L200 200 H520 V20 H750 V320',/* 路径 */
        dur: '10s',
        begin: '2s;click',
        fill: 'freeze',/* 结束时保持的状态freeze | remove(缺省默认) */
        restart: 'whenNotActive',
        rotate: 'auto', /* 元素是否按路基走向调整自己的朝向 auto | auto-reverse | 角度数值 */
});
        </pre></div>
        <p>svgdr生成的SVG代码:</p>
        <div id="di8"><pre id="pr8"></pre></div>
        <p>【说明】animateMotion 路径动画还有一个子标签 mpath 用以取代动画属性 path,svgdr 尚未实现,敬请期待。</p>
        <p>本节的内容,因篇幅关系,未能详细介绍svg动画全方位知识,对svg动画感兴趣的朋友可以查询相关资料进行学习研究并在svgdr中灵活应用。</p>
       
        <p><a href="/forum.php?mod=viewthread&tid=79137&extra=page%3D1" targete="_blank">返回目录</a></p>
</div>

<script type="module">
import hl from 'https://638183.freep.cn/638183/web/mod/helight.js';
import draw from 'https://638183.freep.cn/638183/web/mod/svgdr.js';

var dr1 = draw.dr('svg1');
dr1.rect(10,10,190,100,'gray');
dr1.animate('set', {
        attributeName: 'fill',
        to: 'fuchsia',
        dur: '1s',
        begin: '2s; click',
});
dr1.circle(300,60, 40, 'teal').animate('set', {
        attributeName: 'cx',
        to: 750,
        dur: '1s',
        begin: '2s; click',
});
pr2.textContent = dr1.code(svg1);

var dr2 = draw.dr(svg2);
dr2.rect(10,10,190,100,'gray').animate('animate', {
        attributeName: 'fill',
        to: 'fuchsia',
        dur: '1s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive',
});
dr2.circle(300, 60, 40, 'tan').animate('animate', {
        attributeName: 'cx',
        values: '300; 750; 300',
        dur: '2s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive',
});
pr4.textContent = dr2.code(svg2);

var dr3 = draw.dr(svg3);
dr3.rect(40,40,100,100,'peru').animate('animateTransform', {
        attributeName: 'transform',
        type: 'rotate',
        from: '0 90 90',
        to: '360 90 90',
        dur: '3s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive',
});
dr3.circle(260, 90, 50, 'peru').animate('animateTransform', {
        attributeName: 'transform',
        type: 'translate',
        values: '0; 480; 0',
        dur: '3s',
        begin: '2s; click',
        repeatCount: 10,
        restart: 'whenNotActive',
});
pr6.textContent = dr3.code(svg3);

var dr4 = draw.dr(svg4);
dr4.rect(0,0,30,20,'peru').animate('animateMotion', {
        path: 'M100 100 V320 H400 L200 200 H520 V20 H750 V320',
        dur: '10s',
        begin: '2s;click',
        fill: 'freeze',
        restart: 'whenNotActive',
        rotate: 'auto',
});
pr8.textContent = dr4.code(svg4);

hl.hl(di1, pr1);
hl.hl(di2, pr2);
hl.hl(di3, pr3);
hl.hl(di4, pr4);
hl.hl(di5, pr5);
hl.hl(di6, pr6);
hl.hl(di7, pr7);
hl.hl(di8, pr8);

</script>

愤怒的葡萄 发表于 2024-11-12 13:16

感谢马版的教程分享,学习了。

梦江南 发表于 2024-11-12 13:44

问老师这个路径动画很趣,如果把(四)animateMotion 动画 :路径动画,设置元素沿路径运动,要想把四的路径设置成鱼儿在游哪怎么去变成一条鱼?

冬天的雨 发表于 2024-11-12 18:23

问好马老师{:4_187:}

红影 发表于 2024-11-12 19:28

四种动画放在一起讲,便于比较和记忆,真好,谢谢黑黑的耐心讲解{:4_187:}

红影 发表于 2024-11-12 19:35

前两个是针对元素的,必须有名称,第三个是固定名称,最后一个好像没名称?

红影 发表于 2024-11-12 19:36

这个好,已经很全了。这个需要好好学一下{:4_187:}

泡沫 发表于 2024-11-12 19:37

原来动画可以区分得这么详细,每一种都共同点又有区别之处。。
最意外的是set 动画,我记得它用来添加设置属性的,摇身一变可以变动态了。。
身兼多职啊这是。。{:4_170:}

泡沫 发表于 2024-11-12 19:40

对其中的重启动画比较感兴趣,想看演示就再来一遍呗。。。
rotate、translate、scale 和 skew这几种形变动画比较面熟,之前经常见到。。

泡沫 发表于 2024-11-12 19:44

最后沿路径的动画,多了一个fill: 'freeze', 保留最终形态,如果缺省,则回到起点。。这个也是新的。
看的时候还好奇,这个小长方形块状为啥可以按路径方向调整自己的方向,原来是rotate: 'auto'这一句在起作用。。
这个路径设横走,竖走,斜走,应该也是为了看清方向变化吧。。{:4_174:}

马黑黑 发表于 2024-11-12 21:49

泡沫 发表于 2024-11-12 19:44
最后沿路径的动画,多了一个fill: 'freeze', 保留最终形态,如果缺省,则回到起点。。这个也是新的。
看的 ...

是的,为了不一路向北{:4_170:}

泡沫 发表于 2024-11-13 11:26

马黑黑 发表于 2024-11-12 21:49
是的,为了不一路向北

同意
现在大可不必,因为一路向北可冷了。。{:4_173:}
暖气和空调还是选择开空调

马黑黑 发表于 2024-11-13 12:25

泡沫 发表于 2024-11-13 11:26
同意
现在大可不必,因为一路向北可冷了。。
暖气和空调还是选择开空调

就这么定了

泡沫 发表于 2024-11-13 19:40

马黑黑 发表于 2024-11-13 12:25
就这么定了

定个也不是难事儿{:4_170:}
页: [1]
查看完整版本: svgdr教程·动画