Texture repeats and overlaps in three.js - javascript

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)

Related

Javascript SVG curve change path attirbut C

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>

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>

Filling in a Bezier Curve SVG

acknowledgement: reference
[SVG] How to close the path (between the 1st and the last point) and fill the area accordingly:
It's not a single path, so i can't close it with 'Z' at the end
It's not a single path, so I can't close it with 'Z' at the end
Join the paths first.
E.g. the sample from your link is originally
<path xmlns="http://www.w3.org/2000/svg" fill="none" stroke="blue" stroke-width="8" d="M 60 60 C 111.55555555555557 160 163.11111111111114 260 220 300"/>
<path xmlns="http://www.w3.org/2000/svg" fill="none" stroke="red" stroke-width="8" d="M 220 300 C 276.88888888888886 340 339.11111111111114 320 420 300"/>
But if you append the dstring of the second to the first and replace the second M (Move) with L (LineTo), you get this:
<path xmlns="http://www.w3.org/2000/svg" fill="cyan" stroke="red" stroke-width="8" d="M 60 60 C 111.55555555555557 160 163.11111111111114 260 220 300 L 220 300 C 276.88888888888886 340 339.11111111111114 320 420 300 Z"/>
I have also set fill=cyan.
Some of these drawn things are from the linked site and not in the code in my answer.

SVG - Animation Problems

