SVG 圆形变形
SVG circle shape morphing
如何制作带有形状变形的圆形 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>
Any ideas on how to make it better looking ?
可以通过更改补丁的 d
属性来实现圆形边界的变形
逐步实现变形:
- 正在将圆加载到矢量编辑器中
- 添加额外的锚点。以 SVG 格式保存文件。这会
成为变形的起始路径
- 移动节点。我们保存文件。这将是最终路径
用于变形。
- 我们写了一个动画命令来改变
d
属性。价值
此属性更改为
values="path Start; path Finish; path Start"
注意:Start和Finish路径之间用分号隔开
完整代码如下。点击后动画开始
<svg id="svg1" width="200px" height="200px" viewBox="0 0 120 120">
<path
style="fill:none;stroke:#000000;stroke-width:2"
d="M 90,60 C 90,68.642693 86.345292,76.431784 80.497023,81.906123 75.133823,86.926409 67.925849,90 60,90 51.779957,90 44.332072,86.694001 38.913442,81.339102 33.410134,75.90052 30,68.3485 30,60 30,52.173162 32.99728,45.046376 37.906648,39.704832 43.389864,33.738925 51.258296,30 60,30 68.057492,30 75.373063,33.17654 80.762728,38.345633 86.455778,43.805696 90,51.488949 90,60 Z">
<animate
attributeName="d"
begin="svg1.click"
dur="1.5s"
fill="freeze"
repeatCount="indefinite"
restart="whenNotActive"
values="
M 90,60 C 90,68.642693 86.345292,76.431784 80.497023,81.906123 75.133823,86.926409 67.925849,90 60,90 51.779957,90 44.332072,86.694001 38.913442,81.339102 33.410134,75.90052 30,68.3485 30,60 30,52.173162 32.99728,45.046376 37.906648,39.704832 43.389864,33.738925 51.258296,30 60,30 68.057492,30 75.373063,33.17654 80.762728,38.345633 86.455778,43.805696 90,51.488949 90,60 Z;
m 92.542373,60 c 0,8.642693 -9.247929,11.982631 -15.096197,17.45697 -5.363201,5.020286 -9.647445,15.212522 -17.573295,15.212522 -8.220042,0 -9.947589,-10.678881 -15.366218,-16.03378 -5.503309,-5.438582 -17.176155,-8.541449 -17.176155,-16.889949 0,-7.826839 9.480331,-11.267184 14.389699,-16.608727 5.483217,-5.965908 10.046563,-16.187883 18.788268,-16.187883 8.057491,0 12.195097,9.786709 17.584761,14.955802 C 83.786287,47.365018 92.542373,51.488949 92.542373,60 Z;
M 90,60 C 90,68.642693 86.345292,76.431784 80.497023,81.906123 75.133823,86.926409 67.925849,90 60,90 51.779957,90 44.332072,86.694001 38.913442,81.339102 33.410134,75.90052 30,68.3485 30,60 30,52.173162 32.99728,45.046376 37.906648,39.704832 43.389864,33.738925 51.258296,30 60,30 68.057492,30 75.373063,33.17654 80.762728,38.345633 86.455778,43.805696 90,51.488949 90,60 Z" />
</path>
</svg>
另一个从圆形变形为三角形,然后变形为矩形再变回圆形的示例
所有形状的路径都在矢量编辑器中绘制。
要想动画流畅,不卡顿,创建路径时必须满足两个条件:
- 所有形状的锚点数量必须相同
- 从头开始位置相同的锚点类型,
所有形状必须相同
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600" viewBox="0 0 400 400" >
<rect width="100%" height="100%" fill="#2772C7" />
<path
style="stroke:white; fill:none;stroke-width:18; stroke-linecap:round; stroke-dasharray:0,15"
d="m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z">
<!-- Animation of morphing circle into a triangle and a rectangle -->
<animate
attributeName="d"
begin="svg1.click"
dur="3s"
fill="freeze"
repeatCount="3"
restart="whenNotActive"
values="
m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z;
m 285,200 c 15,25 55,90 65,110 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 64.378221,285 99.019238,225 113.45299,200 153.86751,130 170,100 200,50 c 45,79.01924 48.45299,85 85,150 z;
m 285,200 c 15,25 55,90 65,110 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 64.378221,285 99.019238,225 113.45299,200 153.86751,130 170,100 200,50 c 45,79.01924 48.45299,85 85,150 z;
m 350,50 c 0,40 0,240 0,260 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 50,285 50,85 50,50 c 70,0 105,0 150,0 80,0 100,0 150,0 z;
m 350,50 c 0,40 0,240 0,260 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 50,285 50,85 50,50 c 70,0 105,0 150,0 80,0 100,0 150,0 z;
m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z;
m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150z"
/>
</path>
</svg>
我认为出现毛刺效应是因为 feTurbulence
滤镜在 R、G 和 B 通道中输出 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>
好吧,您可以尝试使用额外的过滤器基元来尝试使事情顺利进行 - 但这并不完美。这是一次勇敢的尝试。
额外的模糊+粘稠的颜色矩阵将使锯齿状的边缘变得平滑,但一些位移非常锯齿,导致部分圆圈消失。所以我增加了原始圆的笔划宽度,然后使用 feMorphology/erode 再次将其变细 - 如您所见,这并不完美。 (由于粘糊糊的 feColorMatrix 的工作方式,我还不得不去掉原来的白色填充。)
class App extends React.Component {
render() {
return (
<div>
<svg width="200px" height="200px" viewBox="0 0 120 120">
<defs>
<filter id="distort" width="130%" height="130%">
<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="15"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 10 -1"/>
<feMorphology operator="erode" radius="1"/>
</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: 3;
stroke: #293133;
stroke-linecap: round;
fill: none;
}
<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>
如何制作带有形状变形的圆形 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>
Any ideas on how to make it better looking ?
可以通过更改补丁的 d
属性来实现圆形边界的变形
逐步实现变形:
- 正在将圆加载到矢量编辑器中
- 添加额外的锚点。以 SVG 格式保存文件。这会 成为变形的起始路径
- 移动节点。我们保存文件。这将是最终路径 用于变形。
- 我们写了一个动画命令来改变
d
属性。价值 此属性更改为
values="path Start; path Finish; path Start"
注意:Start和Finish路径之间用分号隔开
完整代码如下。点击后动画开始
<svg id="svg1" width="200px" height="200px" viewBox="0 0 120 120">
<path
style="fill:none;stroke:#000000;stroke-width:2"
d="M 90,60 C 90,68.642693 86.345292,76.431784 80.497023,81.906123 75.133823,86.926409 67.925849,90 60,90 51.779957,90 44.332072,86.694001 38.913442,81.339102 33.410134,75.90052 30,68.3485 30,60 30,52.173162 32.99728,45.046376 37.906648,39.704832 43.389864,33.738925 51.258296,30 60,30 68.057492,30 75.373063,33.17654 80.762728,38.345633 86.455778,43.805696 90,51.488949 90,60 Z">
<animate
attributeName="d"
begin="svg1.click"
dur="1.5s"
fill="freeze"
repeatCount="indefinite"
restart="whenNotActive"
values="
M 90,60 C 90,68.642693 86.345292,76.431784 80.497023,81.906123 75.133823,86.926409 67.925849,90 60,90 51.779957,90 44.332072,86.694001 38.913442,81.339102 33.410134,75.90052 30,68.3485 30,60 30,52.173162 32.99728,45.046376 37.906648,39.704832 43.389864,33.738925 51.258296,30 60,30 68.057492,30 75.373063,33.17654 80.762728,38.345633 86.455778,43.805696 90,51.488949 90,60 Z;
m 92.542373,60 c 0,8.642693 -9.247929,11.982631 -15.096197,17.45697 -5.363201,5.020286 -9.647445,15.212522 -17.573295,15.212522 -8.220042,0 -9.947589,-10.678881 -15.366218,-16.03378 -5.503309,-5.438582 -17.176155,-8.541449 -17.176155,-16.889949 0,-7.826839 9.480331,-11.267184 14.389699,-16.608727 5.483217,-5.965908 10.046563,-16.187883 18.788268,-16.187883 8.057491,0 12.195097,9.786709 17.584761,14.955802 C 83.786287,47.365018 92.542373,51.488949 92.542373,60 Z;
M 90,60 C 90,68.642693 86.345292,76.431784 80.497023,81.906123 75.133823,86.926409 67.925849,90 60,90 51.779957,90 44.332072,86.694001 38.913442,81.339102 33.410134,75.90052 30,68.3485 30,60 30,52.173162 32.99728,45.046376 37.906648,39.704832 43.389864,33.738925 51.258296,30 60,30 68.057492,30 75.373063,33.17654 80.762728,38.345633 86.455778,43.805696 90,51.488949 90,60 Z" />
</path>
</svg>
另一个从圆形变形为三角形,然后变形为矩形再变回圆形的示例
所有形状的路径都在矢量编辑器中绘制。 要想动画流畅,不卡顿,创建路径时必须满足两个条件:
- 所有形状的锚点数量必须相同
- 从头开始位置相同的锚点类型, 所有形状必须相同
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="600" height="600" viewBox="0 0 400 400" >
<rect width="100%" height="100%" fill="#2772C7" />
<path
style="stroke:white; fill:none;stroke-width:18; stroke-linecap:round; stroke-dasharray:0,15"
d="m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z">
<!-- Animation of morphing circle into a triangle and a rectangle -->
<animate
attributeName="d"
begin="svg1.click"
dur="3s"
fill="freeze"
repeatCount="3"
restart="whenNotActive"
values="
m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z;
m 285,200 c 15,25 55,90 65,110 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 64.378221,285 99.019238,225 113.45299,200 153.86751,130 170,100 200,50 c 45,79.01924 48.45299,85 85,150 z;
m 285,200 c 15,25 55,90 65,110 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 64.378221,285 99.019238,225 113.45299,200 153.86751,130 170,100 200,50 c 45,79.01924 48.45299,85 85,150 z;
m 350,50 c 0,40 0,240 0,260 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 50,285 50,85 50,50 c 70,0 105,0 150,0 80,0 100,0 150,0 z;
m 350,50 c 0,40 0,240 0,260 -45,0 -94.3876,0 -150,0 -55.32584,0 -85,0 -150,-0.0962 C 50,285 50,85 50,50 c 70,0 105,0 150,0 80,0 100,0 150,0 z;
m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150 z;
m 350,200 c 0,27.23032 -7.25588,52.76593 -19.93968,74.77889 C 304.15623,319.7359 255.6124,350 200,350 144.67416,350 96.344223,320.04698 70.34191,275.47268 57.409394,253.30319 50,227.51687 50,200 50,117.15729 117.15729,50 200,50 c 82.84271,0 150,67.15729 150,150z"
/>
</path>
</svg>
我认为出现毛刺效应是因为 feTurbulence
滤镜在 R、G 和 B 通道中输出 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>
好吧,您可以尝试使用额外的过滤器基元来尝试使事情顺利进行 - 但这并不完美。这是一次勇敢的尝试。
额外的模糊+粘稠的颜色矩阵将使锯齿状的边缘变得平滑,但一些位移非常锯齿,导致部分圆圈消失。所以我增加了原始圆的笔划宽度,然后使用 feMorphology/erode 再次将其变细 - 如您所见,这并不完美。 (由于粘糊糊的 feColorMatrix 的工作方式,我还不得不去掉原来的白色填充。)
class App extends React.Component {
render() {
return (
<div>
<svg width="200px" height="200px" viewBox="0 0 120 120">
<defs>
<filter id="distort" width="130%" height="130%">
<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="15"/>
<feGaussianBlur stdDeviation="1"/>
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 10 -1"/>
<feMorphology operator="erode" radius="1"/>
</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: 3;
stroke: #293133;
stroke-linecap: round;
fill: none;
}
<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>