Javascript SVG curve change path attirbut C - javascript

Thank you in advance.
i try to move un SVG curve element in html using javascript.
I would like to change the path of my svg so that my blue curve transforms like the red curve but with the transition to see the displacement of the curve.
i understand how to get or create an element but i am not sure how to set the attribude 'd' like change every 'c' in path.
alert(document.getElementById('s3').getAttribute('d'));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<svg viewBox="0 0 990 180" height="200" width="1100" id="mySVG">
<g>
<path id="s2" d="M 241,128 C 272,113 293,152 369,125 C 434,80 471,72 580,114 "
fill="none" stroke="red" stroke-width="5px" />
<path id="s3" d="M 241,128 C266,131 298,100 369,125 C 441,150 482,151 580,114 "
fill="none" stroke="blue" stroke-width="5px" />
</g>
</svg>
<script src="app.js"></script>
</body>
</html>

I hope I understand your question: If you want to animate from one curve to the other you can use SMIL animations.
Since the paths in your code have the same number and the same type of commands you can use an <animate> element to animate the d attribute.
The values attribute is a list of values separated with semicolons (;) The first and the last value is the d attribute of the curve. The second value is the d attribute of the other one.
In my code the duration of the animation is 5 seconds: dur="5s
<svg viewBox="235 80 350 70" width="300" id="mySVG">
<g>
<path id="s2" d="M 241,128
C 272,113 293,152 369,125
C 434,80 471,72 580,114" fill="none" stroke="red" stroke-width="5px">
</path>
<path id="s3" d="M 241,128
C266,131 298,100 369,125
C 441,150 482,151 580,114" fill="none" stroke="blue" stroke-width="5px">
<animate attributeName="d" attributeType="XML" values="M 241,128
C266,131 298,100 369,125
C 441,150 482,151 580,114;
M 241,128
C 272,113 293,152 369,125
C 434,80 471,72 580,114;
M 241,128
C266,131 298,100 369,125
C 441,150 482,151 580,114; " dur="5s" repeatCount="indefinite" />
</path>
</g>
</svg>
UPDATE
The OP is commenting:
can i make it in javascript?
Making it in javascript is more complicated. You will need to set an array of values and an array of target values and recalculate each value of the curve with every frame of the animation. Next comes an example that is animating the blue curve on click:
Please read the comments in the code.
//I've hard coded the values and the target array
//you may want to do it dimamicaly from the d attribute
let vals = [
["M", 241, 128],
["C", 272, 113, 293, 152, 369, 125],
["C", 434, 80, 471, 72, 580, 114]
];
let target = [
["M", 241, 128],
["C", 266, 131, 298, 100, 369, 125],
["C", 441, 150, 482, 151, 580, 114]
];
//the request animation id
let rid = null;
//build the memory array used for the animation
let memory = [];
for (let i = 0; i < vals.length; i++) {
memory[i] = [];
memory[i][0] = target[i].slice();
memory[i][1] = vals[i].slice();
}
function Frame() {
rid = window.requestAnimationFrame(Frame);
updateValues();
updatePath();
}
window.addEventListener("load", updatePath, false);
// I'm animating the curve on click
svg.addEventListener(
"mousedown",
function () {
// if there is an animation running stop it before start another one
if (rid) {
window.cancelAnimationFrame(rid);
rid = null;
}
//reverse the animation
for (let i = 0; i < memory.length; i++) {
memory[i].reverse();
target[i] = memory[i][1].slice();
}
//call the Frame function
Frame();
},
false
);
function updateValues() {
//a function to update all the values of the curve except the move to part that is not changing anyway
for (let i = 1; i < vals.length; i++) {
for (let j = 1; j < vals[i].length; j++) {
let dist = target[i][j] - vals[i][j];
let vel = dist / 10;
vals[i][j] += vel;
}
}
}
//a function to reset the value of the d attribute
function updatePath() {
let d = `M${vals[0][1]},${vals[0][2]}`;
for (let i = 1; i < vals.length; i++) {
d += `C${vals[i][1]},${vals[i][2]},${vals[i][3]},${vals[i][4]},${vals[i][5]},${vals[i][6]}`;
}
s3.setAttributeNS(null, "d", d);
}
svg{border:1px solid}
<svg id="svg" viewBox="235 80 350 70" width="300" id="mySVG">
<g>
<path id="s2" d="M 241,128
C 272,113 293,152 369,125
C 434,80 471,72 580,114" fill="none" stroke="red" stroke-width="5px">
</path>
<path id="s3" d="M 241,128
C266,131 298,100 369,125
C 441,150 482,151 580,114" fill="none" stroke="blue" stroke-width="5px">
</path>
</g>
</svg>

