Change small elements (SVG) in main SVG image - javascript

i want to ask you about change SVG elements into SVG main element.
Let's suppose that the black square is a main SVG element. I want to change element 1,2 and 3 to diffrent SVG element. I need to do this by JS code but i don't know how to prepare SVG image for this action. When i simply change the path of element in SVG tag, the changed element isn't in good location on main SVG image.
What i will need to know about SVG and changing SVG elements path to achieve wanted result? Because, copying the path from new SVG image, just to main SVG image as element doesn't work well
Maybe easiest way to understand it, is the shoe customize. On main SVG i have a shoe image with raw elements of shoe (TONGUE and HEEL). I have 5 diffrent TONGUES and HEELS. When i click on shoe TONGUE, i want to be able to choose one of five TONGUES (same with HEEL). When i choose new TONGUE for shoe, the main SVG image need to change TONGUE to new choosen TONGUE (same with HEEL).
I think that i need to change element path to change the image but i don't know if it's a proper way
Thank You in Advance,
Best Regards.

I would use <symbol>s with the same viewBox or al least the same ratio. You can <use> those symbols and the x,y, width and height would be always the same for the same spot.
Next comes an example where I'm changing the icon dynamically on click.
const SVG_XLINK = "http://www.w3.org/1999/xlink";
demo.addEventListener("click",()=>{
let actual = volume.getAttribute('xlink:href');
if(actual == "#volume_up"){
volume.setAttributeNS(SVG_XLINK, 'xlink:href', '#volume_off');
}else{volume.setAttributeNS(SVG_XLINK, 'xlink:href', '#volume_up');}
})
svg{border:1px solid;width:90vh}
<svg id="demo" viewBox = "0 0 100 100">
<symbol id="volume_up" viewBox='0 0 24 24'>
<title>volume up</title>
<path d='M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z'></path>
</symbol>
<symbol id="volume_off" viewBox='0 0 24 24'><title>volume off</title>
<path d='M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z'></path>
</symbol>
<use id="volume" xlink:href="#volume_off" x="35" y="35" width="30" height="30"/>
</svg>

Related

move image using java script and html css

I want to move a image in a path using js and html.
is that doable?
please check the image to get better idea about my question. are there any example codes or libraries? so I can study and edit to match into my case.
There are multiple ways to approach this problem.
Modify html image css styling via javascript.
add css styling via javascript.
styling to move/rotate : transform: translate(20px,10px) rotate(0.5turn);
change styling using pure css animations #keyframes more here
Display stuff on <canvas> element via javascript more here
Animated svg, or svg with css animation.
Inline svg animated via javascript or css.
I am for now just going to demonstrate the svg approach.
SVG approach (no javascript)
My preferred approach would be to create a svg containing multiple images, and then animate it. The bellow example is just using circle objects, but images should work too using <image href="">.
<svg viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<path id="movepath" d="M 5 5 C 10 10, 20 10, 25 5" stroke="#aaa" stroke-width="1" fill="none" />
<circle cx=5 cy=5 r=2 fill="#aaa"/>
<circle cx=25 cy=5 r=2 fill="#aaa"/>
<circle r=1.5 fill="#000">
<animateMotion dur="1s" repeatCount="indefinite">
<mpath xlink:href="#movepath"/>
</animateMotion>
</circle>
</svg>
I don't know if I had understood your question, but I try to answer you.
If I should to do this, "move rocket from earth to sun" I would do it like this:
I'll create 3 img.
img rocket;
img earth;
img sun;
With CSS I will set the Rocket img movement from img earth to sun. Html is not request.

How can I divide an image into hoverable sub sections?

