SVG hover cancelled when mousing over an object on top - javascript

I have an SVG that had to have text centred both horizontally and vertically.
I would have pasted an image but don't have enough rep points. You can see the graphic at
https://www.dropbox.com/s/tt9ayqr0xugr4m9/link_example.png?dl=0
I need the white around the text to go grey (#eeeeee) when you hover over it. I got that with some simple CSS. I even got it with jQuery and some SVG but the issue is that when you hover over the word about (which needs to stay black all the time), the grey goes back to white as the text is over the circle and cancels the hover. I have been trying for hours and hours to fix this.
My code is:
<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" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<!-- gradient information -->
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="50" y2="100">
<stop offset="0" style="stop-color:#ED7625"/>
<stop offset="1" style="stop-color:#CF202F"/>
</linearGradient>
<a xlink:href="about.php">
<!-- gradient -->
<circle class="gradient-outer" fill="url(#SVGID_1_)" cx="50" cy="50" r="50"/>
<g class="svg-button_1">
<!-- white overlay -->
<circle id="#svg-text_1" class="white-inner" cx="50" cy="50" r="46" stroke="black" stroke-width="0" fill="white" />
<!-- text element -->
<text x="50%" y="50%" dy=".3em" text-anchor="middle">About</text>
</g>
</a>
Any help would be appreciated and I have tried many numerous ways with HTML/CSS/jquery to do it but it also have to be a link, scalable, ratio locked and responsive. (GROAN!!!)

JSBin
The jsbin has your required code. The issue you are facing is because
Text is not inside circle. Create a svg group and make that effect on
the svg group
2>One more point is dont give your id as # i.e <circle
id="#svg-text_1" should be <circle id="svg-text_1"
.svg-button_1:hover #svg-text_1{
fill: grey;
}
SVG is as below
<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" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve">
<!-- gradient information -->
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="50" y2="100">
<stop offset="0" style="stop-color:#ED7625"/>
<stop offset="1" style="stop-color:#CF202F"/>
</linearGradient>
<a xlink:href="about.php">
<!-- gradient -->
<circle class="gradient-outer" fill="url(#SVGID_1_)" cx="50" cy="50" r="50"/>
<g class="svg-button_1">
<!-- white overlay -->
<circle id="svg-text_1" class="white-inner" cx="50" cy="50" r="46" stroke="black" stroke-width="0" fill="white" />
<!-- text element -->
<text x="50%" y="50%" dy=".3em" text-anchor="middle">About</text>
</g>
</a>

Related

SVG Mask Path is cropped

I am trying to build a javascript experiment of a dynamic chain which follows the mouse cursor.
Therefore I am useing a SVG wwith the following path:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 240">
<defs>
<path id="a" d="M143 158q-31-139 9-99" fill="none" stroke-linecap="round"/>
<mask id="b">
<rect x="0%" y="0%" width="100%" height="100%" fill="#fff"/>
<use href="#a" stroke-width="4" stroke-dasharray="6 14" stroke-dashoffset="7" stroke="#000"/>
</mask>
</defs>
<use href="#a" stroke-width="8" stroke-dasharray="6 14" stroke-dashoffset="7" stroke="#333" stroke-opacity=".8" mask="url(#b)"/>
<use href="#a" stroke-width="2" stroke-dasharray="12 8" stroke="#333" stroke-opacity=".8"/>
</svg>
Unfortunately the chain is cropped:
Why is this happening?
You can see the full experiment here (desktop only).
Long story short: A mask works within an object's bounding box, but the bounding box of any element doesn't include the stroke width.
Therefore, the default mask adds 10% padding around the bounding box with its x, y, width, height and maskUnits attributes. This works in most cases, but fails when an element is slim and almost horizontal or vertical.
See the below image: The blue rectangle is your path's bounding box, and the green is the area where the mask does its job. You can see that some of the path sticks out to the left and right.
So you must change the mask attributes to work for you. For example, make it cover the whole image:
<mask id="b" maskUnits="userSpaceOnUse" x="0" y="0" width="100%" height="100%">
I fixed it by adding maskUnits="userSpaceOnUse"
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/maskUnits
(changed the viewBox to better display it in an SO snippet)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 40 300 240">
<defs>
<path id="a" d="M143 158q-31-139 9-99" fill="none" stroke-linecap="round"/>
<mask id="b" maskUnits="userSpaceOnUse">
<rect x="0%" y="0%" width="100%" height="100%" fill="#fff"/>
<use href="#a" stroke-width="4" stroke-dasharray="6 14" stroke-dashoffset="7" stroke="#000"/>
</mask>
</defs>
<use href="#a" stroke-width="8" stroke-dasharray="6 14" stroke-dashoffset="7" stroke="#333" stroke-opacity=".8" mask="url(#b)"/>
<use href="#a" stroke-width="2" stroke-dasharray="12 8" stroke="#333" stroke-opacity=".8"/>
</svg>

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>

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>

How to generate 3d view in the svg?

