使用SVG制作逼真的(正弦)标记动画/抖动

想像力

我试图制作一个更逼真的动画svg旗帜,随风飘扬。这是我目前正在使用的简单标志库:

<svg
  xmlns="http://www.w3.org/2000/svg"
  width="200px"
  height="100px"
  viewBox="0 0 200 100"
>
  <path
    fill="red"
    d=
    "
      M 20,20
      Q 25,10 50,20
      T 80,20
      L 80,80
      Q 75,90 50,80
      T 20,80
      z
    "
  >
    <animate
      dur="1.8s"
      attributeName="d"
      fill="freeze"
      repeatCount="indefinite"
      values=
      "
        M 20,20
        Q 25,10 50,20
        T 80,20
        L 80,80
        Q 75,90 50,80
        T 20,80
        z;

        M 20,30
        Q 35,30 50,20
        T 80,20
        L 80,80
        Q 65,70 50,80
        T 20,90
        z;

        M 20,20
        Q 25,10 50,20
        T 80,20
        L 80,80
        Q 75,90 50,80
        T 20,80
        z;
      "
      calcMode="spline"
      keySplines="0,0,.58,1; 0,0,.58,1"
    />
  </path>
  <line x1="50" y1="35" x2="50" y2="65" stroke="#fff" stroke-width="10" />
  <line x1="35" y1="50" x2="65" y2="50" stroke="#fff" stroke-width="10" />
</svg>

如您所见,我在顶部和底部边缘绘制了一个带有附加中点的正方形。为了给当前标志设置动画,我在移动左边缘的拐角点和中点的曲率,但是这并不能提供很好的“标志行为”。

我希望获得一种更令人信服的颤动,该颤动类似于从右到左的正弦曲线。我尝试设置动画中点以“流动”到左边缘,因为它们会改变曲率角度,但这看起来也不正确。

r3mainer

我认为仅通过对两个关键帧之间的两个端点和一个控制点进行动画处理就不可能获得令人满意的结果。无论如何,如果旗标的一侧看起来像贴在旗杆上,则应保持静止。

我认为最好的方法是使用更多的控制点和更多的关键帧以编程方式生成路径数据。这是我用Python(v2)制作的一个程序来演示:

def flag_transform(x, y, t, a):
    from math import sin, pi
    freq = 1.0
    theta = (x * freq - t) * 2 * pi
    amp = a * x
    return (x, y+amp*sin(theta))

def flag_svg(nframes):
    x0 = y0 = 20
    w = h = 160
    amp = 10.0
    frames = []
    for i in range(nframes):
        s = 'M%.1f %.1f' % (x0,y0)
        for x in range(1,11):
            (fx1,fy1) = flag_transform(x*0.1-.05,0,i*1.0/nframes,amp)
            ax = fx1 * w + x0
            ay = fy1 + y0
            (fx2,fy2) = flag_transform(x*0.1,0,i*1.0/nframes,amp)
            bx = fx2 * w + x0
            by = fy2 + y0
            s += 'Q%.1f %.1f %.1f %.1f' % (ax,ay,bx,by)
        by += h
        s += 'L%.1f %.1f' % (bx,by)
        for x in range(9,-1,-1):
            (fx1,fy1) = flag_transform(x*0.1+.05,0,i*1.0/nframes,amp)
            ax = fx1 * w + x0
            ay = fy1 + y0 + h
            (fx2,fy2) = flag_transform(x*0.1,0,i*1.0/nframes,amp)
            bx = fx2 * w + x0
            by = fy2 + y0 + h
            s += 'Q%.1f %.1f %.1f %.1f' % (ax,ay,bx,by)
        s += 'Z'
        frames.append(s.replace('.0',''))
    #
    frames.append(frames[0])
    print '<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="200px" viewBox="0 0 200 200">'
    print '<path fill="red" d="' + frames[0] + '">'
    print '<animate dur="1.8s" attributeName="d" fill="freeze" repeatCount="indefinite" values="'
    print ';\n'.join(frames)
    print '"/>'
    print '</path>'
    print '</svg>'

flag_svg(10)

这是输出。如果要模拟瑞士国旗,则可以以完全相同的方式在中间添加白色十字。Q水平线使用二次曲线(),L垂直线使用直线()。

