My javascript animated SVG not working in WordPress. Can anybody help with the best practice of how to make an animated SVG work?
My first thought is - is it not working because of the security of having javascript inside an SVG file...
The file works as-is:
https://aau.gagarindigital.dk/wp-content/uploads/2021/07/stack-test-menu_3x.svg
My SVG file looks like this:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 912.83 882.07">
<defs>
<style>
:root {
--color-1: #F2B705;
--color-2: #C30F0E;
--color-3: #264ABA;
--color-4: #009CD2;
--color-5: #E25727;
--color-11: #C29204;
--color-22: #990B0B;
--color-33: #172E73;
--color-44: #006B8E;
--color-55: #BA4620;
}
#c1 {
fill: var(--color-1);
}
#c2 {
fill: var(--color-2);
}
#c3 {
fill: var(--color-3);
}
#c4 {
fill: var(--color-4);
}
#c5 {
fill: var(--color-5);
}
.cls-7 {
fill: #a1ac75;
}
circle:hover:not(.active) {
stroke: #999;
stroke-width: 11.5;
}
circle.active {
stroke: black;
stroke-width: 11.5;
}
line {
stroke: gold;
stroke-width: 4;
}
line.highlight {
stroke: black;
}
</style>
</defs>
<polygon id="fem-kant" class="cls-7" points="456.29 7.49 898.87 329.05 729.82 849.33 182.76 849.33 13.71 329.05 456.29 7.49"/>
<line class="c3 c5" x1="656.32" y1="748.57" x2="133.5" y2="368.62"/>
<line class="c2 c4" x1="258.55" y1="747.22" x2="779.33" y2="368.43"/>
<line class="c1 c4" x1="258.55" y1="747.22" x2="457.43" y2="133.5"/>
<line class="c1 c3" x1="457.43" y1="133.5" x2="657.03" y2="748.57"/>
<line class="c5 c2" x1="133.5" y1="368.62" x2="779.33" y2="368.43"/>
<line class="c1 c2" x1="779.33" y1="368.43" x2="457.43" y2="133.5"/>
<line class="c2 c3" x1="779.33" y1="368.43" x2="657.03" y2="748.57"/>
<line class="c3 c4" x1="258.55" y1="747.22" x2="657.03" y2="748.57"/>
<line class="c4 c5" x1="258.55" y1="747.22" x2="133.5" y2="368.62"/>
<line class="c5 c1" x1="133.5" y1="368.62" x2="457.43" y2="133.5"/>
<a href="#0">
<circle id="c1" cx="455.9" cy="133.5" r="133"/>
</a>
<a href="#0">
<circle id="c2" cx="779.33" cy="368.43" r="133"/>
</a>
<a href="#0">
<circle id="c3" cx="656.32" cy="748.57" r="133"/>
</a>
<a href="#0">
<circle id="c4" cx="256.18" cy="748.57" r="133"/>
</a>
<a href="#0">
<circle id="c5" cx="133.5" cy="368.62" r="133"/>
</a>
<script>
<![CDATA[
var allCircles = document.querySelectorAll("circle");
window.addEventListener('DOMContentLoaded', (event) => {
// Add an click handler to every circle that
// adds the class "active" to the clicked circle.
allCircles.forEach(element => {
element.addEventListener("click", clickHandler);
element.addEventListener("mouseover", mouseoverHandler);
element.addEventListener("mouseout", mouseoutHandler);
});
});
function clickHandler(evt) {
// Clear current selection (remove class "active" from any circle)
allCircles.forEach((circle) => circle.classList.remove("active"));
// Mark clicked circle selected
evt.target.classList.add("active");
// Clear any currently highlighted lines
clearHighlightedLines();
}
function mouseoverHandler(evt) {
let activeCircle = document.querySelector("circle.active");
let hoveredCircle = evt.target;
if (activeCircle && (activeCircle != hoveredCircle)) {
// Get the line that has classes matching both the actibve and hovered circle
let line = document.querySelector("line."+activeCircle.id+"."+hoveredCircle.id);
// Add the class "highlight" to that line
if (line)
line.classList.add("highlight");
}
}
function mouseoutHandler(evt) {
clearHighlightedLines();
}
function clearHighlightedLines() {
// Find the line with class "highlight" (if any)
var line = document.querySelector("line.highlight");
// Remove the class "highlight"
if (line)
line.classList.remove("highlight");
}
//]]>
</script>
</svg>
But the javascript is not working and the SVG file looks like this in WordPress:
https://aau.gagarindigital.dk/sample-page/
If the script should be outside the SVG file - can I link to the script placed at the root of the site. What would a link inside an SVG file look like?
I made a little mistake in my answer to your last question. The
var allCircles = document.querySelectorAll("circle");
part should be inside the DOMContentLoaded event. I believe that if you fix that, it will make a difference.
Related
I am using vanilla javascript to navigate the pages of a comic book. However, I need to setup a condition that checks if the points in the current polygon intersects with the points in the next polygon. If true, I want the viewBox to animate from the current points to the next points, if false let nothing happen (use the default fade transition).
Here is a section of my code
var DELAY = 400;
function nextArea() {
if (isFirstPage() || areaIndex >= areas.length - 1) {
changePage(true);
changeArea();
} else {
fade();
areaIndex++;
setTimeout(changeArea, DELAY);
}
}
function prevArea() {
if (isLastPage() || areaIndex <= 0) {
changePage(false);
changeArea();
} else {
fade();
areaIndex--;
setTimeout(changeArea, DELAY);
}
}
function changeArea() {
if (isFirstPage() || isLastPage()) {
return;
}
var activeArea = areas[areaIndex];
var points = activeArea.getAttribute('points').split(' ');
var xy1 = points[0].split(',');
var xy2 = points[1].split(',');
var xy3 = points[2].split(',');
var box = [xy1[0], xy1[1], xy2[0] - xy1[0], xy3[1] - xy2[1]];
activePage.classList.remove('fade');
activePage.setAttribute('viewBox', box.join(' '));
activeRect = rects[pageIndex - 1];
activeRect.setAttribute('x', xy1[0]);
activeRect.setAttribute('y', xy1[1]);
}
My code repository is here: https://github.com/cnario/svg-carousel
Here is what I have thus far: https://cnario.github.io/svg-carousel/
Here is how I expect it to act: https://read.marvel.com/#book/41323
I suppose this is what you may need: a way to transition the viewBox from one value to another so that every time you have only one part of the svg in the viewBox.
let BB = {};
BB.tomato = tomato.getBBox();
BB.skyblue = skyblue.getBBox();
BB.gold = gold.getBBox();
let radios = document.querySelectorAll("#controls input");
radios.forEach(r =>{
let color = r.dataset.color;
let bb = BB[color];
r.addEventListener("change",()=>{
svg.setAttributeNS(null,"viewBox", `${bb.x} ${bb.y} ${bb.width} ${bb.height}`)
svg.style.height = `${bb.height * 300 / bb.width}px`;
})
})
svg {
width: 300px;
border: 1px solid;
height: 600px;
transition: height 1s;
}
<p id="controls">
<label>tomato: <input type="radio" name="selector" data-color="tomato" /></label>
<label>skyblue: <input type="radio" name="selector" data-color="skyblue" /></label>
<label>gold: <input type="radio" name="selector" data-color="gold" /></label>
</p>
<svg id="svg" viewBox="0 0 100 200">
<g id="tomato">
<circle cx="35" cy="70" r="25" fill="tomato" />
</g>
<g id="skyblue">
<ellipse cx="75" cy="160" rx="15" ry="35" fill="skyblue" />
</g>
<g id="gold">
<polygon fill="gold" points="75,15 60,30 90,30" />
</g>
</svg>
I need to place some html elements over my svg path. How can i do that ?
I looked up for foreignObject but it only allows for whole svg what about the path sections ?
Here is my svg code
<svg id="svg" width="50%" height="50%" fill="none" stroke="#000000" stroke-linejoin="round" enable_background="new 0 0 1000 589" pretty_print="False" version="1.1" viewBox="0 0 271.87 232.08" xmlns="http://www.w3.org/2000/svg">
<g fill="#f9f9f9" fill-rule="evenodd" stroke-width=".97063">
<path d="m109.29 15.045 0.2913-7.5709-3.106-0.0971-21.451-0.97063-21.548-1.3589-48.92-4.2708-3.009-0.29119-0.38825 3.4943-7.2797 75.127-0.67944 7.0856-2.7178 28.634 0.38826 0.0971 13.395 1.2618 1.2618-6.7944 2.4266-1.9413 27.178 2.4266h0.19413l-2.4266-4.7561 12.327 0.87357 30.769 1.7471 19.218 0.87357 3.3002-91.045 0.67944 0.0971 0.0971-2.6207z" data-id="NM" data-name="New Mexico"/>
<path d="m246.35 13.201-0.19413-2.6207-0.0971-2.5236-0.19413-2.5236-3.6884 0.29119-37.563 1.7471-52.705 0.77651-22.519-0.29119-4.1737-0.0971h-1.553l-6.115-0.19413-1.9413-0.0971-4.0766-0.0971-1.9413-0.0971-0.2913 7.5709-0.0971 2.6207h0.58238l23.489 0.58238 24.848 0.29119 0.29119 33.196 1.7471 5.8238 3.8825 3.6884 4.1737 0.19413 0.87356-1.7471 5.7267 5.2414 7.4739 0.7765 1.3589 1.553 2.7178-1.2618 6.7944 3.2031v1.8442l2.5236-0.0971 2.6207-2.2324 4.8532 3.106 4.562 1.6501 3.106-4.2708 9.9004 4.659 3.6884-3.009 3.009-1.1648 2.4266 0.58238 9.1239-2.6207 4.8532 2.0383 4.3678 2.8148 3.7855 0.67944h0.0971l-0.0971-4.3678-1.0677-26.401-0.0971-4.3678-3.7855-19.607-0.58238-2.7178-0.0971-2.5236z" data-id="OK" data-name="Oklahoma"/>
<path d="m210.82 227.22-4.659-17.568v3.3002zm-1.0677-30.866-3.3002 6.212-0.38825 2.0383zm2.6207-4.562 3.106-4.0767-2.2324 1.3589zm10.968-9.9004-7.2797 3.7855 2.0383-0.38825zm0.97063-1.3589 2.0383-1.6501-0.7765 0.19413zm-115.12-162.87-0.67944-0.0971-3.3002 91.045-19.218-0.87357-30.769-1.7471-12.327-0.87357 2.4266 4.7561 10.58 10.58 6.0179 7.0856 7.9592 5.9208 5.6297 10.289 2.1354 10.774 4.562 3.009 3.5913 3.9796 5.1443 1.8442 7.4739 4.7561 3.3972 1.2618 4.659-4.659 1.456-4.9502 2.4266-4.7561 7.5709-3.009 2.9119 1.4559 8.4445 0.67945 7.668 4.7561 5.2414 0.97063-1.456 2.7178 3.009 1.9413 2.8148 3.3972 0.58238 3.5913 1.8442 2.4266 4.2708 10.289 4.2708 3.5913 3.3002 5.4355 4.1737 4.2708 1.8442 0.58238 1.553 11.065 4.562 2.5236 0.19412 3.4943 1.1648-0.29119 7.9592 9.7063 3.9796 0.87357 5.0473 3.009h7.765l5.6297 3.106 6.6974-1.4559-3.009-2.8148-2.7178-8.1533-1.0677-7.0856-1.553-2.3295 0.67944-4.7561-2.0383-0.19413-2.7178-4.4649 3.106 3.3002 3.5913-1.2618 1.9413-5.1444-3.8825-5.2414 5.8238 0.67944 2.7178-4.1737-0.38825-1.456 2.4266-3.2031-0.58238 2.8148 2.7178-2.1354-1.0677-3.7855 3.4943 1.8442 4.4649-2.5236-4.3678-4.562 2.7178 1.0677 5.0473 0.29119 6.6003-1.456 7.3768-4.9502 4.4649-3.6884 0.67944-2.7178 2.7178-2.8148-1.456-4.659 0.29119-2.9119 4.8532-2.1354-0.38826 5.1444h2.9119l-3.2031 2.7178 12.909-6.7944 2.1354-0.0971 1.3589-6.212h0.38826l1.4559-3.5913 0.67944-11.065 0.87357-4.4649-2.5236-7.9592-3.106-5.4355-0.0971-2.6207-3.2031-4.4649-1.9413-18.733-0.0971-2.3295-0.19413-2.4266-0.58238-8.5416-5.8238 0.19413-1.456-1.553-0.29119-0.0971h-0.0971l-3.7855-0.67944-4.3678-2.8148-4.8532-2.0383-9.1239 2.6207-2.4266-0.58238-3.009 1.1648-3.6884 3.009-9.9004-4.659-3.106 4.2708-4.562-1.6501-4.8532-3.106-2.6207 2.2324-2.5236 0.0971v-1.8442l-6.7944-3.2031-2.7178 1.2618-1.3589-1.553-7.4739-0.7765-5.7267-5.2414-0.87356 1.7471-4.1737-0.19413-3.8825-3.6884-1.7471-5.8238-0.29119-33.196-24.848-0.29119-23.489-0.58238h-0.58238z" data-id="TX" data-name="Texas"/>
</g>
</svg>
You need to find the center of a path in pixels in a resizable svg element. For this you need:
to find the center of a path in svg units
convert the svg units in pixels
repeat on resize
Please read the comments on my code.
In my code the div #label is just a point. If you need to add text to the div you'll need to take in account the width and the height of the div.
// the values of the svg viewBox
svgVB = { x: 0, y: 0, w: 271.87, h: 232.08 };
//the bounding box for the path id="NM"
let BB = NM.getBBox();
//the center of the path in svg units
let center = {};
center.x = BB.x + BB.width / 2;
center.y = BB.y + BB.height / 2;
//the center of the path in html units
let htmlCenter = {};
// a function to get the position of the div
function positionDiv() {
//first get the size and the position of the svg element
let SVGClientRect = svg.getBoundingClientRect();
//calculate the htmlCenter x
htmlCenter.x = map(
center.x,
svgVB.x,
svgVB.w,
SVGClientRect.x,
SVGClientRect.x + SVGClientRect.width
);
//calculate the htmlCenter y
htmlCenter.y = map(
center.y,
svgVB.y,
svgVB.h,
SVGClientRect.y,
SVGClientRect.y + SVGClientRect.height
);
// set the styles for the label
label.style.left = htmlCenter.x + "px";
label.style.top = htmlCenter.y + "px";
}
//call the positionDiv function
positionDiv();
//call the positionDiv function on resize
window.setTimeout(function() {
positionDiv();
window.addEventListener("resize", positionDiv, false);
}, 15);
function map(n, a, b, _a, _b) {
let d = b - a;
let _d = _b - _a;
let u = _d / d;
return _a + n * u;
}
svg {
border: 1px solid;
}
#label {
width: 5px;
height: 5px;
border-radius: 50%;
background: red;
position: absolute;
}
<svg id="svg" width="50%" height="50%" fill="none" stroke="#000000" stroke-linejoin="round" enable_background="new 0 0 1000 589" pretty_print="False" version="1.1" viewBox="0 0 271.87 232.08" xmlns="http://www.w3.org/2000/svg">
<g fill="#f9f9f9" fill-rule="evenodd" stroke-width=".97063">
<path d="m109.29 15.045 0.2913-7.5709-3.106-0.0971-21.451-0.97063-21.548-1.3589-48.92-4.2708-3.009-0.29119-0.38825 3.4943-7.2797 75.127-0.67944 7.0856-2.7178 28.634 0.38826 0.0971 13.395 1.2618 1.2618-6.7944 2.4266-1.9413 27.178 2.4266h0.19413l-2.4266-4.7561 12.327 0.87357 30.769 1.7471 19.218 0.87357 3.3002-91.045 0.67944 0.0971 0.0971-2.6207z" id="NM" data-name="New Mexico"/>
<path d="m246.35 13.201-0.19413-2.6207-0.0971-2.5236-0.19413-2.5236-3.6884 0.29119-37.563 1.7471-52.705 0.77651-22.519-0.29119-4.1737-0.0971h-1.553l-6.115-0.19413-1.9413-0.0971-4.0766-0.0971-1.9413-0.0971-0.2913 7.5709-0.0971 2.6207h0.58238l23.489 0.58238 24.848 0.29119 0.29119 33.196 1.7471 5.8238 3.8825 3.6884 4.1737 0.19413 0.87356-1.7471 5.7267 5.2414 7.4739 0.7765 1.3589 1.553 2.7178-1.2618 6.7944 3.2031v1.8442l2.5236-0.0971 2.6207-2.2324 4.8532 3.106 4.562 1.6501 3.106-4.2708 9.9004 4.659 3.6884-3.009 3.009-1.1648 2.4266 0.58238 9.1239-2.6207 4.8532 2.0383 4.3678 2.8148 3.7855 0.67944h0.0971l-0.0971-4.3678-1.0677-26.401-0.0971-4.3678-3.7855-19.607-0.58238-2.7178-0.0971-2.5236z" id="OK" data-name="Oklahoma"/>
<path d="m210.82 227.22-4.659-17.568v3.3002zm-1.0677-30.866-3.3002 6.212-0.38825 2.0383zm2.6207-4.562 3.106-4.0767-2.2324 1.3589zm10.968-9.9004-7.2797 3.7855 2.0383-0.38825zm0.97063-1.3589 2.0383-1.6501-0.7765 0.19413zm-115.12-162.87-0.67944-0.0971-3.3002 91.045-19.218-0.87357-30.769-1.7471-12.327-0.87357 2.4266 4.7561 10.58 10.58 6.0179 7.0856 7.9592 5.9208 5.6297 10.289 2.1354 10.774 4.562 3.009 3.5913 3.9796 5.1443 1.8442 7.4739 4.7561 3.3972 1.2618 4.659-4.659 1.456-4.9502 2.4266-4.7561 7.5709-3.009 2.9119 1.4559 8.4445 0.67945 7.668 4.7561 5.2414 0.97063-1.456 2.7178 3.009 1.9413 2.8148 3.3972 0.58238 3.5913 1.8442 2.4266 4.2708 10.289 4.2708 3.5913 3.3002 5.4355 4.1737 4.2708 1.8442 0.58238 1.553 11.065 4.562 2.5236 0.19412 3.4943 1.1648-0.29119 7.9592 9.7063 3.9796 0.87357 5.0473 3.009h7.765l5.6297 3.106 6.6974-1.4559-3.009-2.8148-2.7178-8.1533-1.0677-7.0856-1.553-2.3295 0.67944-4.7561-2.0383-0.19413-2.7178-4.4649 3.106 3.3002 3.5913-1.2618 1.9413-5.1444-3.8825-5.2414 5.8238 0.67944 2.7178-4.1737-0.38825-1.456 2.4266-3.2031-0.58238 2.8148 2.7178-2.1354-1.0677-3.7855 3.4943 1.8442 4.4649-2.5236-4.3678-4.562 2.7178 1.0677 5.0473 0.29119 6.6003-1.456 7.3768-4.9502 4.4649-3.6884 0.67944-2.7178 2.7178-2.8148-1.456-4.659 0.29119-2.9119 4.8532-2.1354-0.38826 5.1444h2.9119l-3.2031 2.7178 12.909-6.7944 2.1354-0.0971 1.3589-6.212h0.38826l1.4559-3.5913 0.67944-11.065 0.87357-4.4649-2.5236-7.9592-3.106-5.4355-0.0971-2.6207-3.2031-4.4649-1.9413-18.733-0.0971-2.3295-0.19413-2.4266-0.58238-8.5416-5.8238 0.19413-1.456-1.553-0.29119-0.0971h-0.0971l-3.7855-0.67944-4.3678-2.8148-4.8532-2.0383-9.1239 2.6207-2.4266-0.58238-3.009 1.1648-3.6884 3.009-9.9004-4.659-3.106 4.2708-4.562-1.6501-4.8532-3.106-2.6207 2.2324-2.5236 0.0971v-1.8442l-6.7944-3.2031-2.7178 1.2618-1.3589-1.553-7.4739-0.7765-5.7267-5.2414-0.87356 1.7471-4.1737-0.19413-3.8825-3.6884-1.7471-5.8238-0.29119-33.196-24.848-0.29119-23.489-0.58238h-0.58238z" id="TX" data-name="Texas"/>
</g>
</svg>
<div id="label"></div>
You need to add an id to your path
<path id="my-text" .......... />
aftet that, inside your svg tags put:
<text>
<textPath xlink:href="#text">text on a path</textPath>
</text>
you use the same id you used for that path in the href=""
Hope this helps!
this article also may help you out! https://vanseodesign.com/web-design/svg-text-on-a-path-part-1/
for putting elements in your svg:
The only way i found was using <foreignObject>
example:
<svg>
....
....
<foreignObject>
<div> your content</div>
</foreignObject>
</svg>
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject this article can you more about that. There are ways yo position with x and y attributes.
My animation class is not triggering in this codepen. What am I missing? I get to the controller methods fine. I never make it inside the animation class, either addClass or removeClass?
codepen angularjs animation link, same code as here
This is my base animation that I am trying to incorporate into the animation class above.
codepen base animation link, works fine, not the issue
The way this is setup, by clicking on each circle, you make it active. It initializes the active circle at the first one. This timeline will go to the empty circle with stroke when a banner slide is "active" and when not active, the timeline will go back to the solid fill with no stroke.
angular.module("appBanner", [])
.controller('bannerCtrl', function($scope) {
$scope.slides = ["zero", "one", "two"];
$scope.currentIndex = 0;
$scope.currentSlideIndex = "zero";
$scope.setCurrentSlideIndex = function(index) {
$scope.currentIndex = index;
$scope.currentSlideIndex = $scope.slides[$scope.currentIndex];
}
$scope.isCurrentSlideIndex = function(slideIndex) {
return $scope.currentSlideIndex === slideIndex;
}
})
.animation('.navCircleTransition', function($window) {
return {
addClass: function(element, className, done) {
if (className === 'active') {
var svgEl = element.find("svg");
navCircleAnimate(svgEl, "reverse");
} else {
done();
}
},
removeClass: function(element, className, done) {
var scope = element.scope();
if (className === 'active') {
var svgEl = element.find("svg");
navCircleAnimate(svgEl, "reverse");
} else {
done();
}
}
}
});
function navCircleAnimate(el, direction) {
var tlNavCircle = new TimelineMax({
paused: true
});
tlNavCircle.set($(el), {
drawSVG: "0% 100%",
ease: Linear.easeInOut
});
tlNavCircle.to($(el), 1, {
drawSVG: "0% 0%",
fill: "none",
ease: Linear.easeInOut
});
if (direction === "play") tlNavCircle.play();
else tlNavCircle.reverse();
}
.navCircleContainer {
position: absolute;
display: flex;
justify-content: space-between;
padding: 5px;
bottom: 2.5px;
left: 12.5%;
width: 75%;
}
body {
background: #333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.3/angular.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/DrawSVGPlugin.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.18.0/TweenMax.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
<div ng-app="appBanner" ng-controller="bannerCtrl" class="navCircleContainer">
<div id="autoNavCircle" class="navCircleTransition" ng-class="{active: isCurrentSlideIndex('auto')}" ng-click="setCurrentSlideIndex(0)">
<svg id="circle" height="100" width="100">
<circle cx="50" cy="50" r="45"/>
</svg>
</div>
<div id="autoNavCircle" class="navCircleTransition" ng-class="{active: isCurrentSlideIndex('boatowners')}" ng-click="setCurrentSlideIndex(1)">
<svg id="circle" height="100" width="100">
<circle cx="50" cy="50" r="45"/>
</svg>
</div>
<div id="autoNavCircle" class="navCircleTransition" ng-class="{active: isCurrentSlideIndex('commercial')}" ng-click="setCurrentSlideIndex(2)">
<svg id="circle" height="100" width="100">
<circle cx="50" cy="50" r="45"/>
</svg>
</div>
</div>
Forgot to include ngAnimate in my module. grrr....
HTML:
<div>
<svg class="velveti-grid-point" width="100" height="100" style="height: 120px; width: 625px;">
<circle class="myPoint" cx="500" cy="105" r="5" fill="#80E1EE" />
</svg>
<div class="theContainer">bg-color</div>
</div>
CSS:
.myPoint:hover + .theContainer {
background-color: black;
}
Problem: When i am hovering on the blue svg circle the background-color should be displayed on the text, but with svg it doesn't work. What is the problem? what do i need to do?
The demo: http://jsfiddle.net/wy6y66ox/
This has nothing to do with SVG per se.
+ is referred to as an adjacent selector. It will select only the element that is immediately preceded by the former element.
Because .myPoint is not a sibling of .theContainer your selector will not work.
You would need javascript in this instance.
Paulie_D is right.You have to use Javascript.
HTML
<div>
<svg class="velveti-grid-point" width="100" height="100" style="height: 120px; width: 625px;">
<circle id="svgid" class="myPoint" cx="500" cy="105" r="5" fill="#80E1EE" />
</svg>
<div id="divcolor" class="theContainer">bg-color</div>
</div>
JS
var svg = document.getElementById( 'svgid' );
var div = document.getElementById( 'divcolor' );
svg.onmouseover = function() {
div.style.backgroundColor = 'blue';
};
svg.onmouseout = function() {
div.style.backgroundColor = 'transparent';
};
Demo Here
I can get this working successfully within the html body, example...
<div id="myContainer" style="float: left; background-color: Blue; height: 100px;
width: 100px;">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%">
<defs>
<lineargradient id="myLinearGradient" x1="0%" x2="0%" y1="0%" y2="100%">
<stop id="start" offset="50%" style="stop-color: White; stop-opacity: 1" />
<stop id="stop" offset="60%" style="stop-color: #99cd9f; stop-opacity: 1" />
</lineargradient>
</defs>
<circle cx="50px" cy="50px" r="50px" fill="url(#myLinearGradient)" />
</svg>
</div>
However, I need to create this dynamically using javascript. Creating just the circle works fine, it's when I point the circle's Fill to the lineargradient it fails - I just get a black circle.
I think I'm not setting the stop 'style' attribute correctly. I have tried an alternative way to no avail, see below...
I'm using Chrome, and thanks in advance!
Within the body tages:
<body>
<div style="float: left; background-color: Blue; height: 100px;
width: 100px;">
<svg id="Svg1" xmlns="http://www.w3.org/2000/svg">
<defs id="mydefs">
</defs>
</svg>
</div>
</body>
My script:
<script>
// lineargradient
var myLinearGradient = document.createElementNS("http://www.w3.org/2000/svg", "lineargradient");
myLinearGradient.setAttribute("id", "myLGID");
myLinearGradient.setAttribute("x1", "0%");
myLinearGradient.setAttribute("x2", "0%");
myLinearGradient.setAttribute("y1", "0%");
myLinearGradient.setAttribute("y2", "100%");
document.getElementById("mydefs").appendChild(myLinearGradient);
//stops
var stop1 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
stop1.setAttribute("id", "myStop1");
stop1.setAttribute("offset", "70%");
//stop1.setAttribute("style", "stop-color: White; stop-opacity: 1");
stop1.setAttribute("stop-color", "White");
document.getElementById("mydefs").appendChild(stop1);
var stop2 = document.createElementNS("http://www.w3.org/2000/svg", "stop");
stop2.setAttribute("id", "myStop2");
stop2.setAttribute("offset", "80%");
//stop2.setAttribute("style", "stop-color: #99cd9f; stop-opacity: 1");
stop2.setAttribute("stop-color", "#99cd9f");
document.getElementById("mydefs").appendChild(stop2);
// Circle
var myCircle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
myCircle.setAttribute("id", "idCircle");
myCircle.setAttribute("cx", "50px");
myCircle.setAttribute("cy", "50px");
myCircle.setAttribute("r", "50px");
myCircle.setAttribute("fill", "url(#myLGID)");
document.getElementById("Svg1").appendChild(myCircle);
</script>
Two things:
The element name for linear gradients is linearGradient, not lineargradient.
You have to append the stops to the linearGradient element, not the defs element.
See this codepen for an MIT-licensed example:
// Store the SVG namespace for easy reuse.
var svgns = 'http://www.w3.org/2000/svg';
// Create <svg>, <defs>, <linearGradient> and <rect> elements using createElementNS to apply the SVG namespace.
// (https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS)
var svg = document.createElementNS(svgns, 'svg');
var defs = document.createElementNS(svgns, 'defs');
var gradient = document.createElementNS(svgns, 'linearGradient');
var rect = document.createElementNS(svgns, 'rect');
// Store an array of stop information for the <linearGradient>
var stops = [
{
"color": "#2121E5",
"offset": "0%"
},{
"color": "#206DFF",
"offset": "100%"
}
];
// Parses an array of stop information and appends <stop> elements to the <linearGradient>
for (var i = 0, length = stops.length; i < length; i++) {
// Create a <stop> element and set its offset based on the position of the for loop.
var stop = document.createElementNS(svgns, 'stop');
stop.setAttribute('offset', stops[i].offset);
stop.setAttribute('stop-color', stops[i].color);
// Add the stop to the <lineargradient> element.
gradient.appendChild(stop);
}
// Apply the <lineargradient> to <defs>
gradient.id = 'Gradient';
gradient.setAttribute('x1', '0');
gradient.setAttribute('x2', '0');
gradient.setAttribute('y1', '0');
gradient.setAttribute('y2', '1');
defs.appendChild(gradient);
// Setup the <rect> element.
rect.setAttribute('fill', 'url(#Gradient)');
rect.setAttribute('width', '100%');
rect.setAttribute('height', '100%');
// Assign an id, classname, width and height
svg.setAttribute('width', '100%');
svg.setAttribute('height', '100%')
svg.setAttribute('version', '1.1');
svg.setAttribute('xmlns', svgns);
// Add the <defs> and <rect> elements to <svg>
svg.appendChild(defs);
svg.appendChild(rect);
// Add the <svg> element to <body>
document.body.appendChild(svg);