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>
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>
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)