<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="200px" viewBox="0 0 200 200">
<path fill="red" d="M20 20Q28 20.2 36 20.6Q44 21.2 52 21.9Q60 22.5 68 22.9Q76 22.8 84 22.4Q92 21.4 100 20Q108 18.3 116 16.5Q124 14.7 132 13.3Q140 12.5 148 12.4Q156 13.1 164 14.7Q172 17.1 180 20L180 180Q172 177.1 164 174.7Q156 173.1 148 172.4Q140 172.5 132 173.3Q124 174.7 116 176.5Q108 178.3 100 180Q92 181.4 84 182.4Q76 182.8 68 182.9Q60 182.5 52 181.9Q44 181.2 36 180.6Q28 180.2 20 180Z">
<animate dur="1.8s" attributeName="d" fill="freeze" repeatCount="indefinite" values="
M20 20Q28 20.2 36 20.6Q44 21.2 52 21.9Q60 22.5 68 22.9Q76 22.8 84 22.4Q92 21.4 100 20Q108 18.3 116 16.5Q124 14.7 132 13.3Q140 12.5 148 12.4Q156 13.1 164 14.7Q172 17.1 180 20L180 180Q172 177.1 164 174.7Q156 173.1 148 172.4Q140 172.5 132 173.3Q124 174.7 116 176.5Q108 178.3 100 180Q92 181.4 84 182.4Q76 182.8 68 182.9Q60 182.5 52 181.9Q44 181.2 36 180.6Q28 180.2 20 180Z;
M20 20Q28 19.8 36 20Q44 20.5 52 21.2Q60 22 68 22.9Q76 23.5 84 23.8Q92 23.6 100 22.9Q108 21.7 116 20Q124 18 132 15.9Q140 13.9 148 12.4Q156 11.5 164 11.4Q172 12.3 180 14.1L180 174.1Q172 172.3 164 171.4Q156 171.5 148 172.4Q140 173.9 132 175.9Q124 178 116 180Q108 181.7 100 182.9Q92 183.6 84 183.8Q76 183.5 68 182.9Q60 182 52 181.2Q44 180.5 36 180Q28 179.8 20 180Z;
M20 20Q28 19.6 36 19.4Q44 19.5 52 20Q60 20.8 68 21.8Q76 22.8 84 23.8Q92 24.5 100 24.8Q108 24.4 116 23.5Q124 22 132 20Q140 17.7 148 15.3Q156 13.1 164 11.4Q172 10.5 180 10.5L180 170.5Q172 170.5 164 171.4Q156 173.1 148 175.3Q140 177.7 132 180Q124 182 116 183.5Q108 184.4 100 184.8Q92 184.5 84 183.8Q76 182.8 68 181.8Q60 180.8 52 180Q44 179.5 36 179.4Q28 179.6 20 180Z;
M20 20Q28 19.5 36 19Q44 18.8 52 18.8Q60 19.2 68 20Q76 21.1 84 22.4Q92 23.6 100 24.8Q108 25.5 116 25.7Q124 25.3 132 24.1Q140 22.3 148 20Q156 17.4 164 14.7Q172 12.3 180 10.5L180 170.5Q172 172.3 164 174.7Q156 177.4 148 180Q140 182.3 132 184.1Q124 185.3 116 185.7Q108 185.5 100 184.8Q92 183.6 84 182.4Q76 181.1 68 180Q60 179.2 52 178.8Q44 178.8 36 179Q28 179.5 20 180Z;
M20 20Q28 19.6 36 19Q44 18.5 52 18.1Q60 18 68 18.2Q76 18.9 84 20Q92 21.4 100 22.9Q108 24.4 116 25.7Q124 26.5 132 26.7Q140 26.1 148 24.7Q156 22.6 164 20Q172 17.1 180 14.1L180 174.1Q172 177.1 164 180Q156 182.6 148 184.7Q140 186.1 132 186.7Q124 186.5 116 185.7Q108 184.4 100 182.9Q92 181.4 84 180Q76 178.9 68 178.2Q60 178 52 178.1Q44 178.5 36 179Q28 179.6 20 180Z;
M20 20Q28 19.8 36 19.4Q44 18.8 52 18.1Q60 17.5 68 17.1Q76 17.2 84 17.6Q92 18.6 100 20Q108 21.7 116 23.5Q124 25.3 132 26.7Q140 27.5 148 27.6Q156 26.9 164 25.3Q172 22.9 180 20L180 180Q172 182.9 164 185.3Q156 186.9 148 187.6Q140 187.5 132 186.7Q124 185.3 116 183.5Q108 181.7 100 180Q92 178.6 84 177.6Q76 177.2 68 177.1Q60 177.5 52 178.1Q44 178.8 36 179.4Q28 179.8 20 180Z;
M20 20Q28 20.2 36 20Q44 19.5 52 18.8Q60 18 68 17.1Q76 16.5 84 16.2Q92 16.4 100 17.1Q108 18.3 116 20Q124 22 132 24.1Q140 26.1 148 27.6Q156 28.5 164 28.6Q172 27.7 180 25.9L180 185.9Q172 187.7 164 188.6Q156 188.5 148 187.6Q140 186.1 132 184.1Q124 182 116 180Q108 178.3 100 177.1Q92 176.4 84 176.2Q76 176.5 68 177.1Q60 178 52 178.8Q44 179.5 36 180Q28 180.2 20 180Z;
M20 20Q28 20.4 36 20.6Q44 20.5 52 20Q60 19.2 68 18.2Q76 17.2 84 16.2Q92 15.5 100 15.2Q108 15.6 116 16.5Q124 18 132 20Q140 22.3 148 24.7Q156 26.9 164 28.6Q172 29.5 180 29.5L180 189.5Q172 189.5 164 188.6Q156 186.9 148 184.7Q140 182.3 132 180Q124 178 116 176.5Q108 175.6 100 175.2Q92 175.5 84 176.2Q76 177.2 68 178.2Q60 179.2 52 180Q44 180.5 36 180.6Q28 180.4 20 180Z;
M20 20Q28 20.5 36 21Q44 21.2 52 21.2Q60 20.8 68 20Q76 18.9 84 17.6Q92 16.4 100 15.2Q108 14.5 116 14.3Q124 14.7 132 15.9Q140 17.7 148 20Q156 22.6 164 25.3Q172 27.7 180 29.5L180 189.5Q172 187.7 164 185.3Q156 182.6 148 180Q140 177.7 132 175.9Q124 174.7 116 174.3Q108 174.5 100 175.2Q92 176.4 84 177.6Q76 178.9 68 180Q60 180.8 52 181.2Q44 181.2 36 181Q28 180.5 20 180Z;
M20 20Q28 20.4 36 21Q44 21.5 52 21.9Q60 22 68 21.8Q76 21.1 84 20Q92 18.6 100 17.1Q108 15.6 116 14.3Q124 13.5 132 13.3Q140 13.9 148 15.3Q156 17.4 164 20Q172 22.9 180 25.9L180 185.9Q172 182.9 164 180Q156 177.4 148 175.3Q140 173.9 132 173.3Q124 173.5 116 174.3Q108 175.6 100 177.1Q92 178.6 84 180Q76 181.1 68 181.8Q60 182 52 181.9Q44 181.5 36 181Q28 180.4 20 180Z;
M20 20Q28 20.2 36 20.6Q44 21.2 52 21.9Q60 22.5 68 22.9Q76 22.8 84 22.4Q92 21.4 100 20Q108 18.3 116 16.5Q124 14.7 132 13.3Q140 12.5 148 12.4Q156 13.1 164 14.7Q172 17.1 180 20L180 180Q172 177.1 164 174.7Q156 173.1 148 172.4Q140 172.5 132 173.3Q124 174.7 116 176.5Q108 178.3 100 180Q92 181.4 84 182.4Q76 182.8 68 182.9Q60 182.5 52 181.9Q44 181.2 36 180.6Q28 180.2 20 180Z
"/>
</path>
</svg>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何制作逼真的轮盘赌球旋转动画