Related

Draw SVG dashed line on scroll? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I want to have a svg dashed line drawn on scroll and got stuck on this for 4hrs.
If it's just a straight line, I can easily animate it by setting stroke-dasharray on css animation, but it doesn't work on a dashed line.
Since there's a background image on body, I cannot use a mask trick either.
I just want to have a simple 45 degree diagonal dashed line (about 100px) drawn on scroll.
Any advice?
In the next example I'm using the wheel event but you can use scroll instead. And I'm cheating. I'm drawing a dashed path over the path I want to animate. You'll see the animated path through the gaps. I hope it helps.
var svg = document.querySelector("svg");
var l = track.getTotalLength();
var dasharray = l;
var dashoffset = l;
theUse.style.strokeDasharray = dasharray;
theUse.style.strokeDashoffset = dashoffset;
document.addEventListener("wheel",
function(e) {
e.preventDefault();
if (dashoffset > 0 && e.deltaY > 0 ||
dashoffset < l && e.deltaY < 0) {
dashoffset -= e.deltaY;
}
if(dashoffset < 0)dashoffset = 0;
if(dashoffset > l)dashoffset = l;
theUse.style.strokeDashoffset = dashoffset;
}, false);
svg{border:1px solid}
<svg id="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 -23 238 120">
<defs>
<path id="track" fill="none" d="M18.265,6.037c0,0,22.354-2.458,32.585,2.709c13.401,6.768,22.928,25.006,33.864,30.677c10.935,5.67,11.901,9.014,21.216,8.608c10.013-0.435,11.08-5.485,14.862-5.485
c9.801,0,25.631,24.662,36.168,24.115c14.971-0.777,9.135-0.936,22.096-0.531c12.959,0.406,29.501,7.144,41.247,4.309"/>
</defs>
<use xlink:href="#track" id="theUse" stroke="black" />
<use xlink:href="#track" stroke-dasharray="10 10" stroke="white" stroke-width="2" />
UPDATE
Someone commented:
what we are supposed to see .. because I see nothing when running the snippet
When moving the wheel of your mouse you should see something like this:
UPDATE 2
I'm updating again as an answer to another comment:
ok I don't have a wheel, but why not considering the scroll as stated in the question
Next comes a demo where I'm using the scroll event:
var l = thePath.getTotalLength();
var dasharray = l;
track.style.strokeDasharray = dasharray;
var dashoffset = l;
track.style.strokeDashoffset = dashoffset;
wrap.addEventListener("scroll", function() {
// - 10 is because I want to offset slightly the dashoffse
dashoffset =
-10 + l - this.scrollTop * l / (this.scrollHeight - this.clientHeight);
track.style.strokeDashoffset = dashoffset;
});
#wrap,svg{border:1px solid}
#wrap{height:200px; overflow:scroll}
use{fill:none}
<div id="wrap">
<svg id="svg"
width="100" viewBox="0 0 78.571 753.021" >
<defs>
<path id="thePath" d="M46.249,7c0,0-37.5,0-37.5,32.812s20.312,56.25,37.5,75
s23.881,51.525,6.25,73.438c-31.43,39.062,21.875,43.882,18.75,70.378s-35.938,63.997-45.312,90.559s17.08,37.5,23.438,81.25
s-23.438,75-18.75,118.75s45.312,75,26.562,103.125s-51.812,83.438-50.125,100"/>
</defs>
<use xlink:href="#thePath" id="track" stroke="black" />
<use xlink:href="#thePath" stroke-dasharray="10 10" stroke="white" stroke-width="2" />
</svg>
</div>
UPDATE num 3
Got another comment:
You should use a mask instead of a white path for hiding the dashed path, so that everything but the dashes remains transparent. Like here: Animate dashed SVG line
Inspired by this answer Animate dashed SVG line I'm using a mask instead of a white path.
var l = thePath.getTotalLength();
var dasharray = l;
mask.style.strokeDasharray = dasharray;
var dashoffset = l;
mask.style.strokeDashoffset = dashoffset;
wrap.addEventListener("scroll", function() {
dashoffset =
l - this.scrollTop * l / (this.scrollHeight - this.clientHeight);
mask.style.strokeDashoffset = dashoffset;
});
#wrap,svg{border:1px solid}
#wrap{height:200px; overflow:scroll}
use{fill:none;}
path{stroke-width:3px;}
#mask{stroke:white}
<div id="wrap">
<svg id="svg"
width="100" viewBox="0 0 78.571 753.021" >
<defs>
<path id="thePath" d="M46.249,7c0,0-37.5,0-37.5,32.812s20.312,56.25,37.5,75
s23.881,51.525,6.25,73.438c-31.43,39.062,21.875,43.882,18.75,70.378s-35.938,63.997-45.312,90.559s17.08,37.5,23.438,81.25
s-23.438,75-18.75,118.75s45.312,75,26.562,103.125s-51.812,83.438-50.125,100"/>
<mask id="mask1">
<use id="mask" xlink:href="#thePath" />
</mask>
</defs>
<use xlink:href="#thePath" stroke-dasharray="10 10" stroke="black" mask="url(#mask1)" />
</svg>
</div>

