Works in codepen but not in Wordpress - javascript

I'm trying to get this animated svg tree to work in Wordpress. It works fine in codepen, but not at all in a Wordpress page on my localhost.
Can anyone see what is missing/wrong? In the page source code the javascript files are loading.
svg tree
var svg = $("#svg-container");
svg.children().find("path:not(.except)").click(function(e) {
$("#Layer_1 path").removeAttr("style");
$this = $(this);
var bbox = this.getBBox();
var centreX = bbox.x + bbox.width / 2;
var centreY = bbox.y + bbox.height / 2;
$this.css("transform-origin", centreX + 'px ' + centreY + 'px');
$this.css("transform", "scale(4)");
$this.css("stroke", "");
$this.css("fill", "");
this.parentElement.appendChild(this);
})
#svg-container {
width: 500px;
height: 500px;
}
#svg-container svg {
width: 100%;
height: 100%;
}
#font-face {
font-family: "Amaranth";
src: url('https://fonts.googleapis.com/css?family=Amaranth');
}
<div id="svg-container">
<!--?xml version="1.0" encoding="utf-8"?-->
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<script type="text/javascript">
< ![CDATA[
]] >
</script>
<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="1247.24px" height="1360.63px" viewBox="0 0 1800 1400" enable-background="new 0 0 1247.24 1360.63" xml:space="preserve">
<g>
<font>
<font-face font-family="Amaranth">
<font-face-src>
<font-face-uri xlink:href="https://fonts.googleapis.com/css?family=Amaranth" />
</font-face-src>
</font-face>
</font>
<text x="10" y="10" font-weight="bold" font-size="75" fill="#3ABDF2" font-family="Amaranth">The tree</text>
<path class="except" fill="#3E6325" d="m1175 917.29c-11.44-1.847-21.576 0.042-32.652 2.825-3.182 0.8-6.644 1.598-10.131 1.985 48.901-29.163 .....continued"
fill="#639357"
id="path5022" /><path
d="m604.1 171.56s-18.18-9.487-18.989-9.087c-0.812 0.401-2.108 1.365-0.619 2.624 1.491 1.259 18.873 8.725 20.208 8.689 1.331-0.037 1.5-1.57-0.6-2.226z"
fill="#3E6325"
stroke="#A64F2C"
stroke-miterlimit="10"
id="path5024" />
</g>
</svg>
</div>
https://codepen.io/paulfadams/pen/PRzMNE?editors=1111

I had this same issue once.
WordPress ships with its own version of the jQuery library.
Try using "jQuery" instead of just "$" sign.
For example:
var svg = $("#svg-container"); should be replaced with var svg = jQuery("#svg-container");

Use jQuery instead of the "$" sign. ex: jQuery("#svg-container");

Related

How to compute getBoundingClientRect() in a scaled svg?

I have a usecase where designers supply us with a SVG, and we use certain elements in that SVG to position our dynamically created elements.
In the snippet below I try to overlap the rect#overlayTarget with the div#overlay using getBoundingClientRect: it doesn't take the scaling of the parent element into account, and the elements don't overlap.
The answers from this question is not applicable here as it uses element.offsetLeft and element.offsetTop, which aren't available for SVG: How to compute getBoundingClientRect() without considering transforms?
How do I make the #overlay and #overlayTarget overlap?
const target = document.querySelector("#overlayTarget");
const position = target.getBoundingClientRect();
const overlay = document.querySelector("#overlay");
overlay.style.top = `${position.y}px`;
overlay.style.left = `${position.x}px`;
overlay.style.width = `${position.width}px`;
overlay.style.height = `${position.height}px`;
#overlay {
position: absolute;
background: hotpink;
opacity: 0.3;
width: 100px;
height: 100px;
}
<div id="app" style="transform: scale(0.875);">
Test
<div id="overlay"></div>
<svg xmlns="http://www.w3.org/2000/svg" width="1809" height="826" viewBox="0 0 809 826">
<g
id="Main_overview"
data-name="Main overview"
transform="translate(-49.5 -155)"
>
<g
id="overlayTarget"
data-name="DC-DC converter"
transform="translate(400 512)"
>
<rect
id="Rectangle_29"
data-name="Rectangle 29"
width="74"
height="74"
fill="none"
stroke="#47516c"
stroke-width="2"
/>
</g>
</g>
</svg>
</div>
If you cannot set your overlay element outside of the transformed element, this answer will work, but only for some simple transformations:
translations and
scales with factors > 0
In these cases, the corners of the bounding box aren't moved out of their top/left and bottom/right orientation. Rotations or skews, and most of the 3D transforms won'T work out.
You can then compute the resulting box values for your overlay by transforming the corners of position with the inverse matrix to that set for the #app element. The DOMPoint and DOMMatrix interfaces help with that.
It is important to remember that transform sets an implicit position: relative, so the top and left values of the overlay are not in relation to the viewport.
const app = document.querySelector('#app');
const relative = app.getBoundingClientRect();
const target = document.querySelector("#overlayTarget");
const position = target.getBoundingClientRect();
const matrix = new DOMMatrix(app.style.transform).inverse();
const topleft = new DOMPoint(
position.x - relative.x,
position.y - relative.y
).matrixTransform(matrix);
const bottomright = new DOMPoint(
position.x - relative.x + position.width,
position.y - relative.y + position.height
).matrixTransform(matrix);
const overlay = document.querySelector("#overlay");
overlay.style.top = `${topleft.y}px`;
overlay.style.left = `${topleft.x}px`;
overlay.style.width = `${bottomright.x - topleft.x}px`;
overlay.style.height = `${bottomright.y - topleft.y}px`;
#overlay {
position: absolute;
background: hotpink;
opacity: 0.3;
width: 100px;
height: 100px;
}
<div id="app" style="transform: scale(0.875);">
Test
<div id="overlay"></div>
<svg xmlns="http://www.w3.org/2000/svg" width="1809" height="826" viewBox="0 0 809 826">
<g
id="Main_overview"
data-name="Main overview"
transform="translate(-49.5 -155)"
>
<g
id="overlayTarget"
data-name="DC-DC converter"
transform="translate(400 512)"
>
<rect
id="Rectangle_29"
data-name="Rectangle 29"
width="74"
height="74"
fill="none"
stroke="#47516c"
stroke-width="2"
/>
</g>
</g>
</svg>
</div>

matrixTransform on svg: unexpected behaviour

I have a div containing an SVG image of 300x300 px and a viewbox of 1000x1000.
The image describes a blue rectangle on top of a red one.
When I move the mouse a circle is following the mouse position inside the image:
Everything is perfect except that when I apply a transformation changing perspective and rotation, the mouse pointer and circle center are not anymore matching:
Code is here:
$(function() {
$('#image').mousemove(function(event) {
var svg = document.querySelector('svg');
var pt = svg.createSVGPoint();
pt.x = event.clientX;
pt.y = event.clientY;
pt = pt.matrixTransform(svg.getScreenCTM().inverse());
overlay = document.getElementById('overlay');
$('#overlay').html(
"<circle cx='" + pt.x + "' cy='" + pt.y + "' r='50' stroke='#8f00ff' fill='transparent' stroke-width='10' /></svg>"
);
refresh = $("#overlay").html();
$("#overlay").html( refresh )
});
});
function Transform() {
$('#image').css({
transformOrigin: '500px 500px',
transform: 'perspective(100px) rotateX(5deg)'
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='image' tabindex='0' >
<svg id='svgmap' width='300' height='300' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1000 1000'>
<rect x='0' y='0' width='1000' height='1000' fill='red' />
<rect x='250' y='250' width='500' height='500' stroke='yellow' fill='blue' stroke-width='10' />
<g id='overlay'></g>
</svg>
</div>
<button onclick='Transform()'>Transform</button>
My goal is to preserver matching between the purple circle center and the mouse pointer, even when a transformation is applied to the object.
Is there a way to do it?
In your code #image is a div. In order to make it work you need to apply the transformation to the svg element (#svgmap) and the transformation must be an svg transformation.
$(function() {
$('#svgmap').mousemove(function(event) {
var svg = document.querySelector('svg');
var pt = svg.createSVGPoint();
pt.x = event.clientX;
pt.y = event.clientY;
pt = pt.matrixTransform(svg.getScreenCTM().inverse());
overlay = document.getElementById('overlay');
$('#overlay').html(
"<circle cx='" + pt.x + "' cy='" + pt.y + "' r='50' stroke='#8f00ff' fill='transparent' stroke-width='10' /></svg>"
);
refresh = $("#layer_wafer").html();
$("#layer_wafer").html( refresh )
});
});
function Transform() {
svgmap.setAttributeNS(null,"transform", "skewX(-20) translate(100)");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='image' tabindex='0' >
<svg id='svgmap' width='300' height='300' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1000 1000' transform="">
<rect x='0' y='0' width='1000' height='1000' fill='red' />
<rect x='250' y='250' width='500' height='500' stroke='yellow' fill='blue' stroke-width='10' />
<g id='overlay'></g>
</svg>
</div>
<button onclick='Transform()'>Transform</button>
I understand that you are needing a 3D css transformation but this (at least for now) doesn't work.
This is an article where you can read more about 3d transforms in svg: https://oreillymedia.github.io/Using_SVG/extras/ch11-3d.html In the article you can read: All the 3D transformation functions described in this section should be considered “future”
I've solved the issue in the ugliest possible way. Simply hiding the mouse cursor over the div.
Ugly. But effective.
$(function() {
$('#image').mousemove(function(event) {
var svg = document.querySelector('svg');
var pt = svg.createSVGPoint();
pt.x = event.clientX;
pt.y = event.clientY;
pt = pt.matrixTransform(svg.getScreenCTM().inverse());
overlay = document.getElementById('overlay');
$('#overlay').html(
"<circle cx='" + pt.x + "' cy='" + pt.y + "' r='50' stroke='#8f00ff' fill='transparent' stroke-width='10' /></svg>"
);
refresh = $("#overlay").html();
$("#overlay").html( refresh )
});
});
function Transform() {
$('#image').css({
transformOrigin: '500px 500px',
transform: 'perspective(100px) rotateX(5deg)'
});
}
div#image {
cursor: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='image' tabindex='0' >
<svg id='svgmap' width='300' height='300' xmlns='http://www.w3.org/2000/svg' version='1.1' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 1000 1000'>
<rect x='0' y='0' width='1000' height='1000' fill='red' />
<rect x='250' y='250' width='500' height='500' stroke='yellow' fill='blue' stroke-width='10' />
<g id='overlay'></g>
</svg>
</div>
<button onclick='Transform()'>Transform</button>
There's a little bit of optimization that I have to do to reduce the mouse cursor position gap between the DIV over and any other page element, but it's acceptable to me.

Path Of SVG Image Uploaded By user in WebSite

I build this pen , and it is work on my path image .
//Circle
$(document).on('click','#Change_Green_Circle',function(e){
e.preventDefault();
var img = document.getElementById('imgCircle');
img.style.fill = 'Green';
});
$(document).on('click','#Change_Yellow_Circle',function(e){
e.preventDefault();
var img = document.getElementById('imgCircle');
img.style.fill = 'Yellow';
});
// Wiki
$(document).on('click','#Change_Green_wiki',function(e){
e.preventDefault();
var img = document.getElementById('imgWiki');
img.style.fill = 'Green';
});
$(document).on('click','#Change_Yellow_wiki',function(e){
e.preventDefault();
var img = document.getElementById('imgWiki');
img.style.fill = 'Yellow';
});
//Rest
$(document).on('click','#Rest',function(e){
e.preventDefault();
var circle = document.getElementById('imgCircle');
var wiki = document.getElementById('imgWiki');
imgWiki.style.fill = 'Red';
imgCircle.style.fill = 'Black';
});
#import "compass/css3";
.logo {
width: 200px;
height: 164px;
}
body {
padding: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg id="imgCircle" 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="502.174px" viewBox="0 65.326 612 502.174" enable-background="new 0 65.326 612 502.174"
xml:space="preserve" class="logo">
<ellipse class="ground" cx="283.5" cy="487.5" rx="259" ry="80"/>
<path id="imgWiki" style="fill: red" d="M210.333,65.331C104.367,66.105-12.349,150.637,1.056,276.449c4.303,40.393,18.533,63.704,52.171,79.03
c36.307,16.544,57.022,54.556,50.406,112.954c-9.935,4.88-17.405,11.031-19.132,20.015c7.531-0.17,14.943-0.312,22.59,4.341
c20.333,12.375,31.296,27.363,42.979,51.72c1.714,3.572,8.192,2.849,8.312-3.078c0.17-8.467-1.856-17.454-5.226-26.933
c-2.955-8.313,3.059-7.985,6.917-6.106c6.399,3.115,16.334,9.43,30.39,13.098c5.392,1.407,5.995-3.877,5.224-6.991
c-1.864-7.522-11.009-10.862-24.519-19.229c-4.82-2.984-0.927-9.736,5.168-8.351l20.234,2.415c3.359,0.763,4.555-6.114,0.882-7.875
c-14.198-6.804-28.897-10.098-53.864-7.799c-11.617-29.265-29.811-61.617-15.674-81.681c12.639-17.938,31.216-20.74,39.147,43.489
c-5.002,3.107-11.215,5.031-11.332,13.024c7.201-2.845,11.207-1.399,14.791,0c17.912,6.998,35.462,21.826,52.982,37.309
c3.739,3.303,8.413-1.718,6.991-6.034c-2.138-6.494-8.053-10.659-14.791-20.016c-3.239-4.495,5.03-7.045,10.886-6.876
c13.849,0.396,22.886,8.268,35.177,11.218c4.483,1.076,9.741-1.964,6.917-6.917c-3.472-6.085-13.015-9.124-19.18-13.413
c-4.357-3.029-3.025-7.132,2.697-6.602c3.905,0.361,8.478,2.271,13.908,1.767c9.946-0.925,7.717-7.169-0.883-9.566
c-19.036-5.304-39.891-6.311-61.665-5.225c-43.837-8.358-31.554-84.887,0-90.363c29.571-5.132,62.966-13.339,99.928-32.156
c32.668-5.429,64.835-12.446,92.939-33.85c48.106-14.469,111.903,16.113,204.241,149.695c3.926,5.681,15.819,9.94,9.524-6.351
c-15.893-41.125-68.176-93.328-92.13-132.085c-24.581-39.774-14.34-61.243-39.957-91.247
c-21.326-24.978-47.502-25.803-77.339-17.365c-23.461,6.634-39.234-7.117-52.98-31.273C318.42,87.525,265.838,64.927,210.333,65.331
z M445.731,203.01c6.12,0,11.112,4.919,11.112,11.038c0,6.119-4.994,11.111-11.112,11.111s-11.038-4.994-11.038-11.111
C434.693,207.929,439.613,203.01,445.731,203.01z"/>
<filter id="pictureFilter" >
<feGaussianBlur stdDeviation="15" />
</filter>
</svg>
<button type="button" id="Change_Green_Circle">Change Circle to Green</text>
<button type="button" id="Change_Yellow_Circle">Change Circle to Yellow</text>
<button type="button" id="Change_Green_wiki">Change wiki to Green</text>
<button type="button" id="Change_Yellow_wiki">Change Wiki to Yellow</text>
<button type="button" id="Rest">Rest </text>
BUT
I want to allow the user to upload SVG in my site, and to do the same function i did in my pen above, so I need to take the path of image uploaded by the user , HOW ?
1- which programming language i need to use ?
2- how to take the path
of the uploaded SVg image by user
check out this fiddle: http://jsfiddle.net/recouwnh/19/
What does fiddle do:
01) Retrieve details of dragged SVG image by user.
02) Then convert that image data into SVG tags, with appropriate tags like circle, path etc.
03) On click of "Change Color" button, script finds all path elements from viewing SVG and give them random colors.
HTML Code:
<div class="viewer">
<label class="viewer-switch"> </label>
<div class="alert-error"></div>
<div class="introbox"></div>
<div class="viewer-wrap"></div>
<a style="display: none;"></a>
<p>Drop your content here</p>
</div>
<div>
<button type="button" name="btn_changecolor" id="btn_changecolor">Change Color</button>
</div>
JS Code:
var viewerCtrl = new ViewerController(document.querySelector('.viewer'));
// Cheap way to inform the user about errors.
var alertBoxTimeout, alertBox = document.querySelector('.alert-error');
window.onerror = function (msg) {
alertBox.textContent = msg;
alertBox.classList.add('show');
if (!alertBoxTimeout) {
setTimeout(function () {
alertBox.classList.remove('show');
}, 8000);
}
};
$('#btn_changecolor').on('click', function(){
var min=0, max=255, random1 = 0, random2 = 0, random3 = 0;
$('.viewer-wrap svg path').each(function(){
random1 = Math.random() * (+max - +min) + +min;
random2 = Math.random() * (+max - +min) + +min;
random3 = Math.random() * (+max - +min) + +min;
this.style.fill = 'rgb('+ random1 +', '+ random2 +', '+ random3 +')';
});
});
Taken reference from
01) https://maxwellito.github.io/vivus-instant/ (SVG Animation Playground)
02) Original github link which created above SVG animation:
https://github.com/maxwellito/vivus
03) https://maxwellito.github.io/vivus-instant/scripts/ViewerCtrl.js (Used to create draggable area & prepare SVG from the data which is getting read from user uploading image)
Note: Have checked working of this fiddle with SVG only. For changing the colors of specific path elements, you need to find out your own way.
Hope this will be useful too you.

