How to animate SVG path polymorphing circle images? - javascript

SVG animation - for example
https://theplusaddons.com/widgets/morphing-sections/
How can I do such animation?
<div class="polymorphing">
<svg viewBox="0 0 200 200" height="600" width="600" xmlns="http://www.w3.org/2000/svg">
<clipPath id="myClip">
<path fill="#FF0066"
d="M42.3,-45.7C56.3,-38.7,70.1,-26.8,73.3,-12.4C76.5,2,69.1,18.8,58.1,29.6C47.1,40.4,32.7,45.1,17.7,51.9C2.8,58.7,-12.5,67.6,-28.1,66.5C-43.7,65.4,-59.5,54.5,-69.8,39.1C-80.2,23.7,-85.1,3.9,-80.7,-13.1C-76.4,-30.2,-62.9,-44.5,-47.9,-51.3C-32.9,-58.1,-16.4,-57.5,-1.1,-56.1C14.2,-54.8,28.4,-52.7,42.3,-45.7Z"
transform="translate(100 100)" />
</clipPath>
<g clip-path="url(#myClip)">
<image class="morph-image"
xlink:href="https://theplusaddons.com/wp-content/uploads/2019/04/digitalagency3.jpg" x="0" y="0"
height="100%" width="100%">
</image>
</g>
</svg>
</div>

Related

Is it possible to programatically control fill color of individual cells of svg pattern?

<svg viewBox="200 190 500 500" id="example">
<defs>
<pattern id="patt" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<g stroke="black" strokeWidth="0.5" >
<path id='a' fill='green' d="M0,0.054V20h21V0.054H0z M15.422,18.129l-5.264-2.768l-5.265,2.768l1.006-5.863L1.64,8.114l5.887-0.855 l2.632-5.334l2.633,5.334l5.885,0.855l-4.258,4.152L15.422,18.129z"/>
</g>
</pattern>
</defs>
<g fill="url(#patt)" stroke="orange" >
<circle cx="450" cy="300" r="100"/>
</g>
</svg>
Requirement is to create a pattern of svg in which fill color of each element in the pattern has to be manipulated.
Only when you create all colored shapes inside the <pattern> yourself:
<svg-pattern colors="green,red,blue,yellow"></svg-pattern>
<svg-pattern colors="purple,hotpink,hotpink,purple"></svg-pattern>
<script>
customElements.define("svg-pattern", class extends HTMLElement {
connectedCallback() {
let colors = this.getAttribute("colors").split(",");
let star = `v20h21v-20h-21zm15.4 18-5.3-2.8-5.3 2.8 1-5.9-4.3-4.2 5.9-.9 2.6-5.3 2.6 5.3 5.9.9-4.3 4.2 1 6z`;
let id = "unique" + Math.random();
this.innerHTML = `<svg width="180" height="180" style="display:inline-block" viewBox="0 0 200 200">
<defs>
<pattern id="${id}" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
<g stroke="black" strokeWidth="0.5" >
<path fill='${colors[0]}' d="m0 0 ${star}"/>
<path fill='${colors[1]}' d="m20 0 ${star}"/>
<path fill='${colors[2]}' d="m0 20 ${star}"/>
<path fill='${colors[3]}' d="m20 20 ${star}"/>
</g>
</pattern>
</defs>
<g fill="url(#${id})">
<circle cx="100" cy="100" r="100"/>
</g>
</svg>`;
}
});
</script>

Using SVG Pattern as Background