Is there someway I can have hover only access the exact dimensions of the colored areas of this head (not the excess corners of the box model)?
If I was creating a website where you could hover over the sections of the human body and click for information regarding the clicked section, would I have to piece the body together with individual divs or is there a better way to divide an image into hover selectable sections? (not sure if im using the correct terminology!)
Just to reiterate, I only want to be able to select the colored areas in their exact dimensions (not white space outside of the colored sections/outside of the box model). Any suggestions?
Maybe <map>/<area> elements could of help: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area
HTML <map> tag is what you are looking for.
An image-map is an image with clickable areas.
The required name attribute of the element is associated with
the 's usemap attribute and creates a relationship between the
image and the map.
The element contains a number of elements, that defines
the clickable areas in the image map.
You can have your detailed step-by-step turorial HERE and some detailed explanation HERE.
If your image would consist of strict rectangles only there would be easier options.
Anyway, you can load the image into a vector drawing application like Illustrator and trace the outlines of the shapes by hand. After that's done export the drawing as a .svg.
If you take a look at the svg file you will see that the individual shapes are stored as tags. For example:
<path fill="#44CACF" d="M42.124,213.07l64.5-1l-1.5,66l-51.5,35C53.624,313.07,14.124,246.57,42.124,213.07z"/>
If you give these an id attribute
<path fill="#44CACF" id="partC" d="M42.124,213.07l64.5-1l-1.5,66l-51.5,35C53.624,313.07,14.124,246.57,42.124,213.07z"/>
you can access it using javascript and add mouse events as you desire.
Here's an example:
function enter(e) {
e.target.style.opacity = 0.5;
}
function leave(e) {
e.target.style.opacity = 1;
}
document.getElementById("partA").addEventListener("mouseenter", enter);
document.getElementById("partB").addEventListener("mouseenter", enter);
document.getElementById("partC").addEventListener("mouseenter", enter);
document.getElementById("partD").addEventListener("mouseenter", enter);
document.getElementById("partE").addEventListener("mouseenter", enter);
document.getElementById("partA").addEventListener("mouseleave", leave);
document.getElementById("partB").addEventListener("mouseleave", leave);
document.getElementById("partC").addEventListener("mouseleave", leave);
document.getElementById("partD").addEventListener("mouseleave", leave);
document.getElementById("partE").addEventListener("mouseleave", leave);
<svg version="1.0" id="Layer_1" xmlns="&ns_svg;" xmlns:xlink="&ns_xlink;" width="247.741" height="344.813" viewBox="0 0 247.741 344.813" overflow="visible" enable-background="new 0 0 247.741 344.813" xml:space="preserve">
<path fill="#CF454B" id="partA" d="M14.624,131.57c0,0-2-44,13.5-67s32.5-39,55-45.5s40-7.5,55.5-5s36,4,46,12.5s30,30,36.5,39
s15.5,26.5,15.5,35.5s2.5,15,0.5,19.5s-15.5,14-21,15s-201.5,2-201.5,2V131.57z"/>
<path fill="#7F45CF" id="partB" d="M14.124,140.07l203-2.5c0,0,17-9,20-12.5s0.5,11.5,0.5,11.5l-4.5,18l-5.5,23.5l-15,29.5l-170,2.5
C42.624,210.07,5.624,178.57,14.124,140.07z"/>
<path fill="#44CACF" id="partC" d="M42.124,213.07l64.5-1l-1.5,66l-51.5,35C53.624,313.07,14.124,246.57,42.124,213.07z"/>
<path fill="#44CACF" id="partD" d="M142.124,211.57l70.5-0.5c0,0,1.5,88.5-20,104.5s-25-42-51-56L142.124,211.57z"/>
<path fill="#45CE7C" id="partE" d="M108.624,213.57l-1.5,63.5l-53.5,36c0,0,49.5,57.5,124.5,10c0,0-13-23.5-17-32.5s-20.5-24.5-22.5-26
s2-49.5,2-49.5"/>
<g>
<g>
<path fill="none" d="M59.624,333.57c-9-11.5-17-22-23-35.5c-2.5-5.5-5-11.5-6.5-17.5c-0.5-3-0.5-7-2-9.5c-1.5-5-6.5-7.5-9.5-12.5
c-7.5-12.5-22-47.5-15.5-62c3.5-7.5,12.5-5,14.5-13c2-7.5-5.5-17-6.5-24.5c-1-10.5,0-21.5,0-32c0-10-1.5-21,0-31
c2.5-19,20-37.5,31.5-52c11.5-15,27-23.5,44.5-31c13-5.5,28-10.5,42-11.5c10-0.5,19.5,3.5,29,6c20,5.5,38,12,52,28
c13,15.5,21,31,27,50c5,17,10.5,33.5,9,51.5c-2,19.5-16.5,33-21,51.5c6.5,2.5,12.5-1.5,16,6.5c2.5,6.5,0,17-1,23.5
c-1.5,9-2.5,19.5-6.5,27.5c-5,10-14.5,16-19.5,26c-7.5,15.5-1.5,35.5-16.5,47.5c-11.5,9-28.5,13.5-42,18.5c-17,5.5-34,5-52,5
c-15,0-32-0.5-44.5-10.5"/>
<path d="M60.762,332.604c-9.078-11.613-17.466-23.343-23.539-36.839c-3.107-6.904-5.255-13.645-6.37-21.11
c-0.841-5.631-4.562-9.469-8.302-13.416c-6.492-6.854-10.047-17.929-13.238-26.606c-3.649-9.927-7.015-21.035-6.2-31.732
c0.423-5.549,2.972-8.828,7.999-11.088c3.796-1.707,6.611-3.603,7.912-7.725c1.328-4.208-0.39-8.836-1.904-12.738
c-1.039-2.677-2.266-5.276-3.301-7.955c-1.67-4.322-1.583-8.987-1.648-13.553c-0.107-7.544,0.4-15.087,0.439-22.631
c0.042-7.941-0.794-15.854-0.619-23.801c0.327-14.881,7.469-27.208,16.122-38.86c7.877-10.607,16.325-22.004,26.267-30.735
c10.153-8.917,22.654-14.903,35.021-20.081c14.179-5.937,30.953-12.106,46.565-10.361c7.387,0.826,14.504,3.658,21.641,5.597
c6.507,1.769,12.952,3.758,19.259,6.148c12.759,4.834,24.456,12.177,33.223,22.746c8.938,10.775,15.94,22.884,21.225,35.825
c5.654,13.847,9.963,28.944,12.437,43.696c1.249,7.448,1.627,15.179,0.458,22.656c-1.124,7.188-4.419,13.957-7.797,20.319
c-4.792,9.026-10.096,17.707-12.687,27.692c-0.198,0.763,0.053,1.646,0.882,1.917c3.994,1.309,8.962,0.2,12.6,2.284
c5.723,3.278,3.348,14.424,2.539,19.606c-1.952,12.5-2.695,26.565-9.734,37.418c-6.213,9.581-15.568,16.064-19.245,27.304
c-3.225,9.854-2.545,20.52-5.956,30.342c-4.303,12.391-17.536,17.938-28.839,22.344c-12.355,4.817-25.046,9.401-38.232,11.149
c-13.678,1.813-27.839,1.399-41.609,1.084c-12.773-0.292-25.747-2.187-36.148-10.153c-1.531-1.172-3.236,1.277-1.712,2.445
c9.989,7.649,22.168,9.926,34.471,10.567c13.874,0.724,28.131,0.622,41.97-0.614c13.793-1.232,26.558-5.946,39.475-10.632
c10.981-3.983,23.473-8.927,30.333-18.921c5.991-8.729,5.857-20.339,7.578-30.378c1.116-6.509,3.493-12.179,7.467-17.46
c4.03-5.354,9.028-9.867,12.893-15.365c7.248-10.313,7.711-24.044,9.79-36.05c1.379-7.964,4.44-22.313-5.488-26.183
c-3.481-1.357-7.519-0.41-11.113-1.587c0.294,0.639,0.588,1.278,0.881,1.917c3.188-12.286,10.521-22.688,15.877-34.045
c5.766-12.226,6.275-24.966,4.288-38.176c-2.108-14.005-6.555-28.165-11.494-41.417c-4.563-12.247-10.906-23.686-18.659-34.191
c-7.413-10.045-16.488-18.284-27.638-24.006c-11.763-6.036-24.382-9.234-36.968-13.017c-6.304-1.895-12.56-3.687-19.155-4.15
c-7.216-0.506-14.777,1.344-21.713,3.096C97.538,6.597,84.376,12.106,72.02,18.524c-10.839,5.629-20.65,12.879-28.608,22.182
C34.829,50.739,26.2,61.18,19.102,72.324c-7.223,11.34-10.278,22.922-10.105,36.327c0.095,7.343,0.71,14.653,0.604,22.003
c-0.111,7.689-0.652,15.384-0.306,23.075c0.272,6.046,1.634,10.702,4.006,16.22c2.646,6.154,5.938,14.373-1.634,18.324
c-3.538,1.846-6.774,2.956-9.169,6.337c-2.165,3.056-2.443,7.521-2.493,11.111c-0.136,9.845,2.954,19.747,6.165,28.942
c2.935,8.405,6.375,17.402,11.316,24.872c3.981,6.018,9.499,9.415,10.644,17.082c1.08,7.229,3.453,13.727,6.397,20.428
c6.045,13.762,14.749,25.707,23.959,37.49C59.671,336.053,61.946,334.12,60.762,332.604L60.762,332.604z"/>
</g>
</g>
</svg>

