html - 使用 svg 每隔几秒移动一次对象
问题描述
绘制(一次)并每五秒钟移动一次对象,如图从左到右所示。我搜索但无法找到一种方法来绘制外线并将对象移近它。
<animate xlink:href="#blue-rectangle"
attributeName="x"
from="50"
to="425"
dur="5s"
begin="circ-anim.repeat(2)"
fill="freeze"
id="rect-anim" />
参考:https ://css-tricks.com/guide-svg-animations-smil/
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Basic_Shapes
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animateMotion
解决方案
使用animateMotion
将是路径上连续运动的解决方案。如果您需要每隔一段时间停止移动,我会使用 javascript。在这本书:将 SVG 与 CSS3 和 HTML5 结合使用:Web 设计的矢量图形,您可以全面了解如何使用 javascript 进行模拟animateMotion
为了停止矩形,我使用 requestAnimationFrame 回调的时间戳。在下一个示例中,我每 2 秒停止一次矩形,持续 1 秒。
由于时间戳连续运行,我需要一种方法来记录它停止的时刻,以便我可以从这里恢复动画。为此,我将其设置lastTime
为矩形停止的最后一次。
请阅读我的代码中的注释。
let rid;//the request animation frame id
let track = document.getElementById("track"),
trackLength = track.getTotalLength(),//the total length of the track
dur = 15000; //duration of one loop of track, in ms
let lastTime = 0;//last time when the rect has stopped
let flag = false;
let interval = 5000;
function update(time) {
rid = requestAnimationFrame(update);
// to stop the rect every 5 seconds
var deltaT = time%interval;
//during 1 second
if (deltaT < interval/2){
flag = false;
var t = ((deltaT + lastTime) % dur) / dur, // position in repeat cycle
distance, // distance along the path for this rect
point, // SVGPoint for that distance
point2; // SVGPoint for a slightly different distance
distance = trackLength * (t % 1);
point = track.getPointAtLength(distance);
point2 = track.getPointAtLength((distance + 2) % trackLength);
angle = Math.atan2(point.y - point2.y, point.x - point2.x);
rect.setAttribute(
"transform",
"translate(" +
[point.x, point.y] +
")" +
"rotate(" +
angle * 180 / Math.PI +
")"
);
}else{if(flag==false){lastTime += interval/2; flag = true;}}
}
rid = requestAnimationFrame(update);
svg{border:1px solid;}
path{fill:none; stroke:black;}
<svg viewBox = "0 0 150 200" width="200">
<path id="track" d="M70,30 Q70,20 80,20L120,20 Q130,20 130,30L130,170.000 Q130,180 120,180L30,180 Q20,180 20,170L20,130 Q20,120 30,120L60,120 Q70,120 70,110Z" />
<polygon id="rect" points="0,0 -10,0 -10,-10 0,-10 0,0" style="fill: #ff0000;"/>
</svg>
更新
这就是我将如何使用animateMotion
setInterval(()=>{ svg.pauseAnimations();
setTimeout(()=>{svg.unpauseAnimations()},1000)
},2000);
svg{border:1px solid;}
path{fill:none; stroke:black;}
<svg id="svg" viewBox = "0 0 150 200" width="300">
<path id="track" d="M70,30 Q70,20 80,20L120,20 Q130,20 130,30L130,170.000 Q130,180 120,180L30,180 Q20,180 20,170L20,130 Q20,120 30,120L60,120 Q70,120 70,110Z" />
<polygon id="rect" points="0,0 10,0 10,10 0,10 0,0" style="fill: #ff0000;">
<animateMotion id="test" begin= "0s" dur="15s" repeatCount="infinite" rotate="auto" fill="freeze">
<mpath xlink:href= "#track" />
</animateMotion></polygon>
</svg>
更新 2
这是在路径上移动 5 个方块的方法: 唯一的区别begin
是animateMotion
.
所有
setInterval(()=>{ svg.pauseAnimations();
setTimeout(()=>{svg.unpauseAnimations()},1500)
},3000);
svg{border:1px solid;}
path{fill:none; stroke:black;}
<svg id="svg" viewBox = "30 0 360 450" width="300">
<defs>
<polygon id="theRect" points="0,0 20,0 20,20 0,20 0,0" style="fill: #ff0000;" />
</defs>
<path id="track" d="M288.938,33 Q289,12 310,12L350,12 Q371,12 371,33L371,408 Q371,429 350,429L66,429 Q45,429 45,408L45,374 Q45,353 66,353L267,353 Q288,353 288.062,332Z" />
<use xlink:href="#theRect">
<animateMotion id="test" begin= "0s" dur="15s" repeatCount="infinite" rotate="auto" fill="freeze" >
<mpath xlink:href= "#track" />
</animateMotion></use>
<use xlink:href="#theRect">
<animateMotion id="test" begin= "-.5s" dur="15s" repeatCount="infinite" rotate="auto" fill="freeze" >
<mpath xlink:href= "#track" />
</animateMotion></use>
<use xlink:href="#theRect">
<animateMotion id="test" begin= "-1s" dur="15s" repeatCount="infinite" rotate="auto" fill="freeze" >
<mpath xlink:href= "#track" />
</animateMotion></use>
<use xlink:href="#theRect">
<animateMotion id="test" begin= "-1.5s" dur="15s" repeatCount="infinite" rotate="auto" fill="freeze" >
<mpath xlink:href= "#track" />
</animateMotion></use>
<use xlink:href="#theRect">
<animateMotion id="test" begin= "-2s" dur="15s" repeatCount="infinite" rotate="auto" fill="freeze" >
<mpath xlink:href= "#track" />
</animateMotion></use>
</svg>
推荐阅读
- reactjs - React.JS - 功能组件中的普通函数或箭头函数
- sql - 使用 BigQuery SQL 计算同一 ID 的所有列值的模式
- oop - 如何在 Dart 中复制对象,但不引用位置?
- azure-vm - Azure SQL VM 和我们手动安装 SQL Server 的 Azure VM 有什么区别
- assembly - 在 NASM 结构中搜索
- python - 使用 Python 将 datetime64 转换为整数小时
- assembly - 为什么 Visual Studio 编译器使用“mov esp,ebp”/“pop ebp”而不是“leave”?
- sql - 使用列表中的元素设置 SQL WHERE 值
- python - 用于 2D ALE 图的 Python PyALE 函数的值错误
- api - 如何仅通过 API 调用在 Rasa 中成功训练和替换模型?