Changing SVG image attributes by button click using javascript/jquery - javascript

I have created one svg door image using Adobe illustrator.The image has 3 components
Door body
Glass part in center of the door
Door handle. >>
I want change the this 3 attributes by clicking buttons like changing handle, color, body material etc.
I have open this svg file in dreamweaver and it's looking weird with long image links and codes.
I don't know where to start with.
Thanks
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="612px" height="792px" viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
<rect x="146.889" y="134.444" fill="#6B4520" stroke="#000000" stroke- miterlimit="10" width="328.889" height="487.777"/>
<path fill="#BDE5F1" stroke="#000000" stroke-miterlimit="10" d="M372.998,351.667c0,38.2-25.577,67-66.998,67
c-41.421,0-71.002-28.8-71.002-67c0-38.2,27.579-64.667,69- 64.667C345.419,287,372.998,313.467,372.998,351.667z"/>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="155.665" y1="352.25" x2="174.25" y2="352.25">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="0" style="stop-color:#603913"/>
<stop offset="0" style="stop-color:#000000"/>
<stop offset="0.0161" style="stop-color:#000000"/>
<stop offset="0.3333" style="stop-color:#D9CDC0"/>
<stop offset="0.5161" style="stop-color:#000000"/>
<stop offset="0.8763" style="stop-color:#FFFFFF"/>
</linearGradient>
<polygon fill="url(#SVGID_1_)" stroke="#000000" stroke-miterlimit="10" points="171.333,430.556 164.958,434 159.111,430.556
155.665,344.667 159.111,272.778 164.958,270.5 171.333,272.778 174.25,344.25 "/>
</svg>

It's reasonably simple, the most important part is you include the svg within the html not simply as an image src attribute. The following is not dreamweaver specific.
For example:
<body>
<!-- this won't work well -->
<img src="/images/door.svg>
...
<!-- this will work very well -->
<svg>
<path></path>
<path></path>
</svg>
...
</body>
Now just like any other element you can give the svg and path elements id's and classes
<svg id="door">
<path id="handle"></path>
<path id="window"></path>
</svg>
From here you can use event listeners to those specific elements for example (with jQuery) to run off other functions for the customization of these svg elements.
$('#handle').on('click', function(){
$(this).css('fill', 'blue') // change path fill to blue
})
path's and other svg elements can more or less be styled with css which makes this a lot easier.
This isn't a copy and paste answer, but I hope it helps you!

Related

How can I make a SVG crop as page is shrinked (resized) instead of resizing the svg itself