Add a class to specific elements with pure Javascript

I am evaluating an Svg coloring image. A function evaluates the fill colors set by the user, against a correct answers list, by looping through them with querySelectorAll method and converted (to compare their values) to arrays. Only the paths with the class setColor can be colored.
Question: How can I add the class wrongColor ONLY to the path elements that have the wrong fill color?
<!--Hypothetical SVG that must be colored correctly.-->
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<path id="aSVG" class="setColor" d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="green" />
<path id="bSVG" class="setColor" d="M70 10 C 70 20, 120 20, 120 10" stroke="black" fill="red" />
<path d="M130 10 C 120 20, 180 20, 170 10" stroke="black" fill="white" />
<path id="cSVG" class="setColor" d="M10 60 C 20 80, 40 80, 50 60" stroke="black" fill="lightblue" />
<path id="dSVG" class="setColor" d="M70 60 C 70 80, 110 80, 110 60" stroke="black" fill="lightblue" />
<path d="M130 60 C 120 80, 180 80, 170 60" stroke="black" fill="white" />
<path id="eSVG" class="setColor" d="M10 110 C 20 140, 40 140, 50 110" stroke="black" fill="lightblue" />
<path id="fSVG" class="setColor" d="M70 110 C 70 140, 110 140, 110 110" stroke="black" fill="lightblue" />
<path d="M130 110 C 120 140, 180 140, 170 110" stroke="black" fill="white" />
</svg>
<!--Correct answers list. Not visible in user-->
<ol class="answersList">
<li class="t1">red</li>
<li class="t1">green</li>
<li class="t1">lightblue</li>
<li class="t1">lightblue</li>
<li class="t1">lightblue</li>
<li class="t1">lightblue</li>
</ol>
Below is a functional example in order to clarify the functionality of the game.
#Amethystx87 Your code adds class wrongColor to all the paths with the class setColor. You can see it below in the code Snippet. The map property will create error "document.querySelectorAll(...).map is not a function" because querySelectorAll returns a Node List (array like) so you have to convert the Node List to array and then array methods can be used.
I had the same problem too and solved it as in the JavaScript code below with the comments "check users answers","check correct answers list". In the comment "Amethystx87 solution" is the way I made your code to work but not completely there yet.
#DacreDenny I couldn't utilize your solution maybe my fault. I hope the code snippet below can give you a clear view of the problem. You will see in the snippet that the wrong answers (I made the mistake on purpose) are the first two (green,red) but the correct (red, green) are as appeared in the answer list.
/*~~~~~~~~check button~~~~~~~~~~~*/
document.querySelector(".check").addEventListener('click', checkSvgAnswers);
function checkSvgAnswers() {
/*~~~check users answers~~~*/
var selectedFillColor = document.querySelectorAll(".setColor");
var selectedFillColorArray = [];
for (var i = 0; i < selectedFillColor.length; i++) {
var selectedColors = selectedFillColor[i].getAttribute('fill').toUpperCase();
selectedFillColorArray.push(selectedColors);
}
console.log(selectedFillColorArray);
/*~~~check correct answers list~~~~~~~~~~~*/
var correctAnswers = document.querySelectorAll("li.t1");
var correctAnswersArray = [];
for (var i = 0; i < correctAnswers.length; i++) {
var answerList = correctAnswers[i].innerText.toUpperCase();
correctAnswersArray.push(answerList);
}
console.log(correctAnswersArray);
/*~~~~compare answers helper function~~~~~~~~~~*/
var isEqual = function(value, other) {
// Get the value type
var type = Object.prototype.toString.call(value);
// If the two objects are not the same type, return false
if (type !== Object.prototype.toString.call(other)) {
return false;
}
// If items are not an object or array, return false
if (['[object Array]', '[object Object]'].indexOf(type) < 0) {
return false;
}
// Compare the length of the length of the two items
var valueLen = type === '[object Array]' ? value.length : Object.keys(value).length;
var otherLen = type === '[object Array]' ? other.length : Object.keys(other).length;
if (valueLen !== otherLen) {
return false;
}
// Compare two items
var compare = function(item1, item2) {
// Get the object type
var itemType = Object.prototype.toString.call(item1);
// If an object or array, compare recursively
if (['[object Array]', '[object Object]'].indexOf(itemType) >= 0) {
if (!isEqual(item1, item2)) {
return false;
}
}
// Otherwise, do a simple comparison
else {
// If the two items are not the same type, return false
if (itemType !== Object.prototype.toString.call(item2)) {
return false;
}
// Else if it's a function, convert to a string and compare
// Otherwise, just compare
if (itemType === '[object Function]') {
if (item1.toString() !== item2.toString()) {
return false;
}
} else if (item1 !== item2) {
return false;
}
}
};
// Compare properties
if (type === '[object Array]') {
for (var i = 0; i < valueLen; i++) {
if (compare(value[i], other[i]) === false) {
return false;
}
}
} else {
for (var key in value) {
if (value.hasOwnProperty(key)) {
if (compare(value[key], other[key]) === false) {
return false;
}
}
}
}
// If nothing failed, return true
return true;
};
/*~~~~~~~~compare colors~~~~~~~~~~~*/
if (isEqual(selectedFillColorArray, correctAnswersArray)) {
document.querySelector(".coloringResult").innerHTML = "<span style='color:#00B119;'>✔</span>";
} else if (!isEqual(selectedFillColorArray, correctAnswersArray)) {
document.querySelector(".coloringResult").innerHTML = "<span style='color:#D40D0D;'>✗</span>";
}
console.log(isEqual(selectedFillColorArray, correctAnswersArray));
/*~~~~~~~~Amethystx87 solution*/
document.querySelectorAll('.setColor').forEach((element) => {
if (!correctAnswersArray.includes(element.fill)) {
element.classList.add('wrongColor');
}
});
};
<!--Hypothetical color palette. User can drag and drop colors ONLY to svg paths with the class="setColor" to change the default "fill" color values-->
<div class="colorPalette">
<p>green</p>
<p>red</p>
<p>lightblue</p>
</div>
<!--Hypothetical SVG that must be colored correctly.-->
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<path id="aSVG" class="setColor" d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="green" />
<path id="bSVG" class="setColor" d="M70 10 C 70 20, 120 20, 120 10" stroke="black" fill="red" />
<path d="M130 10 C 120 20, 180 20, 170 10" stroke="black" fill="white" />
<path id="cSVG" class="setColor" d="M10 60 C 20 80, 40 80, 50 60" stroke="black" fill="lightblue" />
<path id="dSVG" class="setColor" d="M70 60 C 70 80, 110 80, 110 60" stroke="black" fill="lightblue" />
<path d="M130 60 C 120 80, 180 80, 170 60" stroke="black" fill="white" />
<path id="eSVG" class="setColor" d="M10 110 C 20 140, 40 140, 50 110" stroke="black" fill="lightblue" />
<path id="fSVG" class="setColor" d="M70 110 C 70 140, 110 140, 110 110" stroke="black" fill="lightblue" />
<path d="M130 110 C 120 140, 180 140, 170 110" stroke="black" fill="white" />
</svg>
<!--Appears on check button click showing tick for correct, x for wrong.-->
<p class="coloringResult"> </p>
<!--control buttons-->
<!--Check button: compares the users colors placed on the svg, with the correct colors from the answers list. Score container appears and shows user score-->
<button class='check' type='button'>Check</button>
<!--Try again button: keep the correct answers, the wrong answers return to the original "fill" color and the score is changed keeping only the correct colors score-->
<button class='try-again' type='button'>Try again</button>
<!--Reset button: reset exersice to original state. All svg paths to default "fill" color. Score resets to 0 and disappears from screen -->
<button class='clear-answers' type='button'>Reset</button>
<!--Correct answers list. Not visible in user-->
<ol class="answersList">
<li class="t1">red</li>
<li class="t1">green</li>
<li class="t1">lightblue</li>
<li class="t1">lightblue</li>
<li class="t1">lightblue</li>
<li class="t1">lightblue</li>
</ol>
Something like this
// Get all the correct colors and map them to an array
const correctColors = document.querySelectorAll('.t1')
.map(element => return element.textContent);
// Loop through all with class setColor and add wrongColor to the element's classList
document.querySelectorAll('.setColor').forEach((element) => {
if (!correctColors.includes(element.fill)) {
element.classList.add('wrongColor');
}
});
You can query SVG elements, and update the classlist of SVG element in the same way that you would any other element in the DOM.
So for instance, you can query all SVG elements with a fill attribute value of a "wrong fill color" of white by doing this:
const wrongFillColor = "white";
document.querySelectorAll(`svg [fill="${wrongFillColor}"]`)
You can then iterate the resulting node set, and add classes to matching elements like so:
const wrongFillColor = "white";
document.querySelectorAll(`svg [fill="${wrongFillColor}"]`).forEach(function(element) {
element.classList.add("wrongColor")
})
.wrongColor {
fill: yellow;
}
<!--Hypothetical SVG that must be colored correctly.-->
<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
<path id="aSVG" class="setColor" d="M10 10 C 20 20, 40 20, 50 10" stroke="black" fill="green" />
<path id="bSVG" class="setColor" d="M70 10 C 70 20, 120 20, 120 10" stroke="black" fill="red" />
<path d="M130 10 C 120 20, 180 20, 170 10" stroke="black" fill="white" />
<path id="cSVG" class="setColor" d="M10 60 C 20 80, 40 80, 50 60" stroke="black" fill="lightblue" />
<path id="dSVG" class="setColor" d="M70 60 C 70 80, 110 80, 110 60" stroke="black" fill="lightblue" />
<path d="M130 60 C 120 80, 180 80, 170 60" stroke="black" fill="white" />
<path id="eSVG" class="setColor" d="M10 110 C 20 140, 40 140, 50 110" stroke="black" fill="lightblue" />
<path id="fSVG" class="setColor" d="M70 110 C 70 140, 110 140, 110 110" stroke="black" fill="lightblue" />
<path d="M130 110 C 120 140, 180 140, 170 110" stroke="black" fill="white" />
</svg>

