问题描述
查看 24 个精灵帧中弹跳圆的代码片段。
<text y='12'>n:0</text>
显示精灵帧
我怎样才能摆脱水平抖动的移动,是SVG还是CSS?
精灵帧越少偏移越小,每个精灵帧越多偏移越差
在 Chromium 中不太明显,在 FireFox 中更明显
我试过https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio
<style>
#bounce {
--w: 200px;
width: var(--w);
height: var(--w);
overflow: hidden;
display: inline-flex;
background: lightgreen;
}
img {
position: relative;
left: 0;
animation: moveX 1s steps(23) infinite;
}
@keyframes moveX {
to {
transform: translate(-100%);
left: 100%;
}
}
</style>
<div id="bounce"><img id=svgimg src="SVG injected here"></div>
<script>
window.onload = () => svgimg.src = `data:image/svg+xml,` + svg.innerHTML;
</script>
<template id=svg>
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 2400 100' height='200'>
<style>
ellipse {
fill: none;
stroke: green;
stroke-width: 5;
}
</style>
<g transform='translate(0 0)'>
<ellipse cx='50' cy='32' rx='30' ry='30'></ellipse><text y='12'>n:0</text>
</g>
<g transform='translate(100 0)'>
<ellipse cx='50' cy='32.3' rx='30' ry='30'></ellipse><text y='12'>n:1</text>
</g>
<g transform='translate(200 0)'>
<ellipse cx='50' cy='33.2' rx='30' ry='30'></ellipse><text y='12'>n:2</text>
</g>
<g transform='translate(300 0)'>
<ellipse cx='50' cy='34.5' rx='30' ry='30'></ellipse><text y='12'>n:3</text>
</g>
<g transform='translate(400 0)'>
<ellipse cx='50' cy='36.5' rx='30' ry='30'></ellipse><text y='12'>n:4</text>
</g>
<g transform='translate(500 0)'>
<ellipse cx='50' cy='39' rx='30' ry='30'></ellipse><text y='12'>n:5</text>
</g>
<g transform='translate(600 0)'>
<ellipse cx='50' cy='42' rx='30' ry='30'></ellipse><text y='12'>n:6</text>
</g>
<g transform='translate(700 0)'>
<ellipse cx='50' cy='45.7' rx='30' ry='30'></ellipse><text y='12'>n:7</text>
</g>
<g transform='translate(800 0)'>
<ellipse cx='50' cy='49.8' rx='30' ry='30'></ellipse><text y='12'>n:8</text>
</g>
<g transform='translate(900 0)'>
<ellipse cx='50' cy='54.5' rx='31.3' ry='30'></ellipse><text y='12'>n:9</text>
</g>
<g transform='translate(1000 0)'>
<ellipse cx='50' cy='59.8' rx='33.9' ry='30'></ellipse><text y='12'>n:10</text>
</g>
<g transform='translate(1100 0)'>
<ellipse cx='50' cy='65.7' rx='36.9' ry='30'></ellipse><text y='12'>n:11</text>
</g>
<g transform='translate(1200 0)'>
<ellipse cx='50' cy='72' rx='40' ry='30'></ellipse><text y='12'>n:12</text>
</g>
<g transform='translate(1300 0)'>
<ellipse cx='50' cy='65.7' rx='36.9' ry='30'></ellipse><text y='12'>n:13</text>
</g>
<g transform='translate(1400 0)'>
<ellipse cx='50' cy='59.8' rx='33.9' ry='30'></ellipse><text y='12'>n:14</text>
</g>
<g transform='translate(1500 0)'>
<ellipse cx='50' cy='54.5' rx='31.3' ry='30'></ellipse><text y='12'>n:15</text>
</g>
<g transform='translate(1600 0)'>
<ellipse cx='50' cy='49.8' rx='30' ry='30'></ellipse><text y='12'>n:16</text>
</g>
<g transform='translate(1700 0)'>
<ellipse cx='50' cy='45.7' rx='30' ry='30'></ellipse><text y='12'>n:17</text>
</g>
<g transform='translate(1800 0)'>
<ellipse cx='50' cy='42' rx='30' ry='30'></ellipse><text y='12'>n:18</text>
</g>
<g transform='translate(1900 0)'>
<ellipse cx='50' cy='39' rx='30' ry='30'></ellipse><text y='12'>n:19</text>
</g>
<g transform='translate(2000 0)'>
<ellipse cx='50' cy='36.5' rx='30' ry='30'></ellipse><text y='12'>n:20</text>
</g>
<g transform='translate(2100 0)'>
<ellipse cx='50' cy='34.5' rx='30' ry='30'></ellipse><text y='12'>n:21</text>
</g>
<g transform='translate(2200 0)'>
<ellipse cx='50' cy='33.2' rx='30' ry='30'></ellipse><text y='12'>n:22</text>
</g>
<g transform='translate(2300 0)'>
<ellipse cx='50' cy='32.3' rx='30' ry='30'></ellipse><text y='12'>n:23</text>
</g>
</svg></template>
注意
我可以不使用库,我正在生成(和更改)精灵表客户端
<template id="bounce">
<ellipse cx='50'
cy='${72-1*ease(40)}'
rx='${minmax(30,40-ease(20))}'
ry='30' fill='none' stroke='black' stroke-width='5'>
</ellipse>
<text y='12'>n:${framenr}</text>
</template>
一个 Web 组件然后(重新)创建精灵和 IMG,以及显示精灵的一切
<svg-spriter do="bounce" steps="24" duration="1s" animation="infinite"></svg-spriter>
解决方法
我对 fiddle 进行了一些更改,它似乎有效。有一点似乎是变换中的最后一个 left
坐标应该是 svg
的总长度减去窗口的长度。在小提琴中,您可以更改
transform: translate(calc(-1 * var(--steps) * var(--w)));
到
transform: translate(calc(-1 * calc(var(--steps) - 1) * var(--w)));
在您的代码段中,transform: translate(-100%);
百分比应为 (2300/2400)*100
。
更重要的是,我已将 width='2400'
属性添加到 svg
。为 svg 设置缺失的长度属性的问题非常复杂,我认为每个浏览器的行为方式都不相同。
在小提琴中,我已将 --w
属性更改为 100,即每个 svg 框架的高度和宽度。如果要将其设置为 200,则需要按比例更改 svg 的大小和每帧的坐标。
是的,这似乎与您的框架对齐有关。如果我在没有翻译的情况下绘制所有省略号且不透明度为 0.05,则会给出以下图像:
乍一看,虽然粗体绿色的厚度在左侧少了一个像素,但还是可以的。因此,在其“空气”位置尝试使用奇数宽度的椭圆可能是值得的。
顺便说一句,SVG(规范)也有您可能会使用的 shape-rendering 参数,但在您的情况下,这应该很少成为问题: