SVG transforming polygon to rectangle - javascript

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>

Related

How to animate SVG path polymorphing circle images?

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>

How can I make a toggle to toggle the visibility of an inline SVG?

I'm making a website where you can create your own character in order to learn more about SVGs. I want the user to be able to select different poses.
I was wondering how I could toggle the visibility of an SVG on the website to make one disappear and another appear.
Here is my SVG code:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 720 720" style="enable-background:new 0 0 720 720;" xml:space="preserve">
<g id="skin">
<circle class="skin" cx="364.42" cy="383" r="278" />
</g>
<g id="mouth">
<path class="mouth" d="M172.92,383c127.67,0,255.33,0,383,0c0,105.05-86.45,191.5-191.5,191.5S172.92,488.05,172.92,383z"/>
</g>
<g id="hair">
<path class = "hair" d="M107.4,276.86c-2.76-50.59,10.76-81.24,24.2-100.13C189.57,95.31,331.92,112,341.92,57.91
c2.04-11.03-2.07-21.46-6.93-29.61c18.47-6.31,81.92-25.39,151.28,3.28c94.59,39.09,121.88,137.21,127.56,160.84
c7.93,32.98,7.18,61.32,5.46,79.42c-38.79-64.73-78.17-85.57-107.42-92.42c-43.32-10.15-60.72,11.26-139.64,11.71
c-67.77,0.39-78.13-15.27-119.49-10.14C216.75,185.45,165.19,204.69,107.4,276.86z"/>
</g>
<g id="eyes">
<g>
<circle class = "eyes" cx="251.17" cy="271.25" r="52.4"/>
<circle class = "eyes" cx="477.67" cy="271.25" r="52.4"/>
</g>
</g>
<g id="clothing">
<rect x="236.92" y="644.4" width="255" height="180"/>
</g>
<g id="tie">
<rect class="tie" x="341.82" y="653.68" transform="matrix(0.7071 0.7071 -0.7071 0.7071 584.9371 -59.6038)" class="st0" width="45.2" height="45.2"/>
<path class="tie" d="M364.95,927.93c-6.29-12.71-12.59-25.42-18.88-38.13c3.44-63.19,6.89-126.39,10.33-189.58
c5.1,0.25,10.2,0.49,15.29,0.74c4.13,62.75,8.25,125.49,12.38,188.24C377.7,902.11,371.32,915.02,364.95,927.93z"/>
</g>
</svg>
The SVG is just a sample right now before I make the actual assets.

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/

SVG defs use relation between different figures Firefox

We've got a simply code, which works cross-browser:
<html>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="100">
<circle id="circ" cx="120" cy="40"
r="30" fill="green"/>
<rect id="rect" x="10" y="10"
width="60" height="60" fill="blue">
<set attributeName="fill-opacity" to="0.5"
begin="circ.mouseover" end="circ.mouseout"/>
</rect>
</svg>
When I try to use the elements in defs block I'm losing relation between two rectangles in Firefox browser.
<html>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="100">
<defs>
<circle id="circ" cx="120" cy="40"
r="30" fill="green"/>
<rect id="rect" x="10" y="10"
width="60" height="60" fill="blue">
<set attributeName="fill-opacity" to="0.5"
begin="circ.mouseover" end="circ.mouseout"/>
</rect>
</defs>
<use id="use_circ.rectangles" xlink:href="#circ" />
<use id="use_rect.rectangles" xlink:href="#rect" />
</svg>
I've read something about relation here http://www.petercollingridge.co.uk/data-visualisation/mouseover-effects-svgs? - actually this words
"Note that this effect does not work in Firefox Firefox 6 and earlier (I think), which is perhaps the biggest drawback of this method. "
I need to press the button to move(change) another element.
I also tried to make something like this, to set relation effect:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Button</title>
<script type="text/javascript" language="javascript">
function turn_right(button, miliSec)
{
document.getElementById("circ_left_position").setAttribute('visibility','hidden');
setTimeout(function() {
button.parentNode.setAttribute('xlink:href','#rect.right_position');
}, miliSec);
document.getElementById("circ_right_position").setAttribute('visibility','visible ');
}
function turn_left(button, miliSec)
{
document.getElementById("circ_right_position").setAttribute('visibility','hidden ');
setTimeout(function() {
button.parentNode.setAttribute('xlink:href','#rect.left_position');
}, miliSec);
document.getElementById("circ_left_position").setAttribute('visibility','visible ');
}
</script>
</head>
<body style="margin:0; border:0">
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="200" height="100">
<defs>
<g id="rect.left_position" onclick="turn_right(this,500)">
<rect x="10" y="10" width="60" height="60" fill="blue"/>
<circle id="circ_left_position" cx="120" cy="40" r="30" fill="green"/>
<animateTransform id="trigger1" begin="click"
attributeName="transform" type="rotate" additive="replace"
from="0 70 70" to="10 70 70" dur="0.5s" fill="freeze" />
</g>
<g id="rect.right_position" onclick="turn_left(this,500)">
<rect x="10" y="10" width="60" height="60" fill="blue" transform="rotate(10 70 70)"/>
<circle id="circ_right_position" cx="120" cy="40" r="30" fill="green"/>
<animateTransform id="trigger1" begin="click"
attributeName="transform" type="rotate" additive="replace"
from="0 70 70" to="-10 70 70" dur="0.5s" fill="freeze" />
</g>
</defs>
<use id="positions.rectangles" xlink:href="#rect.left_position" />
</svg>
</body>
In Chrome and FF we get different results. Farther, I don't understand difference in browsers. I'm sure, there exist a simple solution.
A use does not copy the animation this is not expected behavior in SVG 1.1 (this is not a firefox issue)
Smil in SVG 2 will address this.
What you can do is to use scripting to clone each animation and append them to the use tag. Perhaps on a onload event. However I believe this will not work for your specific code set because specify an id.

Categories