How to find the midPoint of arc in SVG with javascript

I want to the mid point of arc in svg.. Can any one tell formula to find the midbpoint of arc.,
The answer to that question is not straightforward. That's because in SVG arcs can be an elliptical arc. For example, what would you say is the midpoint on the following arc?
<svg width="200" height="200" viewBox="0 0 100 100">
<path fill="none" stroke="black" stroke-width="2"
d="M 20,75 A 21,50, 45, 1 1, 60,75"/>
</svg>
Anyway, without getting into complicated formulae, the simplest method is probably to take advantage of SVG's pointAtLength() method.
var myarc = document.getElementById("myarc");
// Get the length of the path
var pathLen = myarc.getTotalLength();
// How far along the path to we want the position?
var pathDistance = pathLen * 0.5;
// Get the X,Y position
var midpoint = myarc.getPointAtLength(pathDistance)
// For fun, let's add a dot at that position to mark it.
var svg = myarc.ownerSVGElement;
var circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.setAttribute("cx", midpoint.x);
circle.setAttribute("cy", midpoint.y);
circle.setAttribute("r", "5");
circle.setAttribute("fill", "red");
svg.appendChild(circle);
<svg width="200" height="200" viewBox="0 0 100 100">
<path id="myarc" fill="none" stroke="black" stroke-width="2"
d="M 20,75 A 21,50, 45, 1 1, 60,75"/>
</svg>

