javascript - 通过动态生成在屏幕上和屏幕外为 SVG 对象设置动画
问题描述
我正在尝试使用我拥有的 SVG 对象创建动画,单行中的每个单独的 SVG 矩形以向上或向下滚动的方式进行动画处理。我正在努力寻找学习如何做到这一点的资源以及实际实现此功能的最佳方法。
我想我还需要动态生成元素,以便在矩形中永远不会有间隙作为出口和进入屏幕。
我到目前为止的代码:
<div class="hero--wrapper">
<div class="hero--inner">
<div class="page--center">
<div class="svg-rect--el">
<svg xmlns="http://www.w3.org/2000/svg" width="688.571" height="1226.457" viewBox="0 0 688.571 1226.457" preserveAspectRatio="none">
<defs>
<style>
.cls-1 {
fill: #38324d;
}
.cls-2 {
fill: #42cc7f;
}
.cls-3 {
fill: #937ce3;
}
</style>
</defs>
<g id="Group_1" data-name="Group 1" transform="translate(-1009.907 83.176)">
<rect id="Rectangle_16" data-name="Rectangle 16" class="cls-1" width="89" height="32" rx="4" transform="translate(1233.124 669.715) rotate(-64)"/>
<rect id="Rectangle_22" data-name="Rectangle 22" class="cls-1" width="89" height="32" rx="4" transform="translate(1256.124 728.715) rotate(-64)"/>
<rect id="Rectangle_35" data-name="Rectangle 35" class="cls-1" width="89" height="32" rx="4" transform="translate(1317.124 707.715) rotate(-64)"/>
<rect id="Rectangle_8" data-name="Rectangle 8" class="cls-2" width="89" height="32" rx="4" transform="translate(1412.715 302.144) rotate(-64)"/>
<rect id="Rectangle_26" data-name="Rectangle 26" class="cls-2" width="89" height="32" rx="4" transform="translate(1435.715 361.144) rotate(-64)"/>
<rect id="Rectangle_39" data-name="Rectangle 39" class="cls-1" width="89" height="32" rx="4" transform="translate(1496.715 340.144) rotate(-64)"/>
<rect id="Rectangle_10" data-name="Rectangle 10" class="cls-1" width="89" height="32" rx="4" transform="translate(1054.522 1037.148) rotate(-64)"/>
<rect id="Rectangle_19" data-name="Rectangle 19" class="cls-1" width="89" height="32" rx="4" transform="translate(1077.522 1096.148) rotate(-64)"/>
<rect id="Rectangle_32" data-name="Rectangle 32" class="cls-2" width="89" height="32" rx="4" transform="translate(1138.522 1075.148) rotate(-64)"/>
<rect id="Rectangle_4" data-name="Rectangle 4" class="cls-3" width="89" height="32" rx="4" transform="translate(1502.086 118.923) rotate(-64)"/>
<rect id="Rectangle_28" data-name="Rectangle 28" class="cls-3" width="89" height="32" rx="4" transform="translate(1525.086 177.923) rotate(-64)"/>
<rect id="Rectangle_41" data-name="Rectangle 41" class="cls-3" width="89" height="32" rx="4" transform="translate(1586.086 156.923) rotate(-64)"/>
<rect id="Rectangle_14" data-name="Rectangle 14" class="cls-3" width="89" height="32" rx="4" transform="translate(1143.893 853.927) rotate(-64)"/>
<rect id="Rectangle_17" data-name="Rectangle 17" class="cls-3" width="89" height="32" rx="4" transform="translate(1166.893 912.927) rotate(-64)"/>
<rect id="Rectangle_30" data-name="Rectangle 30" class="cls-3" width="89" height="32" rx="4" transform="translate(1227.893 891.927) rotate(-64)"/>
<rect id="Rectangle_5" data-name="Rectangle 5" class="cls-1" width="89" height="32" rx="4" transform="translate(1323.484 486.355) rotate(-64)"/>
<rect id="Rectangle_24" data-name="Rectangle 24" class="cls-1" width="89" height="32" rx="4" transform="translate(1346.484 545.355) rotate(-64)"/>
<rect id="Rectangle_37" data-name="Rectangle 37" class="cls-3" width="89" height="32" rx="4" transform="translate(1407.484 524.355) rotate(-64)"/>
<rect id="Rectangle_2" data-name="Rectangle 2" class="cls-2" width="89" height="32" rx="4" transform="translate(1546.701 26.817) rotate(-64)"/>
<rect id="Rectangle_29" data-name="Rectangle 29" class="cls-1" width="89" height="32" rx="4" transform="translate(1569.701 85.817) rotate(-64)"/>
<rect id="Rectangle_43" data-name="Rectangle 43" class="cls-2" width="89" height="32" rx="4" transform="translate(1614.701 -3.183) rotate(-64)"/>
<rect id="Rectangle_42" data-name="Rectangle 42" class="cls-3" width="89" height="32" rx="4" transform="translate(1630.701 64.817) rotate(-64)"/>
<rect id="Rectangle_15" data-name="Rectangle 15" class="cls-2" width="89" height="32" rx="4" transform="translate(1188.508 761.821) rotate(-64)"/>
<rect id="Rectangle_20" data-name="Rectangle 20" class="cls-1" width="89" height="32" rx="4" transform="translate(1211.508 820.821) rotate(-64)"/>
<rect id="Rectangle_33" data-name="Rectangle 33" class="cls-2" width="89" height="32" rx="4" transform="translate(1272.508 799.821) rotate(-64)"/>
<rect id="Rectangle_6" data-name="Rectangle 6" class="cls-3" width="89" height="32" rx="4" transform="translate(1368.1 394.249) rotate(-64)"/>
<rect id="Rectangle_25" data-name="Rectangle 25" class="cls-3" width="89" height="32" rx="4" transform="translate(1391.1 453.249) rotate(-64)"/>
<rect id="Rectangle_38" data-name="Rectangle 38" class="cls-3" width="89" height="32" rx="4" transform="translate(1452.1 432.249) rotate(-64)"/>
<rect id="Rectangle_3" data-name="Rectangle 3" class="cls-1" width="89" height="32" rx="4" transform="translate(1457.47 211.028) rotate(-64)"/>
<rect id="Rectangle_27" data-name="Rectangle 27" class="cls-3" width="89" height="32" rx="4" transform="translate(1480.47 270.028) rotate(-64)"/>
<rect id="Rectangle_40" data-name="Rectangle 40" class="cls-2" width="89" height="32" rx="4" transform="translate(1541.47 249.028) rotate(-64)"/>
<rect id="Rectangle_12" data-name="Rectangle 12" class="cls-2" width="89" height="32" rx="4" transform="translate(1099.277 946.032) rotate(-64)"/>
<rect id="Rectangle_18" data-name="Rectangle 18" class="cls-3" width="89" height="32" rx="4" transform="translate(1122.277 1005.032) rotate(-64)"/>
<rect id="Rectangle_31" data-name="Rectangle 31" class="cls-2" width="89" height="32" rx="4" transform="translate(1183.277 984.032) rotate(-64)"/>
<rect id="Rectangle_7" data-name="Rectangle 7" class="cls-3" width="89" height="32" rx="4" transform="translate(1278.869 578.461) rotate(-64)"/>
<rect id="Rectangle_23" data-name="Rectangle 23" class="cls-3" width="89" height="32" rx="4" transform="translate(1301.869 637.461) rotate(-64)"/>
<rect id="Rectangle_36" data-name="Rectangle 36" class="cls-2" width="89" height="32" rx="4" transform="translate(1362.869 616.461) rotate(-64)"/>
<rect id="Rectangle_9" data-name="Rectangle 9" class="cls-3" width="89" height="32" rx="4" transform="translate(1009.907 1129.253) rotate(-64)"/>
</g>
</svg>
</div>
</div>
</div>
</div>
/* Keyframes */
@keyframes slide {
from {
top: 0;
}
to {
top: 100%;
}
}
/* General Stying */
body {
margin: 0;
padding: 0;
}
.hero--wrapper .hero--inner {
max-height: 745px;
height: 745px;
overflow: hidden;
}
.page--center {
margin: 0 auto;
max-width: 1140px;
padding: 0 20px;
}
.hero--wrapper .hero--inner .svg-rect--el {
position: relative;
height: 100%;
width: 100%;
}
.hero--wrapper .hero--inner .svg-rect--el svg {
position: absolute;
top: 0;
bottom: 0;
right: 0;
}
.hero--wrapper .hero--inner .svg-rect--el svg rect {
animation: slide 10s linear infinite;
}
链接到jsfiddle
这不是很多,所以我很抱歉,但是,如果有人能指出我正确的方向,那将不胜感激。
谢谢 :)
解决方案
好主意!这是一种方法。此版本使用 SMIL 动画。反向运动有点小技巧,可能有更好的方法来实现它。
它的基本工作原理:我将矩形放置在 0,0 并将它们向右移动。我计算一个矩形需要多长时间才能移动它自己的长度(+两个矩形之间的空间),然后将动画的开始时间设置为与其位置相对应的负值,以便它在时间 0s 到达它的正确位置。
如果您有任何问题,请询问,我将修改答案以阐明其工作原理...希望对您有所帮助
var svgns = "http://www.w3.org/2000/svg"
function rect(w, h, c) {
var rect = document.createElementNS(svgns, "rect")
rect.setAttribute("width", w)
rect.setAttribute("height", h)
rect.setAttribute("class", c)
return rect
}
function animate(from, to, dur, begin) {
var anim = document.createElementNS(svgns, "animate")
anim.setAttribute("attributeName", "x")
anim.setAttribute("from", from)
anim.setAttribute("to", to)
anim.setAttribute("dur", dur)
anim.setAttribute("begin", begin)
anim.setAttribute("repeatCount", "indefinite")
return anim
}
function createRow(rectWidth, rectHeight, rectPadding, numRects, dur, classes) {
var g = document.createElementNS(svgns, "g")
var totalWidth = (rectWidth + rectPadding) * (numRects)
var distanceToTravel = (rectWidth + rectPadding) * (numRects)
var pixelPerSecond = distanceToTravel / dur
var durPerRect = (rectWidth + rectPadding) / pixelPerSecond
for (var i = 0; i < numRects; i++) {
var r = rect(rectWidth, rectHeight, classes[i % classes.length])
var a = animate(-(rectWidth + rectPadding), distanceToTravel, dur, -(i * durPerRect))
r.appendChild(a)
g.appendChild(r)
}
return g
}
row1.appendChild(createRow(89, 32, 5, 10, 17, ["c1", "c2", "c2", "c1", "c3"]))
row2.appendChild(createRow(89, 32, 5, 10, 13, ["c2", "c1", "c1", "c3", "c2"]))
row3.appendChild(createRow(89, 32, 5, 10, 11, ["c3", "c3", "c1", "c2", "c1"]))
rect {
rx: 5
}
.c1 {
fill: #38324d;
}
.c2 {
fill: #42cc7f;
}
.c3 {
fill: #937ce3;
}
<svg id="svg" width="300" height="200" viewBox="0 0 600 400">
<g transform="translate(200,0) rotate(-61, 300, 60) translate(-100,0)">
<g id="row1"/>
<g id="row2" transform="translate(0,40)"/>
</g>
<g transform="translate(200,0) rotate(119, 300, 110) translate(-100,0)">
<g id="row3" transform="translate(0,80)"/>
</g>
</svg>
推荐阅读
- vba - 在运行时通过 VBA 创建动态按钮
- python - 当我们用 pip 或 conda 安装 pytorch 时的几个问题?
- c++ - 内存泄漏线
- javascript - 为什么这个 jQuery AJAX 循环在数百次成功循环后失败并出现 400 错误?
- javascript - 如果用户在浏览器中使用不受支持的语言,如何在 React 的自定义函数中添加回退到某种语言
- ios - 如何快速下载 Pdf 文件并在文件管理器中查找
- php - 满足列的有效负载数据的laravel
- java - 有没有办法将这个接受整数对象集合并添加这些元素的迭代函数转换为递归函数?
- php - 如何使用数组在 PHP Mysqli 中获取结果
- algorithm - 3D 中的最小边界框算法