所以我得到了这个已经在svg中包含动画的SVG,现在我的问题是如何将鼠标悬停在svg图标上时启动动画,svg已经为每个移动的部分提供了id。
当我将鼠标悬停在svg之外时,如何将其重置?
<?xml version="1.0" encoding="utf-8"?>
<svg id="family" image-rendering="auto" baseProfile="basic"
version="1.1" x="0px" y="0px" width="550" height="550"
提供svg本身: https://codepen.io/Zeruw/pen/MpLRqR
Codepen项目: https://codepen.io/Zeruw/project/editor/DVeMEA/
在项目中你可以看到当你将鼠标悬停在按钮上时它变成橙色并且svg开始旋转而不是我想要的方式,我希望它首先冻结,一旦你将鼠标悬停在按钮上它就会播放给出的动画在SVG里面。
答案 0 :(得分:1)
原则上,可以修改svg文件中的SVG / SMIL动画,使它们按照您希望的方式工作,而不需要使用CSS动画。
不幸的是,这些动画的编写方式非常复杂。每组有四个附加动画使用了20个关键帧。由于它们都属于animateTransform
类型,因此可以将它们作为矩阵产品写入每组的单个动画中。对每个关键帧进行数学计算会得到一个明显的结果:它都是transform="rotate(a, cx, cy)"
,具有恒定的旋转中心cx, cy
。而且运动的节奏非常均匀,以至于所有这些关键帧都是完全不必要的。
<g id="fatherHead" transform="translate(96.35 53.15)">
<animateTransform attributeName="transform" additive="replace" type="translate" dur="0.833s"
keyTimes="0;.05;.1;.15;.2;.25;.3;.35;.4;.45;.5;.55;.6;.65;.7;.75;.8;.85;.9;.95;1"
values="176.15,157.45;177.453,158.333;178.648,159.103;179.935,159.911;181.104,160.629;182.261,161.481;183.449,162.199;184.632,162.963;185.711,163.599;186.819,164.308;187.877,165.004;188.916,165.684;189.935,166.338;190.916,166.98;191.921,167.646;192.837,168.282;193.689,168.829;194.633,169.49;195.482,169.967;196.37,170.569;196.37,170.569"
fill="freeze"/>
<animateTransform attributeName="transform" additive="sum" type="rotate" dur="0.833s"
keyTimes="0;.05;.1;.15;.2;.25;.3;.35;.4;.45;.5;.55;.6;.65;.7;.75;.8;.85;.9;.95;1"
values="0,0,0;.78,0,0;1.558,0,0;2.52,0,0;3.291,0,0;4.056,0,0;5.007,0,0;5.765,0,0;6.52,0,0;7.27,0,0;8.019,0,0;8.762,0,0;9.315,0,0;10.051,0,0;10.782,0,0;11.511,0,0;12.048,0,0;12.766,0,0;13.297,0,0;14,0,0;14,0,0"
fill="freeze"/>
<animateTransform attributeName="transform" additive="sum" type="scale" dur="0.833s" keyTimes="0;.25;.3;1"
values="1,1;1,1;1,.999;1,.999" fill="freeze"/>
<animateTransform attributeName="transform" additive="sum" type="translate" dur="0.833s"
keyTimes="0;.05;.1;.15;.2;.25;.3;.35;.4;.45;.5;.55;.6;.65;.7;.75;.8;.85;.9;.95;1"
values="-79.8,-104.3;-79.85,-104.4;-79.8,-104.4;-79.9,-104.4;-79.85,-104.35;-79.8,-104.35;-79.85,-104.4;-79.9,-104.4;-79.9,-104.3;-79.85,-104.35;-79.9,-104.3;-79.9,-104.35;-79.9,-104.3;-79.9,-104.3;-79.9,-104.4;-79.85,-104.4;-79.85,-104.35;-79.85,-104.4;-79.85,-104.35;-79.8,-104.35;-79.8,-104.35"
fill="freeze"/>
<path d="..." />
</g>
因此可以归结为
<g id="fatherHead" transform="translate(96.35 53.15)">
<animateTransform attributeName="transform" additive="sum"
type="rotate" dur="0.833s"
from="0,36.691,193.224" to="14,36.691,193.224"
fill="freeze"/>
<path d="..." />
</g>
对于下一步,您可以利用动画可以由任何元素上的事件启动的事实。当鼠标悬停在最外层元素Scene-1r1
上时,可以启动动画,但这有一个问题:悬停将被解释为过度填充区域,线条之间的所有内容都是&#34; out&#34 ;。解决方案是捕获覆盖矩形,其大小与图像viewBox的大小相同:
<rect id="mask" x="0px" y="0px" width="550" height="550" opacity="0"/>
将其插入最顶层元素; opacity="0"
使其隐身但可以恢复。
现在,动画可以获取属性begin="mask.mouseover"
:
<g id="fatherHead" transform="translate(96.35 53.15)">
<animateTransform attributeName="transform" additive="sum"
type="rotate" dur="0.833s" begin="mask.mouseover"
from="0,36.691,193.224" to="14,36.691,193.224"
fill="freeze"/>
<path d="..." />
</g>
你可以说,此时问题已经解决了。但是当你再次将鼠标移出时会发生什么?它不是很漂亮。
如果您想让头部在悬停时只移动一次而不再移动,只需添加一个属性restart="never"
。
如果您希望将受控转换回原始位置,可以通过撤消mouseout
上的转换来完成此操作。添加这些转换会导致错误行为,但可以通过稍微不同的结构来纠正:
<g id="fatherHead" transform="translate(96.35 53.15)">
<g>
<animateTransform attributeName="transform" additive="replace"
type="rotate" dur="0.833s" begin="bg.mouseover"
from="0,36.691,193.224" to="14,36.691,193.224"
fill="freeze"/>
<animateTransform attributeName="transform" additive="replace"
type="rotate" dur="0.1s" begin="bg.mouseout"
from="14,36.691,193.224" to="0,36.691,193.224"
fill="freeze"/>
<path d="..." />
</g>
</g>
现在,当鼠标离开图像时,磁头会移回原来的位置。