CSS Targeting Individual Paths through SVG -> Use tag

I'm having huge problems animating an ellipsis icon to jiggle the little dots up and down in a wave. I suspect that because its in the shadow DOM I can't target the individual path elements specifically, however is there a work-around?
DOM looks like this:
<svg class="icon__vector">
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-ellipsis"></use>
</svg>
Where the href link links to this SVG hardcoded in a sprite sheet in which I can edit if needed.
<svg id="icon-ellipsis" width="100%" height="100%" viewBox="0 0 24 24">
<path className="icon-ellipsis-dotone" d="M6 11.59c0 1.105-0.895 2-2 2s-2-0.895-2-2c0-1.105 0.895-2 2-2s2 0.895 2 2z"></path>
<path className="icon-ellipsis-dottwo" d="M14 11.59c0 1.105-0.895 2-2 2s-2-0.895-2-2c0-1.105 0.895-2 2-2s2 0.895 2 2z"></path>
<path className="icon-ellipsis-dotthree" d="M22 11.59c0 1.105-0.895 2-2 2s-2-0.895-2-2c0-1.105 0.895-2 2-2s2 0.895 2 2z"></path>
</svg>
EDIT:
So i have an ellipsis icon something like this "O O O" and i its loaded in with a <use> tag and i want to be able to target each individual dot and animate them differentely. I can edit the master sprite sheet, use javascript or css however no jquery.
Problem is that there is no way to target the individual paths because they exist in the shadow DOM
You can't use CSS or JS to target the referenced elements through the <use>.
You can animate the targeted sprite directly. However that means that, if the SVG is referenced more than once, all those instances will be animated at the same time.