I am new to svg
Actually we are doing for property interaction. With the help of the svg.
I have slots like this
SVG Path
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="281.333px" height="117.333px" viewBox="0 0 281.333 117.333" enable-background="new 0 0 281.333 117.333"
xml:space="preserve">
<path id="slot_1" fill="#0D8900" d="M189.667,20l-1,37.667h80.667l0.333-37.333L189.667,20z M264.667,53.5L193.5,53.667l0.542-30.208
l70.625,0.708V53.5z"/>
<path id="slot_2" fill="#0D8900" d="M24,20.25l-6.002,37.667h82.668L105,20.583L24,20.25z M94.998,53.416l-70.166,0.167l4.001-29.332
l69.166,0.166L94.998,53.416z"/>
<path id="slot_3" fill="#0D8900" d="M107.997,20.25l-4.001,37.667h81.667l1.332-37.333L107.997,20.25z M179.996,53.416l-69.166,0.167
l3.001-29.332l67.164,0.166L179.996,53.416z"/>
<path id="slot_4" fill="#0D8900" d="M188.176,61.251l-1,40.669h82.668l0.333-40.337L188.176,61.251z M265.177,96.418l-73.167,0.167l0.542-30.875
l72.871-0.121L265.177,96.418z"/>
<path id="slot_5" fill="#0D8900" d="M16.996,60.25l-6.002,40.669h85.669l3.334-40.337L16.996,60.25z M90.996,96.418l-73.167,0.167l5.002-32.335
l70.166,0.166L90.996,96.418z"/>
<path id="slot_1" fill="#0D8900" d="M103.255,60.75l-3.001,40.669h83.668l1.332-40.337L103.255,60.75z M178.256,95.917l-71.167,0.167l2-31.334
l70.165,0.166L178.256,95.917z"/>
<text transform="matrix(1 0 0 1 53.1675 41.9995)" font-family="'MyriadPro-Regular'" font-size="12">A1</text>
<text transform="matrix(1 0 0 1 143.501 41.9995)" font-family="'MyriadPro-Regular'" font-size="12">A2</text>
<text transform="matrix(1 0 0 1 222.8345 41.9995)" font-family="'MyriadPro-Regular'" font-size="12">A3</text>
<text transform="matrix(1 0 0 1 53.1675 81.9995)" font-family="'MyriadPro-Regular'" font-size="12">A4</text>
<text transform="matrix(1 0 0 1 143.501 81.9995)" font-family="'MyriadPro-Regular'" font-size="12">A5</text>
<g>
<path d="M225.052,79.457L224.213,82h-1.08l2.747-8.084h1.259L229.897,82h-1.115l-0.864-2.543H225.052z M227.703,78.641
l-0.792-2.326c-0.18-0.528-0.3-1.008-0.419-1.476h-0.024c-0.12,0.479-0.251,0.972-0.408,1.463l-0.792,2.339H227.703z"/>
<path d="M235.167,74.948c-0.216-0.013-0.492,0-0.792,0.048c-1.655,0.275-2.531,1.487-2.71,2.771h0.036
c0.372-0.492,1.02-0.899,1.883-0.899c1.379,0,2.351,0.995,2.351,2.519c0,1.427-0.972,2.746-2.591,2.746
c-1.667,0-2.758-1.295-2.758-3.322c0-1.535,0.552-2.746,1.319-3.514c0.647-0.636,1.511-1.031,2.495-1.151
c0.312-0.048,0.576-0.061,0.768-0.061V74.948z M234.867,79.445c0-1.115-0.636-1.787-1.607-1.787c-0.636,0-1.224,0.396-1.511,0.96
c-0.072,0.119-0.12,0.275-0.12,0.468c0.024,1.283,0.612,2.23,1.715,2.23C234.255,81.316,234.867,80.56,234.867,79.445z"/>
</g>
</svg>
When user mouse hover any of the slot (**example like this 3d view with the transition **) need to be generated. Each slot will have unique id of the path.
This SVG path one need to generate dynamically based on the mouse hover
Here i have attached the sample svg slots For your reference.
SVG Mouse hover
<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="49.667px" height="60.536px" viewBox="0 0 49.667 60.536" enable-background="new 0 0 49.667 60.536" xml:space="preserve">
<g enable-background="new ">
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="13.4409" y1="17.2715" x2="37.1904" y2="17.2715">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#3D3D3D"/>
</linearGradient>
<polygon fill="url(#SVGID_1_)" points="36.223,10.347 37.19,24.193 14.333,24.335 13.441,10.208 "/>
</g>
<g>
<polygon fill="#B5B6B6" points="13.955,10.157 15.333,24.333 12.667,50 11.802,27.738 "/>
</g>
<g>
<path fill="#226A36" d="M7.566,30.208l3.157-20.865l29.541-0.261l-5.008,21.522L7.566,30.208z M35.783,11.955l-21.467,0.127
l-2.514,15.656l20.296-0.267l2.449-9.984"/>
</g>
<g>
<polygon fill="#B5B6B6" points="40.348,9.097 41.223,21.717 37.514,52.217 35.256,30.603 "/>
</g>
<g>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="22.6021" y1="29.1782" x2="22.602" y2="53.7121">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#3D3D3D"/>
</linearGradient>
<polygon fill="url(#SVGID_2_)" points="35.256,30.603 37.514,51.883 8.726,51.495 7.691,30.333 "/>
</g>
</g>
</svg>
Note: SVG should be in the tiles overview
Kindly guide me how can i achive this. if you have any other easy way to achieve this, Suggestion are welcome ...

Categories