React-Native-svg supports SVG pattern, however, I am not sure how to apply it...
When I try the minimal example from the documentation, I get a blanc screen, white screen.
<View
style={{paddingTop: 20,
height: '100%',
flex: 1,
backgroundColor: 'white'}}>
<Svg width="100%" height="100%" viewBox="0 0 800 400">
<Defs>
<Pattern
id="TrianglePattern"
patternUnits="userSpaceOnUse"
x="0"
y="0"
width="100"
height="100"
viewBox="0 0 10 10">
<Path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" stroke="blue" />
</Pattern>
</Defs>
</Svg>
</View>
Why is that?
As #Robert Longson pointed out in a comment below the Q. You need a shape (like a rect or ellipse) with the id given in the pattern.
<Svg width="100%" height="100%" viewBox="0 0 800 400">
<Defs>
<Pattern
id="TrianglePattern"
patternUnits="userSpaceOnUse"
x="0"
y="0"
width="100"
height="100"
viewBox="0 0 10 10"
>
<Path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" stroke="blue" />
</Pattern>
</Defs>
<Rect fill="none" stroke="blue" x="1" y="1" width="798" height="398" />
<Ellipse
fill="url(#TrianglePattern)" // make sure this is the id given in the pattern
stroke="black"
strokeWidth="5"
cx="400"
cy="200"
rx="350"
ry="150"
/>
</Svg>

SVG transforming polygon to rectangle

Is it possible to convert the following polygon svg to a rectangular shaped. The internal pattern should also be converted along too. Also since this is a cutout of a bigger pattern, I am using feMorphology filter to show where the clipPath and what shape the clipPath is in.
XML
<svg id="SvgjsSvg1008" width="550" height="650" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs">
<defs id="SvgjsDefs1009">
<clipPath id="SvgjsClipPath1022">
<polygon id="SvgjsPolygon1015" points="131,55 131,218 90,280 5,235">
</polygon>
</clipPath>
<filter id="dilate_shape">
<feMorphology operator="dilate" in="SourceGraphic" radius="5" />
</filter>
</defs>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="550" height="650" viewBox="0 0 550 650" xml:space="preserve">
<g transform="matrix(1,0,0,1,0,0)" clip-path="url("#SvgjsClipPath1022")">
<g filter="url("#dilate_shape")">
<polygon points="131,55 131,218 90,280 5,235" fill="blue" fill-opacity="0.5" clip-path="url("#SvgjsClipPath1019")"></polygon>
</g>
<g transform="matrix(1,0,0,1,0,0)" clip-path="url("#SvgjsClipPath1022")">
<image xlink:href="https://www.dropbox.com/pri/get/3574%20%5BConverted%5D.svg?_subject_uid=360738345&raw=1&size=1280x960&size_mode=3&w=AADi5fkmMPJI2i6WvcO3faWWR_30_D8f5IdWsJhFarM2JA" x="-75" y="-75" width="150" height="150" transform="matrix(1,0,0,1,109,185)"></image>
</g>
</g>
</svg>
</svg>

Can I add a mask to an svg-element without using an id?