My goal is to make my SVG act the same way as Netlify's SVG.
SVG Code
<svg min-width="1152" min-height="523" viewBox="0 0 1152 523" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M592 383C457.295 487.224 134.333 527 0 522V0H1154V172C1001.67 191 729 277 592 383Z" fill="url(#paint0_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="577" y1="0" x2="577" y2="522.669" gradientUnits="userSpaceOnUse">
<stop stop-color="#04724D"/>
<stop offset="1" stop-color="#23E8A5"/>
</linearGradient>
</defs>
</svg>
Html Code
<div class="home_background">
<a class="btn btn-white btn-right">Sign Up</a>
</div>
I am also using gatsby.js, although it doesn't affect the end result.

How to fill gradient svg with solid color on hover

Is it possible to do that with just css? I've got my svg with predefined gradient that I would like to fill with a color on hover in css. What I tried was embedding the svg tag in html structure and then adding a class to path that I would then style in css with fill property. This didn't work though, how should I approach this issue?
SVG tag for reference:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<defs>
<style>
.be51c222-80b4-489f-b2dd-486e23c9eef8{fill:url(#a89527f1-b302-44b4-9a05-0e6cac241929);}
</style>
<linearGradient id="a89527f1-b302-44b4-9a05-0e6cac241929" x1="12.05" x2="11.97" y1="23.94" y2="4.41" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#c41230"/>
<stop offset="1" stop-color="#f62028"/>
</linearGradient>
</defs>
<title>
slide-down
</title>
<g id="a50b190a-9952-4444-9199-5e8e5ee16a51" data-name="Warstwa 2">
<g id="bf15b3ba-4a89-4930-a912-ff1c5832ba6d" data-name="Warstwa 1">
<path d="M24,12A12,12,0,1,0,12,24,12,12,0,0,0,24,12ZM7,13h4V5h2v8h4l-5,6Z" class="be51c222-80b4-489f-b2dd-486e23c9eef8 icon-slide"/>
</g>
</g>
</svg>
Just use the :hover pseudo selector.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24">
<defs>
<style>
.be51c222-80b4-489f-b2dd-486e23c9eef8{fill:url(#a89527f1-b302-44b4-9a05-0e6cac241929);}
.be51c222-80b4-489f-b2dd-486e23c9eef8:hover{fill:blue;}
</style>
<linearGradient id="a89527f1-b302-44b4-9a05-0e6cac241929" x1="12.05" x2="11.97" y1="23.94" y2="4.41" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#c41230"/>
<stop offset="1" stop-color="#f62028"/>
</linearGradient>
</defs>
<title>
slide-down
</title>
<g id="a50b190a-9952-4444-9199-5e8e5ee16a51" data-name="Warstwa 2">
<g id="bf15b3ba-4a89-4930-a912-ff1c5832ba6d" data-name="Warstwa 1">
<path d="M24,12A12,12,0,1,0,12,24,12,12,0,0,0,24,12ZM7,13h4V5h2v8h4l-5,6Z" class="be51c222-80b4-489f-b2dd-486e23c9eef8 icon-slide"/>
</g>
</g>
</svg>

Assigning an (x,y) position to svg element when loading with Snap

I have successfully loaded an SVG element onto my webpage and it displays correctly.
The problem is that I need it to be in a certain position on my page. Since I am not loading it through html, I cannot assign a div and modify position using css.
I have taken a look through Snap.svg API references and some examples. It has pointed me into trying Element.attr.
I am also aware of using Element.animate({transform: 'tx,y'}); but I am looking for a solution of initial placement upon loading.
Here is my code along with what I tried:
window.onload = function() {
var s = Snap(800,800);
Snap.load( "/svg/RedBar-01.svg", function( f ) {
s.append( f ); //add the loaded svg fragment into the DOM
var element = s.select('#line');
element.animate({
fill: "purple",
}, 1000);
element.attr({
x:100, //Setting this
y:500 // or this doesnt seem to change the position at all
});
//Find out how to position this element..
});
Does anyone have an idea of how I can assign an (x,y) position for my svg element? Thanks for any help I can get.
Here is the svg file code to make it more clear of what I am working with:
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 20.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="redBar" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 113.9 3.7" style="enable-background:new 0 0 113.9 3.7;" xml:space="preserve">
<style type="text/css">
</style>
<g id="line">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="1.239177e-04" y1="29.3381" x2="113.9399" y2="29.3381" gradientTransform="matrix(1 0 0 1.3293 0 -37.1699)">
<stop offset="1.075269e-02" style="stop-color:#EC1C24"/>
<stop offset="0.1548" style="stop-color:#EC2026"/>
<stop offset="0.2961" style="stop-color:#ED2C2A"/>
<stop offset="0.436" style="stop-color:#EE3F32"/>
<stop offset="0.5" style="stop-color:#EF4B37"/>
<stop offset="0.5483" style="stop-color:#EE4334"/>
<stop offset="0.7058" style="stop-color:#ED2D2B"/>
<stop offset="0.8586" style="stop-color:#EC2026"/>
<stop offset="1" style="stop-color:#EC1C24"/>
</linearGradient>
<path class="st0" d="M113,3.7H1c-0.5,0-1-0.4-1-1L0,1c0-0.5,0.4-1,1-1l112,0c0.5,0,1,0.4,1,1v1.7C113.9,3.2,113.5,3.7,113,3.7z"/>
</g>
</svg>

Equivalent SVG transform for new coordinate system

SVG is embedded in an object tag which has some dimensions (w1,h1). The user can zoom and pan to an arbitrary region in the SVG and wants to retain that view.
I have the transform of the SVG with old dimensions. How to compute the transformation for the SVG to retain the previous view for the new dimensions(w2, h2)?
Here is an example HTML, the SVG is embedded in the object tag
In this example, (w1,h1) are (100%,100%) and (w2,h2) can be (50% ,50%)
<html>
<body>
<object class="auto-capital-svg-content" data="1.svg" width="100%" height="100%" type="image/svg+xml">
</object>
</body>
</html>
Here is a sample SVG
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" height="150" width="400" style="" >
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1"></stop>
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1"></stop>
</linearGradient>
</defs>
<g id="viewport" transform="matrix(6,0,0,6,200,200)">
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)"></ellipse>
<text fill="#ffffff" font-size="45" font-family="Verdana" x="150" y="86">SVG</text>
</g>
</svg>
This is what I thought : calculate the scale based on the new/old dimensions such that aspect ratio is preserved and scale the transform. But this did not take care of the translation (tx,ty) in the matrix {a,b,c,d,tx,ty}.What should be done here?

Why are the gradients in this SVG displaying as black?

I have made an svg and added it to my page but it has some rather unusual behaviour, as the page is loading I can see the SVG on the page(looks fine the gradients are showing, see below image. Also I have 2 SVG files One the logo and the other the 'K' gets hidden after loading).
After the page loads however for some reason the gradients disappear and I am left with black ascenders and descenders. (see Below)
But things get weirder still as if I click the green circle button, it causes the side bar to collapse Angular then hides the 'Logo' SVG and displays the 'K' SVG. I only have to hit this toggle once and it correctly the gradient issue. I can hide the 'K' & show the 'Logo' again and everything is perfectly fine. See below image of after toggling hide/show of sidebar.
Here is the SVG Code perhaps it is something it? I would really love some help with this it is very strange behaviour and I am not really sure how to solve it.
Logo SVG:
<!-- BEGIN LOGO SVG -->
<div class="logo" ng-hide="sidebarCollapsed">
<svg version="1.1" id="logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 443.7 1602 312.6" style="enable-background:new 0 443.7 1602 312.6;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#accend_1_);}
.st1{fill:url(#decend_1_);}
.st2{fill:#FFFFFF;}
</style>
<g id="k">
<linearGradient id="accend_1_" gradientUnits="userSpaceOnUse" x1="-6.7993" y1="1185.7142" x2="42.6791" y2="1114.1494" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="accend" class="st0" points="78.4,582.9 78.4,445 0,445 0,707.1 79,582.9 "/>
<linearGradient id="decend_1_" gradientUnits="userSpaceOnUse" x1="72.7276" y1="1092.825" x2="1.3943" y2="1202.1583" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="decend" class="st1" points="146.1,596.7 105,658.2 162.4,749.1 253.6,749.1 "/>
<polygon id="branch" class="st2" points="78.4,699.2 78.4,750 0.3,750 0.3,707.1 165.2,444.7 247,444.7 "/>
</g>
<g id="i_1_">
<rect id="title" x="280.3" y="443.7" class="st2" width="68.3" height="52"/>
<rect id="stalk" x="280.3" y="519.9" class="st2" width="68.3" height="228.9"/>
</g>
<path id="n" class="st2" d="M541.7,749.1V624c0-25.7-5-47.3-35.7-47.3c-31.7,0-39.2,20.7-39.2,48v124.5h-68.7V520.2h64v24.5h0.9
c14.4-23.5,34.8-32.3,62.4-32.3c19.4,0,43.6,7.5,58.6,19.8c21.9,18.2,26.3,47,26.3,74v143.3h-68.7V749.1z"/>
<path id="d" class="st2" d="M830.8,445v94.4c-18.8-19.1-41.7-27.3-68-27.3c-69,0-113.8,55.2-113.8,121.6
c0,67.7,44.2,122.6,114.4,122.6c27,0,53.9-10.3,68.3-32.3h5.6v21.9h62.7V445H830.8L830.8,445z M774,692.6
c-34.2,0-57.4-25.7-57.4-58.9s25.1-57.4,58.3-57.4c32.9,0,57.7,24.5,57.7,57.4C832.7,667.2,808.2,692.6,774,692.6z"/>
<path id="r" class="st2" d="M1015.1,623v125.7h-68.3V519.9h64.3v24.5h0.9c11.9-23.5,31-32.3,57.4-32.3v69
C1038.9,582,1015.1,587.6,1015.1,623z"/>
<path id="e" class="st2" d="M1322,637.2c0-69-50.8-125.1-121-125.1c-67.1,0-120.1,56.4-120.1,122.9c0,66.8,54.5,121.3,121.3,121.3
c51.4,0,91.9-32.3,111.9-79.3H1244c-11.3,15.7-23.2,21.3-41.7,21.3c-27,0-49.5-11.9-53.6-43.3h171.5
C1321.4,651.9,1322,643.1,1322,637.2z M1149.6,608c5.3-21.9,27.3-39.2,52-39.2c24.8,0,46.7,17.2,52,39.2H1149.6z"/>
<path id="dlast" class="st2" d="M1533,445v94.4c-18.8-19.1-42.3-27.3-69-27.3c-69,0-114.1,55.2-114.1,121.6
c0,67.7,44.2,122.6,114.4,122.6c27,0,53.6-10.3,68-32.3h3.8v21.9h65.8V445H1533L1533,445z M1475,692.6c-34.2,0-57.4-25.7-57.4-58.9
s25.1-57.4,58.3-57.4c33.2,0,57.7,24.5,57.7,57.4C1533.7,667.2,1509.2,692.6,1475,692.6z"/>
</svg>
</div>
<!-- END LOGO SVG -->
'K' SVG:
<!-- BEGIN MARK SVG -->
<div class="mark" ng-show="sidebarCollapsed">
<svg version="1.1" id="mark" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 444.7 253.6 305.4" style="enable-background:new 0 444.7 253.6 305.4;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#accend_1_);}
.st1{fill:url(#decend_1_);}
.st2{fill:#FFFFFF;}
</style>
<g id="k">
<linearGradient id="accend_1_" gradientUnits="userSpaceOnUse" x1="-6.7993" y1="1185.7142" x2="42.6791" y2="1114.1494" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="accend" class="st0" points="78.4,582.9 78.4,445 0,445 0,707.1 79,582.9 "/>
<linearGradient id="decend_1_" gradientUnits="userSpaceOnUse" x1="72.7276" y1="1092.825" x2="1.3943" y2="1202.1583" gradientTransform="matrix(3.135 0 0 -3.135 0 4205.7539)">
<stop offset="0" style="stop-color:#55C953"/>
<stop offset="0.2752" style="stop-color:#52AC55"/>
<stop offset="0.8681" style="stop-color:#49645A"/>
<stop offset="1" style="stop-color:#47535B"/>
</linearGradient>
<polygon id="decend" class="st1" points="146.1,596.7 105,658.2 162.4,749.1 253.6,749.1 "/>
<polygon id="branch" class="st2" points="78.4,699.2 78.4,750 0.3,750 0.3,707.1 165.2,444.7 247,444.7 "/>
</g>
</svg>
</div>
<!-- END MARK SVG -->
If the SVGs look okay when viewed in the browser, then it is unlikely to be the SVGs themselves.
My first suspicion would fall on the JS in your webapp and/or the way you are including the SVGs on your page.
How are the SVGs added to your page? Are the included using an <img> or <object>, or are you including them inline in your page? If it's the latter, then I would suggest the likely cause is the fact that you have duplicate id attributes in your SVGs. For example, both SVGs have gradients named accend_1_ and decend_1_. All ids need to be unique. Try giving them different ids.
If you are not inlining them, then please supply more information about how you are using them.
You have multiple elements with the same id value in the html file from each SVG fragment you are including for instance you have two different linearGradient elements both having id="accend_1_" This is invalid. All id values must be unique within a file.

Categories