I have some shapes which I rotate using two buttons, one for clockwise and the other for anti-clockwise direction:
var svgNS = "http://www.w3.org/2000/svg";
function cwAnim(evt) {
if (window.svgDocument == null)
svgDoc = evt.target.ownerDocument;
addRotateTransform('someShape', 1, -1, 180);
addRotateTransform('shape1', 1, 1, 360);
addRotateTransform('shape2', 1, 1, 360);
}
function acwAnim(evt) {
if (window.svgDocument == null)
svgDoc = evt.target.ownerDocument;
addRotateTransform('someShape', 1, 1, 180);
addRotateTransform('shape1', 1, -1, 360);
addRotateTransform('shape2', 1, -1, 360);
}
function addRotateTransform(target_id, dur, dir, angle) {
var my_element = svgDoc.getElementById(target_id);
var a = svgDoc.createElementNS(svgNS, "animateTransform");
var bb = my_element.getBBox();
var cx = bb.x + bb.width / 2;
var cy = bb.y + bb.height / 2;
a.setAttributeNS(null, "attributeName", "transform");
a.setAttributeNS(null, "attributeType", "XML");
a.setAttributeNS(null, "type", "rotate");
a.setAttributeNS(null, "dur", dur + "s");
a.setAttributeNS(null, "repeatCount", "1");
a.setAttributeNS(null, "fill", "freeze");
a.setAttributeNS(null, "additive", "sum");
a.setAttributeNS(null, "accumulate", "sum");
a.setAttributeNS(null, "from", "0 " + cx + " " + cy);
a.setAttributeNS(null, "to", angle * dir + " " + cx + " " + cy);
my_element.appendChild(a);
a.beginElement();
}
<svg width="600px" height="600px" viewBox="0 0 1000 1000">
<circle stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
<g id="someShape">
<circle fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
<path id="shape1" fill="#DC5A00" stroke="#000000" stroke-miterlimit="10" d="M692.373,317.798C692.373,418.425,606.244,500,500,500
c-106.245,0-192.374-81.575-192.374-182.202c0-100.629,86.128-182.204,192.374-182.204
C606.244,135.595,692.373,217.169,692.373,317.798z M553.391,220.34c-39.316,0-71.188,31.87-71.188,71.187
s31.871,71.187,71.188,71.187c39.314,0,71.186-31.87,71.186-71.187S592.705,220.34,553.391,220.34z" />
<path id="shape2" fill="#3DFF63" stroke="#000000" stroke-miterlimit="10" d="M577.368,647.034c0,69.738-56.913,126.271-127.119,126.271
c-70.206,0-127.119-56.533-127.119-126.271c0-69.737,56.913-126.271,127.119-126.271
C520.455,520.764,577.368,577.297,577.368,647.034z M466.352,617.373c-21.998,0-39.831,17.453-39.831,38.983
c0,21.529,17.833,38.982,39.831,38.982s39.831-17.453,39.831-38.982C506.182,634.826,488.349,617.373,466.352,617.373z" />
</g>
<g onclick="cwAnim(evt)">
<rect x="89.762" y="815.369" stroke="#000000" stroke-miterlimit="10" width="217.865" height="134.426" />
<text transform="matrix(1 0 0 1 127.4673 864.5491)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">AntiClockwise</text>
</g>
<g onclick="acwAnim(evt)">
<rect x="692.373" y="815.369" stroke="#000000" stroke-miterlimit="10" width="194.11" height="134.426" />
<text transform="matrix(1 0 0 1 752.0576 869.467)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">Clockwise</text>
</g>
</svg>
You can also see it on this CodePen: http://codepen.io/Daolagajao/pen/qdyBLo
When I click once, the shape animates fine. The problem arises when I click on the buttons in quick successions (double click, triple click, etc). The axis of rotation shifts and that is certainly not desirable.
Is there a way around this problem? Something like when i click on the next button, the previous animation in progress stops retaining the position and the new animation takes place.
By adding a busy variable you can indicate that you are currently animating and you shouldn't do any animations. You can do more with this, but it fixes the basic issue.
var svgNS = "http://www.w3.org/2000/svg";
var busy = false;
function animationDelegate(evt, direction){
/* Check if we are busy before doing anything.*/
/* If we are, stop executing this request, otherwise, set busy to true.*/
if(busy) return; else busy = true;
if(direction === 'cw') cwAnim(evt);
else if(direction === 'ccw') acwAnim(evt);
/* Your duration is 1 second, so 1000ms.*/
/* Set a timeout that resets busy.*/
setTimeout(function(){ busy = false}, 1000);
}
function cwAnim(evt){
if ( window.svgDocument == null)
svgDoc = evt.target.ownerDocument;
addRotateTransform('someShape', 1, -1, 180);
addRotateTransform('shape1', 1, 1, 360);
addRotateTransform('shape2', 1, 1, 360);
}
function acwAnim(evt){
if ( window.svgDocument == null)
svgDoc = evt.target.ownerDocument;
addRotateTransform('someShape', 1, 1, 180);
addRotateTransform('shape1', 1, -1, 360);
addRotateTransform('shape2', 1, -1, 360);
}
function addRotateTransform(target_id, dur, dir, angle){
var my_element = svgDoc.getElementById(target_id);
var a = svgDoc.createElementNS(svgNS, "animateTransform");
var bb = my_element.getBBox();
var cx = bb.x + bb.width/2;
var cy = bb.y + bb.height/2;
a.setAttributeNS(null, "attributeName", "transform");
a.setAttributeNS(null, "attributeType", "XML");
a.setAttributeNS(null, "type", "rotate");
a.setAttributeNS(null, "dur", dur + "s");
a.setAttributeNS(null, "repeatCount", "1");
a.setAttributeNS(null, "fill", "freeze");
a.setAttributeNS(null, "additive", "sum");
a.setAttributeNS(null, "accumulate", "sum");
a.setAttributeNS(null, "from", "0 "+cx+" "+cy);
a.setAttributeNS(null, "to", angle*dir+" "+cx+" "+cy);
my_element.appendChild(a);
a.beginElement();
}
<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="600px" height="600px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<circle stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
<g id="someShape">
<circle fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" cx="468.451" cy="474.385" r="350" />
<path id="shape1" fill="#DC5A00" stroke="#000000" stroke-miterlimit="10" d="M692.373,317.798C692.373,418.425,606.244,500,500,500
c-106.245,0-192.374-81.575-192.374-182.202c0-100.629,86.128-182.204,192.374-182.204
C606.244,135.595,692.373,217.169,692.373,317.798z M553.391,220.34c-39.316,0-71.188,31.87-71.188,71.187
s31.871,71.187,71.188,71.187c39.314,0,71.186-31.87,71.186-71.187S592.705,220.34,553.391,220.34z" />
<path id="shape2" fill="#3DFF63" stroke="#000000" stroke-miterlimit="10" d="M577.368,647.034c0,69.738-56.913,126.271-127.119,126.271
c-70.206,0-127.119-56.533-127.119-126.271c0-69.737,56.913-126.271,127.119-126.271
C520.455,520.764,577.368,577.297,577.368,647.034z M466.352,617.373c-21.998,0-39.831,17.453-39.831,38.983
c0,21.529,17.833,38.982,39.831,38.982s39.831-17.453,39.831-38.982C506.182,634.826,488.349,617.373,466.352,617.373z" />
</g>
<g onclick="animationDelegate(evt, 'ccw')">
<rect x="89.762" y="815.369" stroke="#000000" stroke-miterlimit="10" width="217.865" height="134.426" />
<text transform="matrix(1 0 0 1 127.4673 864.5491)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">AntiClockwise</text>
</g>
<g onclick="animationDelegate(evt, 'cw')">
<rect x="692.373" y="815.369" stroke="#000000" stroke-miterlimit="10" width="194.11" height="134.426" />
<text transform="matrix(1 0 0 1 752.0576 869.467)" fill="#FFFFFF" font-family="'MyriadPro-Regular'" font-size="21">Clockwise</text>
</g>
</svg>

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