I want to assign a svg-mask to a svg-image. I can make this work using an id on the mask like this:
<svg id="svg1" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<mask id="mask">
<circle cx="100" cy="100" r="100" fill="white"></circle>
</mask>
</defs>
<rect x="0" y="0" width="200" height="200" fill="red" mask="url(#mask)"></rect>
</svg>
However I want to load this svg multiple times, with a different id in the svg-tag. Therefore I will generate duplicates of the '#mask'-id. Using multiple id's is invalid code. So I want to use a class to refer to the appropriate mask. That means I cannot use the mask=url()-technique.
<svg id="svg2" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<mask class="mask">
<circle cx="100" cy="100" r="100" fill="white"></circle>
</mask>
</defs>
<rect x="0" y="0" width="200" height="200" fill="red" mask="url(can't use this)"></rect>
</svg>
Is there a way I can apply a mask to the rect element if the mask has a class instead of id? Maybe using javaScript or some other way I didn't think of.
The full story/context:
I am actually making an svg image slider-module for Joomla with php. This php generates a module containing javascript, css and an svg. I use the javascript to animate the mask.
I do actually have it working with unique id's. I was just wondering if there is a way to assign a mask to an element without referring to id's. I may want to do this because my code is getting a bit more confusing to read, because I have to use some php in my javascript/svg and css for each unique id.
No. You can only reference masks via an id. You cannot reference SVG masks any other way.
According to your description I understand you have a identical grafical entity you want to mask with different forms, multiple times. Write that down DRY:
<!-- start with an invisible svg that only contains mask definitions -->
<svg width="0" height="0"
xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- first, you have a circular mask -->
<mask id="circle-mask">
<circle cx="100" cy="100" r="80" fill="white" />
</mask>
<!-- then, you have a different mask, lets say a diamond -->
<mask id="diamond-mask">
<polygon points="100,20 180,100 100,180 20,100" fill="white" />
</mask>
</defs>
</svg>
<!-- further into your document, you want to mask a rectangle -->
<svg id="svg1" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<!-- reference the circle mask -->
<rect x="0" y="0" width="200" height="200" fill="red" mask="url(#circle-mask)" />
</svg>
<!-- with the circle again, as often as you want, nothing changes -->
<svg id="svg2" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<!-- the mask is the same, so no difference to above -->
<rect x="0" y="0" width="200" height="200" fill="red" mask="url(#circle-mask)" />
</svg>
<!-- and now with the diamond; that one is different -->
<svg id="svg3" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<!-- if the mask changes, you need to change the reference -->
<rect x="0" y="0" width="200" height="200" fill="red" mask="url(#diamond-mask)" />
</svg>
You could also reference the masks in a stylesheet and give your referencing elements a class according to the mask shape:
.masked.circular rect {
mask: url(#circle-mask);
}
.masked.diamond rect {
mask: url(#diamond-mask);
}
<svg width="0" height="0"
xmlns="http://www.w3.org/2000/svg">
<defs>
<mask id="circle-mask">
<circle cx="100" cy="100" r="80" fill="white" />
</mask>
<mask id="diamond-mask">
<polygon points="100,20 180,100 100,180 20,100" fill="white" />
</mask>
</defs>
</svg>
<svg id="svg1" class="masked circular" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="200" height="200" fill="red" />
</svg>
<svg id="svg2" class="masked circular" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="200" height="200" fill="red" />
</svg>
<svg id="svg1" class="masked diamond" width="5cm" height="5cm" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg">
<rect x="0" y="0" width="200" height="200" fill="red" />
</svg>

Adding image to SVG circles

I'm trying to add some background image to SVG nodes "circle".
I have read a lot of stackoverflow answer and everybody is saying that we need to add a node into a to define our image.
I tried this but my image is not displaying at all.
Here is a fiddle of my code: https://jsfiddle.net/baapu6wz/ .
What did I miss ?
<svg baseProfile="full" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" height="390" width="1629">
<g transform="translate(40,0)">
<g>
<line y2="149.3060251652327" x2="819.8567597731511" y1="222.22245513917517" x1="854.7332277213098" style="stroke: #999;" stroke-width="5"></line>
<line y2="213.47136779636722" x2="768.9096407109324" y1="213.47136779636722" x1="768.9096407109324" style="stroke: #999;" stroke-width="5"></line>
<line y2="213.47136779636722" x2="768.9096407109324" y1="149.3060251652327" x1="819.8567597731511" style="stroke: #999;" stroke-width="5"></line>
</g>
<g>
<g transform="translate(854.7332277213098, 222.22245513917517)">
<circle fill="url(#image1);" fillOpacity="0.5" r="16"></circle>
<text x="20" dy="3">pagx</text>
</g>
<g transform="translate(768.9096407109324, 213.47136779636722)">
<circle fill="url(#image1);" fillOpacity="0.5" r="10"></circle>
<text x="20" dy="3">xzreds</text>
</g>
<g transform="translate(819.8567597731511, 149.3060251652327)">
<circle fill="url(#image1);" fillOpacity="0.5" r="14"></circle>
<text x="20" dy="3">jzkcwv</text>
</g>
</g>
</g>
<defs>
<pattern width="16" height="16" patternUnits="userSpaceOnUse" y="0" x="0" id="image1">
<image xlink:href="https://www.google.fr/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png" height="16" width="16" y="0" x="0"></image>
</pattern>
</defs>
You have a typo.
fill="url(#image1);"
should be
fill="url(#image1)"
Remove the semicolon.
https://jsfiddle.net/baapu6wz/1/

Categories