Texture repeats and overlaps in three.js

I am creating a texture from svg files, mapping it on planes and returning the bitmap mesh to a callback. Problem is that first texture works fine but when I apply the second texture the plane has both first and second texture and this continues.
EDIT : What is really surprising is that console.log(mesh.material.map.image.src) is
showing the correct image for each icon(no overlap). Other than that each three.js group has just 2 children one for the overlay image and other for the blue background.
var scene = new THREE.Scene();
var cameraWidth = window.innerWidth;
var cameraHeight = window.innerHeight;
var camera = new THREE.OrthographicCamera(cameraWidth / -2, cameraWidth / 2, cameraHeight / 2, cameraHeight / -2, 0, 10000);
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x555555, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
camera.position.x = 0;
camera.position.y = 0;
camera.position.z = 100;
camera.lookAt(new THREE.Vector3(0, 0, 0));
var ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
var TURTLEPALETTEICON = '<svg xmlns="http://www.w3.org/2000/svg" width="55" height="55"> <path d="m 27.567493,45.252146 c -0.46948,0 -0.933016,-0.02903 -1.389761,-0.08296 l 1.178368,1.948634 1.161389,-1.918769 c -0.314968,0.02489 -0.629086,0.05309 -0.949996,0.05309 z" style="fill:none;stroke:#ffffff;stroke-width:1.20000005;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 38.317981,14.929279 c -1.837168,0 -3.360217,1.289964 -3.68707,2.992219 1.578232,1.115757 2.934884,2.584076 3.968928,4.320343 1.939893,-0.142684 3.475677,-1.709721 3.475677,-3.641764 0,-2.027442 -1.682656,-3.670798 -3.757535,-3.670798 z" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.29999995;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 38.787461,38.290488 c -1.039138,1.851575 -2.42805,3.426908 -4.072502,4.609029 0.442312,1.546298 1.878767,2.686942 3.603022,2.686942 2.07403,0 3.757535,-1.642527 3.757535,-3.669969 0,-1.870656 -1.437304,-3.397874 -3.288055,-3.626002 z" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.29999995;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 16.340734,38.277215 c -1.912727,0.170889 -3.41625,1.724653 -3.41625,3.639275 0,2.026612 1.680958,3.669969 3.755837,3.669969 1.752271,0 3.212497,-1.177974 3.626793,-2.764091 -1.598607,-1.174655 -2.950165,-2.728419 -3.96638,-4.545153 z" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.29999995;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 20.375881,18.007772 c -0.291196,-1.744563 -1.828678,-3.078493 -3.69556,-3.078493 -2.074879,0 -3.755837,1.643356 -3.755837,3.669968 0,1.97601 1.601155,3.575399 3.603872,3.655037 1.006876,-1.694789 2.319381,-3.139051 3.847525,-4.246512 z" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.29999995;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <path d="m 27.567493,15.62362 c 1.619832,0 3.164955,0.340948 4.599711,0.935742 0.629086,-0.892605 1.000085,-1.971862 1.000085,-3.138221 0,-3.058584 -2.537567,-5.5389654 -5.668563,-5.5389654 -3.130146,0 -5.667713,2.4803814 -5.667713,5.5389654 0,1.18461 0.383734,2.280457 1.032345,3.180529 1.463622,-0.62134 3.04525,-0.97805 4.704135,-0.97805 z" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:2.29999995;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> <g transform="matrix(0.8489685,0,0,0.82955893,4.2234061,5.2018707)" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.42992032;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"> <path d="m 43.102,30.421 c 0,4.7344 -1.6452,9.2798 -4.5706,12.6275 -2.9254,3.3478 -6.8973,5.2305 -11.0344,5.2305 -4.1371,0 -8.109,-1.8827 -11.0344,-5.2305 -2.9254,-3.3477 -4.5706,-7.8931 -4.5706,-12.6275 0,-9.7966 7.0444,-17.858 15.605,-17.858 8.5606,0 15.605,8.0614 15.605,17.858 z" style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.42992032;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /> </g> <g transform="matrix(0.8489685,0,0,0.82955893,4.2234061,5.2018707)" style="fill:#ffffff;fill-opacity:1;stroke:none"> <path d="m 25.875,33.75 -1.542,-4.625 3.164,-2.587 3.615,2.626 -1.487,4.669 z" style="fill:#ffffff;fill-opacity:1;stroke:none" /> <path d="m 27.501,41.551 c -3.968,-0.16 -5.543,-2.009 -5.543,-2.009 l 3.57,-4.163 4.465,0.168 3.132,4.12 c 0,0 -2.89,1.994 -5.624,1.884 z" style="fill:#ffffff;fill-opacity:1;stroke:none" /> <path d="m 18.453,33.843 c -0.849,-2.968 0.172,-6.884 0.172,-6.884 l 4,2.167 1.493,4.629 -3.582,4.233 c 0,-10e-4 -1.465,-1.99 -2.083,-4.145 z" style="fill:#ffffff;fill-opacity:1;stroke:none" /> <path d="m 19.458,25.125 c 0,0 0.5,-1.958 3.039,-3.822 2.237,-1.643 4.465,-1.72 4.465,-1.72 l -0.037,4.981 -3.521,2.75 -3.946,-2.189 z" style="fill:#ffffff;fill-opacity:1;stroke:none" /> <path d="M 32.084,27.834 28.625,24.959 29,19.75 c 0,0 1.834,-0.042 3.959,1.667 2.228,1.791 3.362,4.983 3.362,4.983 l -4.237,1.434 z" style="fill:#ffffff;fill-opacity:1;stroke:none" /> <path d="m 31.292,34.042 1.313,-4.464 4.187,-1.536 c 0,0 0.677,2.663 -0.042,5.667 -0.54,2.256 -2.084,4.361 -2.084,4.361 l -3.374,-4.028 z" style="fill:#ffffff;fill-opacity:1;stroke:none" /> </g> </svg>';
var PENPALETTEICON = '<svg xmlns="http://www.w3.org/2000/svg" width="55" height="55"> <path d="m 11.152285,41.709935 c 1.43401,0.788706 5.23977,1.402428 7.528553,1.290609 1.626167,-0.07945 3.914929,-0.479849 5.234137,-1.43401 2.238123,-1.618798 3.032695,-5.829627 5.090736,-7.671954 1.225701,-1.097229 3.231844,-2.444635 4.875634,-2.509518 2.003851,-0.07909 4.468168,1.514349 6.166244,2.581219 1.290216,0.810619 3.800127,3.369923 3.800127,3.369923" style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-miterlimit:4;stroke-opacity:1" /> <path d="m 35.566307,13.352385 2.437818,-2.366117 1.200984,0.84248 1.416085,1.200984 0.985882,1.272684 0.914181,1.487786 -2.366117,2.509519 -0.896257,-1.505711 -2.186866,-2.366117 -1.50571,-1.075508 z" style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-opacity:1" /> <path d="m 32.877538,16.112854 2.294417,-2.079315 1.200984,0.84248 1.416085,1.200984 0.985882,1.272684 0.914181,1.487786 -2.079315,1.864214 -0.967957,-1.147208 -2.330267,-2.222716 -1.43401,-1.218909 z" style="fill:none;stroke:#ffffff;stroke-width:1px;stroke-opacity:1" /> <path d="m 13.423248,38.807621 0.891754,-3.80169 18.820708,-18.21056 -0.469344,-0.680549 2.252852,-2.135517 5.115854,5.115853 -2.229385,2.135517 -0.774419,-0.539747 -19.05538,18.022823 -3.70782,0.657082 -0.84482,-0.563212 z" style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" /> <path d="m 33.482432,17.358584 3.660886,3.473148" style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" /> <path d="m 10.935723,41.905293 2.769132,-2.816066" style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" /> <path d="m 14.690478,35.287537 c 0,0 1.594197,0.393866 2.158983,0.93869 0.574138,0.553844 1.032558,2.158984 1.032558,2.158984" style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1" /> </svg>';
var NUMBERPALETTEICON = '<svg xmlns="http://www.w3.org/2000/svg" width="55" height="55"> <g transform="translate(6.1026134,-1.6740561)" style="fill:#ffffff;fill-opacity:1"> <text style="font-size:12px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"><tspan x="3.9423084" y="26.866751" id="tspan2386" style="font-size:18px;font-weight:normal;fill:#ffffff;fill-opacity:1;-inkscape-font-specification:AlArabiya">123</tspan></text> <text style="font-size:12px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"><tspan x="1.8153553" y="44.840736" style="font-size:18px;font-weight:normal;fill:#ffffff;fill-opacity:1;-inkscape-font-specification:AlArabiya">+–=</tspan></text> </g> </svg>';
var BOOLEANPALETTEICON = '<svg xmlns="http://www.w3.org/2000/svg" width="55" height="55" viewBox="0 0 55 55"><g style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:block"><path d="m 10,25 c 0,-6 6,-12 12,-12 6,0 12,6 12,12 0,6 -6,12 -12,12 -6,0 -12,-6 -12,-12 m 11,0 c 0,-6 6,-12 12,-12 6,0 12,6 12,12 0,6 -6,12 -12,12 -6,0 -12,-6 -12,-12" style="fill:none;stroke:#ffffff;stroke-width:2.5;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" /></g></svg>';
var PALETTEICONS = {
'turtle': TURTLEPALETTEICON,
'pen': PENPALETTEICON,
'number': NUMBERPALETTEICON,
'boolean': BOOLEANPALETTEICON
};
var output = document.getElementById('WebGL-output');
output.appendChild(webGLRenderer.domElement);
var x = 0;
var y = window.innerHeight / 2 - 27.5;
var buttons = {};
addIconOnScreen('pen');
addIconOnScreen('turtle');
addIconOnScreen('number');
addIconOnScreen('boolean');
function addIconOnScreen(name){
var img = new Image();
img.onload = function () {
var texture = new THREE.Texture(img);
texture.needsUpdate = true;
texture.minFilter = THREE.NearestFilter;
var material = new THREE.MeshBasicMaterial({
map: texture
});
material.transparent = true;
material.depthWrite = false;
var bitmap = new THREE.Mesh(new THREE.PlaneBufferGeometry(img.width, img.height), material);
bitmap.name = name;
bitmap.position.setX(0);
bitmap.position.setY(y);
scene.add(bitmap);
y-=55;
webGLRenderer.render(scene, camera);
};
img.src = 'data:image/svg+xml;base64,' + window.btoa(
unescape(encodeURIComponent(PALETTEICONS[name])));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r71/three.min.js"></script>
<div id="WebGL-output"></div>
I suspect that some kind of texture caching is taking place. When I load the new image I am overwriting the old texture cache. THREE.js is assuming that all the img I load are the same. Is there anyway to stop this texture cache?
EDIT : The other thing that I can think of is problem with closures. But I have gone through multiple times and it doesn't seem that way.
When image loaded, you need use canvas:
img.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
var texture = new THREE.Texture(canvas);
...
}
http://jsfiddle.net/wzy7m85y/
Seems to be a browser bug, see: https://code.google.com/p/chromium/issues/detail?id=553885
It's fixed in Chrome 48.0.2557.0 canary (64-bit)