来自分类Dev

如何制作逼真的轮盘赌球旋转动画

来自分类Dev

如何使用Threejs实现逼真的反射

来自分类Dev

Matlab:逼真的动画弹跳球(模拟地球条件)

来自分类Dev

如何在 CSS/SVG 中创建逼真的光泽效果?

来自分类Dev

更逼真的照明

来自分类Dev

悬停时的SVG抖动动画

来自分类Dev

更逼真的透视算法

来自分类Dev

使用SVG为Circle Border制作动画的特定方法?

来自分类Dev

用Javascript制作SVG动画

来自分类Dev

如何使用Pure CSS3绘制逼真的平滑缝阴影?

来自分类Dev

使用正弦波动画圆的填充

来自分类Dev

使用SliverAppBar抖动设计此动画

来自分类Dev

javascript中逼真的鼠标移动坐标?

来自分类Dev

Unity 中逼真的阀轮旋转

来自分类Dev

使用Cartopy制作动画

来自分类Dev

使用StreamBuilder制作动画

来自分类Dev

使用 jQuery 制作动画

来自分类Dev

如何为SVG的某些部分制作动画

来自分类Dev

您可以动态制作SVG动画吗?

来自分类Dev

如何为SVG波动图像制作动画?

来自分类Dev

如何制作JS生成的SVG对象的动画?

来自分类Dev

如何从JS制作蒙版SVG动画?

来自分类Dev

带有动画的Google Maps SVG标记

来自分类Dev

如何在react-native中使用Animated制作svg动画

来自分类Dev

使用angularjs动画制作div动画

来自分类Dev

使用angularjs动画制作div动画

来自分类Dev

使用inkscape的SVG动画

来自分类Dev

如何使用SVG中的标记为更改的路径长度(线)设置动画