1

所以,如果你检查小提琴,(https://jsfiddle.net/xXnikosXx/6jx2rpsf/3/)我有一个 SVG 图像,有几个对象和一个面具。它掩盖了隐藏在其下方的文本(彩色线条),并计划对其顶部位置进行动画处理,使下方的文本出现,顶部的文本消失,以产生文本滚动效果。没有蒙版的文本如下图所示,以防万一。 在这里 我认为当动画发生时文本会出现,但它没有(如果你移除蒙版,文本会正确显示和动画,但它们的图层是错误的,所以文本出现在其他所有内容之上)

我想不出一种使用蒙版使文本正确动画的方法,有没有什么我可以使用而不是蒙版来获得相同的结果,但没有文本问题?

相关代码:

<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="354" y="174" width="733" height="344">
  <rect id="laptop-screen-front" x="354" y="174" width="733" height="344" fill="white" />
</mask>
<g mask="url(#mask0)">

<!-- some of the lines that represent text: -->
<g id="text-lines">
  <line id="Line 3" x1="408" y1="194.5" x2="433" y2="194.5" stroke="#E06C60" stroke-width="5" />
  <line id="Line 23" x1="438" y1="194.5" x2="463" y2="194.5" stroke="#D18C4C" stroke-width="5" />
  <line id="Line 35" x1="469" y1="194.5" x2="542" y2="194.5" stroke="#7BC379" stroke-width="5" />
  <line id="Line 36" x1="469" y1="209.5" x2="525" y2="209.5" stroke="#7BC379" stroke-width="5" />
</g>
4

2 回答 2

2

您的代码不会为面具设置动画。它尝试为 text-lines g 元素的位置设置动画。但是 SVG 不是 HTML。它是它自己的东西,不支持许多常见的 CSS 属性:例如,与您最相关 - SVG 中没有“top”属性。做你想做的最简单的方法是去掉所有的 CSS 动画,并将一个变换和一个 SMIL 动画直接添加到 SVG 的以下部分。

 <g mask="url(#mask0)">
    <g id="text-lines" transform="translate(0 0)">
    <animateTransform attributeName="transform" type="translate" values="0 0; 0 -150; 0 0" dur="11s" repeatCount="indefinite"/>
    <line id="Line 3" x1="408" .... etc.

顺便说一句——对动画使用变换的原因之一是浏览器通常可以通过在 GPU 上制作动画来优化事物——所以它比 viewBox 或顶级动画更好。

于 2021-06-27T12:45:30.770 回答
1

2种方法:

  1. 与 SMIL

svg#parent {
  background-color: rgba(100, 148, 237, 0.3);
}
<svg id="parent" width="200" height="100" viewBox="0 0 200 100">
  <rect x="10" y="10" width="180" height="20" fill="white"  />
  <svg  x="10" y="10" width="180" height="20" viewBox="0 0 180 20" >
    <text x="20" y="15" > hello </text>
    <text x="20" y="35" > world </text>
    <animate attributeName="viewBox" 
       values="0 0 180 20; 0 20 180 20; 0 0 180 20" 
       begin="1s" dur="2s" repeatCount="indefinite" />
  </svg>
</svg>

  1. 使用 javascript - requestAnimationFrame

(function()
  {
  const
    svgInside = document.querySelector('#insideSVG')
  , moving    = .7 // change the value to slow down or speed up
    ;
  let 
    stepVal = moving
  , stepPos = 0
    ;
  requestAnimationFrame(step)
    ;
  function step()
    {
    stepPos += stepVal

    if (stepPos<=0)  stepVal = moving
    if (stepPos>=20) stepVal = -moving

    svgInside.setAttribute('viewBox',`0 ${stepPos} 180 20`)
  
    requestAnimationFrame(step)
    }
  }
)()
svg#parent {
  background-color: rgba(100, 148, 237, 0.3);
}
<svg id="parent" width="200" height="100" viewBox="0 0 200 100">
  <rect x="10" y="10" width="180" height="20" fill="white" />
  <svg  x="10" y="10" width="180" height="20" viewBox="0 0 180 20"
        id="insideSVG" >
    <text x="20" y="15" > hello </text>
    <text x="20" y="35" > world </text>
  </svg>
</svg>

对于您的 SVG,值应该是:


<svg  x="354" y="174" width="733" height="344" viewBox="354 174 733 344" >
   <line x1="419" y1="187.5" ..... />

/.../

   <animate attributeName="viewBox" 
     values="354 174 733 344; 354 520 733 344; 354 174 733 344" 
      begin="1s" dur="8s" repeatCount="indefinite" />
</svg>

怎么<animate>工作?——保罗·勒博

mdn 文档非常完整: :

不要犹豫,咨询其他信息页面的链接

但是,如果您想大致了解 SVG 的动画可能性,维基百科页面是理想的

甚至有一部分显示了我在这里使用的requestAnimationFrame()的使用。

PS:Whitesmith 风格自 1978 年以来一直存在,不,我不是出于审美原因使用它,而是因为它检查正确的大括号对是否构成正确的代码段。出于同样的原因,我将逗号放在数据行的前面(它们在行尾是不可见的[并且经常被遗忘]),以及列对齐方式(两者都在 Haskell 中使用类似的方式)
不, K&R 不是万无一失的风格,也不是比其他任何风格都更合法。

于 2021-06-27T21:12:45.517 回答