reactjs - SVG圆形变形

标签 reactjs animation svg svg-animate

如何使用形状变形制作圆形 SVG?
我正在尝试通过有机运动来制作圆圈。
但正如你所看到的,像素似乎有问题。
关于如何使它更好看的任何想法?它甚至是我用来做这件事的正确方法吗?我不是 svg 或形状变形方面的专家。

class App extends React.Component {
  render() {
    return (
      <div>
       <svg width="200px" height="200px" viewBox="0 0 120 120">
    <defs>
        <filter id="distort">
            <feTurbulence baseFrequency=".02" type="fractalNoise" />
            <feColorMatrix type="hueRotate" values="0">
                <animate attributeName="values" from="0" to="360" dur="1s" repeatCount="indefinite" />
            </feColorMatrix>
            <feDisplacementMap in="SourceGraphic" xChannelSelector="R" yChannelSelector="B" scale="20">
                <animate attributeName="scale" values={Math.round(Math.random() * 20) + ';' + Math.round(Math.random() * 10) + ';' + Math.round(Math.random() * 10) + ';' + Math.round(Math.random() * 10) + ';'}  dur="5s" repeatCount="indefinite" />
            </feDisplacementMap>
        </filter>
    </defs>
    <circle filter="url(#distort)" cx="60" cy="60" r="30" />
</svg>
      </div>
    );
  }
}

// Render it
ReactDOM.render(
  <App />,
  document.getElementById("app")
);
svg {
    stroke-width: 1;
    stroke: #293133;
    stroke-linecap: round;
    fill: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>

最佳答案

我认为故障效应的发生是因为 feTurbulence filter 在 R、G 和 B channel 中输出 8 位整数值。这种量化使得难以在位移映射中实现平滑变化。
无论如何,使用动画矢量曲线可以获得更好的结果。这是一个示例,该示例为具有 50 个顶点的多边形设置动画。您可以通过使用二次或三次贝塞尔曲线而不是直线段来减少点数,但这至少应该让您开始:

window.onload = function() {
    var radius = 60, npoints = 50, nwaves = 8;
    var min_amp = 0.5, max_amp = 2.0;       // Spatial amplitude
    var min_freq = 0.1, max_freq = 0.2;     // Spatial frequency
    var min_speed = 0.05, max_speed = 0.1;  // Temporal speed
    var time_step = 0.2;
    
    // Create path data for initial circle
    var base_coords = [];
    for (var i=0; i<=npoints; i++) {
        var x = Math.sin(i * 2 * Math.PI / npoints) * radius;
        var y = Math.cos(i * 2 * Math.PI / npoints) * radius;
        base_coords.push([x,y]);
    }
    
    // Create wave data for distortion
    var wave_data = [];
    for (var i=0; i<nwaves; i++) {
        var amp = Math.random() * (max_amp - min_amp) + min_amp;
        var freq = Math.random() * (max_freq - min_freq) + min_freq;
        var speed = Math.random() * (max_speed - min_speed) + min_speed;
        var angle = Math.random() * 2 * Math.PI;
        wave_data.push([amp,freq,speed,angle]);
    }
    
    var ticks = 0;
    var update_blob = function() {
        ticks++;
        var blob_coords = [];
        for (var i=0; i<base_coords.length; i++) {
            // Fetch base coordinate
            var x = base_coords[i][0];
            var y = base_coords[i][1];
            // Distort using wave data
            for (var j=0; j<wave_data.length; j++) {
                // Rotate x & y to wave orientation
                var s = Math.sin(wave_data[j][3]);
                var c = Math.cos(wave_data[j][3]);
                var tx = x * c + y * s;
                var ty = x * -s + y * c;
                // Shift along x axis using wave parameters and x value
                tx += Math.sin(tx * wave_data[j][1] + ticks * wave_data[j][2]) * wave_data[j][0];
                // Rotate back to original orientation
                x = tx * c + ty * -s;
                y = tx * s + ty * c;
            }
            blob_coords.push([x,y]);
        }
        var d = "M";
        for (var i=0; i<blob_coords.length; i++) {
            d += " " + blob_coords[i][0].toFixed(2) + " " + blob_coords[i][1].toFixed(2);
        }
        d += "Z";
        // console.log(d);
        document.getElementById("blob").setAttribute("d", d);
        // if (ticks == 1) alert(d);
    }
    setInterval(update_blob, 20);
}
<svg width="150" height="150" viewBox="-75 -75 150 150">
<path id="blob" d="M0 0 0 0Z" stroke="#000" stroke-width="2" fill="none" />
</svg>

关于reactjs - SVG圆形变形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67416834/

相关文章:

reactjs - ReactCSSTransitionGroup 只适用于新组件中的动画?

javascript - React中箭头函数的优化

html - 用括号进行 react

javascript - 如何复合Jquery动画

javascript - 如何在多个位置绘制 svg,在另一个 svg 图像之上

javascript - 如何从元素获取 JSON 路径

javascript - 更新气泡图中的数据时如何将圆圈保留在 svg 内

css - 我们如何将 css 属性添加到样式组件中的类?

ios - 如何在 MKMapView 中对叠加绘图进行动画处理

Jquery "hide"无动画