Svg 火焰多边形动画

问题描述

希望在 SVG 中创建一个动画壁炉来温暖我的壁炉。

仅使用两个 polygon 并在循环中随机化和重绘点。

无法使用 css 转换为 polylinepolygon 点设置动画?

使用js?

如何为 <animate> 属性实现 points

因为 points 是一个 SVGPoints 数组而不是文档中所示的单个值:

https://developer.mozilla.org/en-US/docs/Web/SVG/SVG_animation_with_SMIL

firePlace.appendChild(Object.assign(document.createElementNS("http://www.w3.org/2000/svg",'polygon'),{id: "vline",style: "fill:#ff0"}))
firePlace.appendChild(Object.assign(document.createElementNS("http://www.w3.org/2000/svg",{id: "wline",style: "fill:#f00"}))

setInterval(function(){
  let v = "0,700 ",w = "0,700 "
  for (let i=0;i<=1100;i++){
    v += (i * 30) + "," + (~~(Math.random()*700) + 200) + " "
    w += (i * 30) + "," + (~~(Math.random()*700) + 200) + " "
  }
  v += "1101,900"
  w += "1101,900"
  window.requestAnimationFrame(function(){
    vline.setAttribute("points",v)
    wline.setAttribute("points",w)
  })
},200) // 200ms 
<svg id="firePlace" viewBox="700 0 1100 700" preserveAspectRatio="none" height="700" style="width: 100%; height: 100%;background: black"></svg>

这是一个很难回答的问题,不过还是祝大家假期愉快!

解决方法

带有动画 polylinepoints 示例:

<svg viewBox="-100 165 1100 600" xmlns="http://www.w3.org/2000/svg">
    <polyline fill="none" stroke="currentColor" stroke-width="5" stroke-miterlimit="5">
        <animate id="a1" attributeName="points" dur="3.6s" repeatCount="indefinite" 
                 values="0,511 137,510 137,510 156,478 146,510 181,510 220,441 183,505 211,457 211,457 232,420 232,420 239,489 256,447 256,510 271,429 261,441 274,426 274,426 301,473 301,473 321,441 321,441 348,473 338,494 338,494 374,415 374,415 412,314 402,336 402,336 439,261 439,261 384,494 422,296 422,296 442,256 442,256 457,288 464,304 464,304 484,362 494,415 484,362 501,380 501,380 522,399 522,399 558,437 547,425 547,425 565,447 565,447 589,468 582,462 582,462 619,489 619,489 656,510 656,510 679,510 621,489 684,383 684,383 708,457 708,436 730,473 719,457 743,477 743,477 766,482 799,510 799,510 900,511;
                         0,511 156,470 146,470 181,392 181,392 220,479 183,479 211,421 211,421 232,376 232,376 239,392 256,428 256,428 271,459 261,459 274,485 274,485 301,424 301,424 321,470 321,470 348,410 338,410 374,329 374,329 412,410 402,410 439,487 439,487 384,487 422,402 422,402 442,446 442,446 457,414 464,429 464,429 484,469 494,445 484,445 501,408 501,408 522,366 522,366 558,445 547,445 565,480 565,480 589,431 582,431 619,344 619,344 656,425 656,425 679,476 679,476 621,476 684,340 684,340 708,391 708,391 730,438 719,438 743,489 743,489 766,438 799,511 799,511 900,478 156,463 146,463 181,500 220,500 183,500 211,510 232,388 256,510 261,510 274,293 301,510 321,261 348,336 338,420 338,484 374,309 412,420 402,473 402,473 439,515 384,515 422,457 422,341 442,463 457,463 464,166 484,166 494,351 484,463 501,484 522,256 558,404 547,436 547,489 565,436 589,436 582,489 582,505 619,304 656,494 679,463 621,510 684,510 708,399 730,447 719,473 743,510 766,489 799,511"
                 calcMode="spline" keySplines=".5 1 .3 1;.5 1 .3 1;.5 1 .3 1;"/>
    </polyline>
</svg>

,

是的,<animate> 确实支持 points 数组,使用上面的代码片段可能看起来像:

firePlace.appendChild(Object.assign(document.createElementNS("http://www.w3.org/2000/svg",'polygon'),{id: "vline",style: "fill:#ff0"}))
firePlace.appendChild(Object.assign(document.createElementNS("http://www.w3.org/2000/svg",{id: "wline",style: "fill:#f00"}))

let t
fireWork()

function fireWork(){
  let v = "0,700 ",w = "0,700 "
  for (let i=0;i<=1100;i++){
    v += (i * 30) + "," + (~~(Math.random()*700) + 200) + " "
    w += (i * 30) + "," + (~~(Math.random()*700) + 200) + " "
  }
  v += "1101,900"
  w += "1101,900"
  window.requestAnimationFrame(function(){
    vline.innerHTML = `<animate attributeName="points" from="${vline.getAttribute('points')}" to="${v}" dur="${~~(Math.random() * 10)}s" dur="0.618s" repeatCount="indefinite" />`
    wline.innerHTML = `<animate attributeName="points" from="${wline.getAttribute('points')}" to="${v}" dur="0.218s" repeatCount="indefinite" />`
    vline.setAttribute("points",v)
    wline.setAttribute("points",w)
  })
  clearTimeout(t)
  t = setTimeout(fireWork,5000)
}
<svg id="firePlace" viewBox="700 0 1100 700" preserveAspectRatio="none" height="700" style="width: 100%; height: 100%;background: black"></svg>

仍然有问题,但可以继续,谢谢@Robert

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...