IE 9 stops working when using getIntersectionList function

I have this SVG code:
<svg id="svgSurface" width="500" height="500">
<defs>
<marker id="Triangle" viewBox="0 0 20 20" refX="0" refY="0" markerUnits="strokeWidth" markerWidth="8" markerHeight="6" orient="auto">
<path d="M 0 0 L 20 10 L 0 20 z" fill="red" fill-opacity="1">
</path>
</marker>
</defs>
<line x1="10" y1="10" x2="100" y2="100" class="Line" marker-end="url(#Triangle)"></line>
</svg>
and some javascript code:
var svg = document.getElementById("svgSurface");
var svgRect = svg.createSVGRect();
svgRect.x = 0;
svgRect.y = 0;
svgRect.width = 50;
svgRect.height = 50;
var nodes = svg.getIntersectionList(svgRect, null);
alert(nodes.length);
Here is a working example in fiddle http://jsfiddle.net/gYaEX/1/
As you can see I try to get all nodes whose rendered content intersects the specified rectangle svgRect. In Chrome it works properly but in IE it always crashes and I don't understand why.
If it crashes that's a bug in IE which you should report to Microsoft, having said that you are using it incorrectly as you should be passing in an element and not null as the last argument. In your case you probably want this:
var nodes = svg.getIntersectionList(svgRect, svg);

Categories

Resources