Adapt Div area to Background img size

I haven't found any solution for this problem but I'm sure that one exists.
I have 4 divs with background images, together comprising a graphical option wheel.
The problem is that each div's background image is triangular, but the area that is occupied by the div is bigger and is a square. When I pass the cursor over each div, it is not working well, because the first div overlaps on top of the second, the second over the third, etc.
I thought about using z-index but that won't work because the first and the second div overlap one another, and so do the third and fourth.
I'm not sure if I've explained my problem very well. If you don't understand something, please let me know.
Here is an image to help you understand what I mean.
Thanks!!
UPDATE WITH CODE
Here is my code:
https://jsfiddle.net/ialex90/x7mx1zqu/
You can only achieve this effect with SVG. See the following base implementation that illustrates how you can both apply CSS and JS to irregular shapes using SVG:
$('path').click(function(e) {
alert(e.target.id);
});
path {
stroke:red;
stroke-width:1;
fill:rgba(255,0,0,0.15);
transition:fill 0.5s;
}
path:hover {
fill:rgba(255,0,0,0.5);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg viewBox="0 0 500 250" width="500" height="250">
<g>
<path id="quadrant1" d="M0,250 A250,250 0 0,1 73,73 L161,161 A125,125 0 0,0 125,250 z" />
<path id="quadrant2" d="M73,73 A250,250 0 0,1 250,0 L250,125 A125,125 0 0,0 161,161 z" />
</g>
</svg>

Fill Svg Path with rects

i am in a situation where i need to Fill Svg path with different rects. here 'different' means each rect will be a separate svg element, and i can access it using id i.e document.getElementById('rect_');
I cannot use 'Patterns' because they fill path but i can't access each element separately .
let say i have path :-
<path d="M 10 10 L 50 10 80 125Z" stroke="red" fill='none' />
Now i need to fill this path with rects. Rect specs are:-
<rect x=0 y=0 width=5 height= 5 stroke="red" />
*I can convert path into points (x y cordinates) but unable to make logic to create rects inside that path.
Explanation:-
Let me explain the whole senerio , i am developing an application in svg in which user can draw his custom path (just like painting) , once he finishes his drawing, path will be closed and then i need to fill that path with 'n' number of 'rects' . now i need to determine how many rects will be drawn and at what place . Rects must be inside that path area.
I need help on this,
thanks.

Categories