Snap.SVG - Manipulate $(this) element

I have a problem with Snap.SVG and animation of multiple SVG elements.
I want to change path on hover, but i have many same SVG in html.
HTML:
var svg = $('.svg-wave');
var s = Snap(svg);
var simpleCup = Snap.select('.svg-wave-normal');
var fancyCup = Snap.select('.svg-wave-hover');
var simpleCupPoints = simpleCup.node.getAttribute('d');
var fancyCupPoints = fancyCup.node.getAttribute('d');
svg.mouseenter(function() {
simpleCup.animate({
d: fancyCupPoints
}, 600);
}).mouseleave(function() {
simpleCup.animate({
d: simpleCupPoints
}, 600);
});
svg .svg-wave-hover {opacity: 0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
<div class="item">
<svg class="svg-wave" width="240" height="120" viewBox="0 0 240 120" xmlns="http://www.w3.org/2000/svg">
<path class="svg-wave-normal" d="M108.5,114.8C71.7,114.8,62.7,117,0,117h217C151,117,146.2,114.8,108.5,114.8" fill="#69c6d3"></path>
<path class="svg-wave-hover" d="M108.5,0C71.7,0,62.7,117,0,117h217C151,117,146.2,0,108.5,0" fill="#69c6d3"></path>
</svg>
</div>
<div class="item">
<svg class="svg-wave" width="240" height="120" viewBox="0 0 240 120" xmlns="http://www.w3.org/2000/svg">
<path class="svg-wave-normal" d="M108.5,114.8C71.7,114.8,62.7,117,0,117h217C151,117,146.2,114.8,108.5,114.8" fill="#69c6d3"></path>
<path class="svg-wave-hover" d="M108.5,0C71.7,0,62.7,117,0,117h217C151,117,146.2,0,108.5,0" fill="#69c6d3"></path>
</svg>
</div>
<div class="item">
<svg class="svg-wave" width="240" height="120" viewBox="0 0 240 120" xmlns="http://www.w3.org/2000/svg">
<path class="svg-wave-normal" d="M108.5,114.8C71.7,114.8,62.7,117,0,117h217C151,117,146.2,114.8,108.5,114.8" fill="#69c6d3"></path>
<path class="svg-wave-hover" d="M108.5,0C71.7,0,62.7,117,0,117h217C151,117,146.2,0,108.5,0" fill="#69c6d3"></path>
</svg>
</div>
The problem is that when i hover last SVG, it animate the first one.
Can someone help me to change mouseenter/leave to work from $(this) ?
I'm going to suggest a way without using JQuery firstly, as it's not really necessary.
I would change your css to make the hover path display: none, rather than opacity: 0, as display none means that events will pass through fine, whereas opacity will capture them. Or you could reorder the paths, so the hove paths come first.
var normalWaves = Snap.selectAll('.svg-wave-normal');
var normalPoints = Snap.select('.svg-wave-normal').attr('d');
var hoverPoints = Snap.select('.svg-wave-hover').attr('d');
normalWaves.forEach(function( wave ) {
wave.mouseover(function() {
this.animate({
d: hoverPoints
}, 600);
})
.mouseout(function() {
this.animate({
d: normalPoints
}, 600);
});
});
svg .svg-wave-hover { display: none; }
jsfiddle

Changing svg objects color?

HTML: svg object and script that should change color of the svg object but for some reason it doesnt?
<object id="object" type="image/svg+xml" data="play-pattern--light.svg"></object>
<script type="text/javascript">
window.onload=function () {
var a = document.getElementById("object");
var svgDoc = a.contentDocument;
var styleElement = svgDoc.createElementNS("http://www.w3.org/2000/svg", "style");
styleElement.textContent = ".st0 { fill: #000 }";
svgDoc.getElementById("object").appendChild(styleElement);
};
</script>
I think this is all you need to color an SVG object
<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="160px" height="160px" viewBox="0 0 160 160" style="enable-background:new 0 0 160 160;" xml:space="preserve">
<style type="text/css">
.st0{fill:#EDF5F5;}
</style>
Need some guidance why my code is not working, it also says an error "Uncaught TypeError: Cannot read property 'appendChild' of null"
Thanks
You should use:
svgDoc.documentElement.appendChild(styleElement);
instead of
svgDoc.getElementById("object").appendChild(styleElement);

Categories