I wrote a code to drawing polygons:
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
svg.setAttribute('width', '100%');
svg.setAttribute('height', window.innerHeight);
document.querySelector('#bg').appendChild(svg);
for(var x = 0; x < polygons.length; x++){
var polygon = document.createElementNS(svg.namespaceURI, 'polygon');
polygon.setAttribute('points', polygons[0 + x]);
polygon.setAttribute('fill', polygons[0 + x][1]);
svg.appendChild(polygon);
}
My full code with polygon points:
http://codepen.io/anon/pen/WrqrbB
I would like to animate this polygons similar to this animation:
http://codepen.io/zessx/pen/ZGBMXZ
How to animate my polygons?
You can
call an animation function to manipulate your coordinate values as desired,
convert them to a string, e.g. using .join(),
send the resulting string back to the polygon as its points attribute value, redrawing the shape (as you were already doing when you initially created your shapes), and
have the animation function, when it is finished, call itself again at a reasonable built-in time-delay using requestAnimationFrame.
The following snippet gives a basic idea of what can be done.
(Note that I've redefined the array polygons in my example so that it is different from what you had, but that was done for the sake of simplicity in this example.)
var svg = document.getElementsByTagName("svg")[0];
var polygons = [], numSteps = 100, stepNum = 0;
var coords = [
[40, 20, 80, 20, 80, 60, 40, 60],
[140, 20, 180, 20, 160, 50]
];
for (var x = 0; x < coords.length; x++) {
polygons[x] = document.createElementNS(svg.namespaceURI, 'polygon');
polygons[x].setAttribute('points', coords[x].join());
svg.appendChild(polygons[x]);
}
function anim() {
for (var x = 0; x < coords.length; x++) {
coords[x] = coords[x].map(function(coord) {
return coord + 4 * (Math.random() - 0.5);
});
polygons[x].setAttribute('points', coords[x].join());
stepNum += 1;
}
if (stepNum < numSteps) requestAnimationFrame(anim);
}
anim();
<svg></svg>
UPDATE The above snippet shows generally how to animate a polygon. In your case, however, there is a further issue. On your codepen demo, it is clear that you have hard-coded the point coordinates for each polygon separately. Thus, if you want to move one point, you're going to have to update coordinates in at least 2 if not more places, for every polygon that touches that point.
A better approach would be to create a separate array of all points and then define each polygon with respect to that array. (This is similar to how things are sometimes done in 3D graphics, e.g. WebGL.) The following code snippet demonstrates this approach.
var svg = document.getElementsByTagName("svg")[0];
var polyElems = [], numSteps = 100, stepNum = 0;
var pts = [[120,20], [160,20], [200,20], [240,20], [100,50], [140,50], [180,50], [220,50], [260,50], [120,80], [160,80], [200,80], [240,80]];
var polyPts = [[0,1,5], [1,2,6], [2,3,7], [0,4,5], [1,5,6], [2,6,7], [3,7,8], [4,5,9], [5,6,10], [6,7,11], [7,8,12], [5,9,10], [6,10,11], [7,11,12]];
for (var x = 0; x < polyPts.length; x++) {
polyElems[x] = document.createElementNS(svg.namespaceURI, 'polygon');
polyElems[x].setAttribute('fill', '#'+Math.floor(Math.random()*16777215).toString(16));
// random hex color routine from http://www.paulirish.com/2009/random-hex-color-code-snippets/
drawPolygon(x);
}
function anim() {
pts = pts.map(function(pt) {
return pt.map(function(coord) {
return coord + 3 * (Math.random() - 0.5); // move each point
});
});
for (var x = 0; x < polyPts.length; x++) {drawPolygon(x);}
stepNum += 1;
if (stepNum < numSteps) requestAnimationFrame(anim); // redo anim'n until all anim'n steps done
}
anim(); // start the animation
function drawPolygon(x) {
var ptNums = polyPts[x];
var currCoords = [pts[ptNums[0]], pts[ptNums[1]], pts[ptNums[2]]].join();
// creates a string of coordinates; note that [[1,2],[3,4],[5,6]].join() yields "1,2,3,4,5,6"
polyElems[x].setAttribute('points', currCoords);
svg.appendChild(polyElems[x]);
}
<svg></svg>
Related
is it possible to number a list of points in p5.js?
Right now I am using ml5.pj for face mesh detections, which outputs x and y coordinates for a set of 465 points.
I want to select a few. In order to do that, I need to know what are the corresponding indexes.
Any possible way to do this?
Not relevant, but on Grasshopper 3D, it is a component called "point list"
let facemesh;
let video;
let predictions = [];
function setup() {
createCanvas(640, 480);
video = createCapture(VIDEO);
video.size(width, height);
facemesh = ml5.facemesh(video, modelReady);
// This sets up an event that fills the global variable "predictions"
// with an array every time new predictions are made
facemesh.on("predict", results => {
predictions = results;
});
// Hide the video element, and just show the canvas
video.hide();
}
function modelReady() {
console.log("Model ready!");
}
function draw() {
// image(video, 0, 0, width, height);
background(255);
// We can call both functions to draw all keypoints
drawKeypoints();
}
// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
for (let i = 0; i < predictions.length; i += 1) {
const keypoints = predictions[i].scaledMesh;
// Draw facial keypoints.
for (let j = 0; j < keypoints.length; j += 1) {
const [x, y] = keypoints[j];
fill(0, 255, 0);
ellipse(x, y, 3, 3);
}
}
}
Okay, if I understand you correctly you want to add labeling to each point. You could get sophisticated with this and have it on hover via tracking the cursor coordinates and using those as a key to access an object val. However, since you say you are not well rounded in programming -- I'm going to keep this super simple here...
We are just going to add text to where the point is and have it offset vertically by 5px. You can read more about text here in the p5.js documentation: https://p5js.org/reference/#/p5/text
Here's a link on template literals in js: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
for (let i = 0; i < predictions.length; i += 1) {
const keypoints = predictions[i].scaledMesh;
// Draw facial keypoints.
for (let j = 0; j < keypoints.length; j += 1) {
const [x, y] = keypoints[j];
fill(0, 255, 0);
ellipse(x, y, 3, 3);
text(`${i}-${j}`, x, y+5); // Draw Text with Index Labelling
}
}
}
Advanced: Showing the text on hover.
Create an Object to show the values based on x-y:i-j key:vals
Detect Mouse X, Y Coordinates
Display on Hover
const hoverCoords = {}
function draw() {
background(255);
drawKeypoints();
hoverCoords[`${mouseX}-${mouseY}`] && text(hoverCoords[`${mouseX}-${mouseY}`], x, y+5)
}
// A function to draw ellipses over the detected keypoints
function drawKeypoints() {
for (let i = 0; i < predictions.length; i += 1) {
const keypoints = predictions[i].scaledMesh;
// Draw facial keypoints.
for (let j = 0; j < keypoints.length; j += 1) {
const [x, y] = keypoints[j];
hoverCoords[`${x}-${y}`] = `${i}-${j}` // Create object key val
fill(0, 255, 0);
ellipse(x, y, 3, 3);
}
}
}
I haven't tested the above but you know should be the right approach using an object and setting coordinates as key vals and then being able to do a truthy match on that to display the i-j vals. Look into objects in javascript.
I've got this code. What I want the code to do is to make the ball move and when the ball goes over a grey spot (holes) it goes back to the starting point. I've done that by creating a random place for the grey holes. I simply need to find a way to define the position of these holes even though they are randomized.
var startPoint = new Path.Circle(new Point(40, 40), 40);
startPoint.fillColor = "green";
//finishPoint
var finishPoint = new Path.Circle(new Point(1300, 600), 40);
finishPoint.fillColor = "red";
var ball = new Path.Circle(new Point(40, 40), 20);
ball.fillColor = "black";
//holes
var path = new Path(new Point(20, 20), new Point(20, 23));
path.style = {
strokeColor: 'grey',
strokeWidth: 70,
strokeCap: 'round'
};
var holes = new Symbol(path);
for (var i = 0; i < 10; i++) {
var placement = view.size * Point.random();
var placed = holes.place(placement);
}
var vector = new Point(0, 0);
function onFrame(event) {
ball.position += vector / 100;
}
var moves = new Point(100, 1);
function onKeyDown(event) {
if (event.key === "s") {
vector.y += 10;
}
if (event.key === "d") {
vector.x += 10;
}
if (event.key === "a") {
vector.x -= 10;
}
if (event.key === "w") {
vector.y -= 10;
}
var ballPlace = ball.position;
if (ballPlace.isClose(finishPoint.position, 40) == true) {
var text = new PointText(view.center);
text.content = 'Congratulations';
text.style = {
fontFamily: 'Courier New',
fontWeight: 'bold',
fontSize: 100,
fillColor: 'gold',
justification: 'center'
};
ball.remove();
}
if(ballPlace.isClose(placement.position, 40) == true) {
ball = new Point(40, 40);
}
};
and I want the ball to go back to Point(40, 40) when it goes over a grey hole (var holes) but I can't get it to work. Any idea how to fix this?
You want to test the ball's position against the holes to see if the ball goes back to the starting position. The simplest way I can think of to do this is to create a group of the holes then test the position of the ball against that group. In the following code the ball's position is simulated via the onMouseMove function and the holes are flashed red to indicate when the ball would be returned to the the starting position.
var holes = [];
var hole;
for (var i = 0; i < 10; i++) {
hole = new Path.Circle(view.size * Point.random(), 10);
hole.fillColor = 'grey';
holes.push(hole);
}
holes = new Group(holes);
onMouseMove = function(e) {
if (holes.hitTest(e.point)) {
holes.fillColor = 'red';
} else {
holes.fillColor = 'grey';
}
Here's an implementation: sketch. It should be straightforward to replaced onMouseMove with onFrame, move the ball as you currently do, and then test to see if it falls into a hole.
In order to test if the ball is over a hole you can remove on the onMouseMove function and replace it with:
onFrame = function(e) {
ball.position += vector / 100;
if (holes.hitTest(ball.position)) {
// move the ball wherever you want to move it, position text,
// etc. you might have to loop through the array to find which
// hole was hit.
}
}
#Luke Park is right about using an array.
Trial each new point, by ensuring it is a distance from all other existing points. Example below (not scaled to view.size).
p = Point.random();
while ( isTooClose(p, points) ) {
p = Point.random();
}
It's possible for this to loop infinitely, but if you're populating the area sparsely, there should be no problem.
isTooClose tests each point in array p, where distance = sqrt(dxdx + dydy). If you have many points, you can optimise by avoiding sqrt(), by testing whether the raw dx and dy values are smaller than the test radius.
You can also use a similar function on each frame, to test for collision.
Using jsDraw2DX, I am trying to use a series on concentric circles to display a position upon a floor plan. An array holds all drawn circles to permit clean removal. The original plan was to have them appear one-by-one, stay for 5 seconds, then to disappear one-by-one. I backed off of that due to troubles with setTimeout, and decided that just the circles image was enough, provided it could stay for a bit, then disappear, ready for the next locate operation. In the stripped down code below, The circles draw OK and remove OK, provided the one alert (marked in the code) is present, but not otherwise.
How might I make this work in the case that no alert was present?
How might I add a 5 second delay before removal?
How might it also work with an additional slight delay between drawing or removing each circle?
CTest
var oldCircle = new Array;
var iter = 0;
var rad = 4;
document.addEventListener("click", printMousePos);
function printMousePos(e) {
var cursorX = e.clientX-10;
var cursorY = e.clientY-10;
//alert("clicked: X: " + cursorX + " Y: " + cursorY);
rad = 4;
animateLocator(cursorX, cursorY);
}
function animateLocator(x, y) {
//alert("Entered animateLocator: rad: "+rad+" x: "+x+" y: "+y);
var start = new Date().getTime();
//alert("starting push");
pushall(rad, x, y);
iter = 0;
//for(i=0; i<10; i++) {
// pushFunc(rad+i*4, x, y);
//}
alert("starting pop"); // This alert box makes it work OK; otherwiudse nothing appears.
setTimeout(popall(), 2000);
}
function pushall(rad, x, y) {
iter = 0;
for(i=0; i<10; i++) {
pushFunc(rad+i*4, x, y);
}
}
function popall() {
iter = 0;
for(i=0; i<10; i++) {
popFunc();
}
}
function pushFunc(rad, x, y) { oldCircle.push(drawCircle(rad, x, y)); }
function popFunc() { oldCircle.pop().remove(); }
function drawCircle(rad, x, y) {
iter++;
//alert("drawCircle rad: "+rad+" x: "+x+" y: "+y);
//Create jxColor object
var col = new jxColor("red");
//Create jxPen object
var pen = new jxPen(col,'2px');
//Create jsGraphics object
var gr = new jxGraphics(document.getElementById("graphics"));
var ctr = new jxPoint(x,y);
var cir = new jxCircle(ctr, rad+iter*4, pen);
//alert("after jxcircle");
cir.draw(gr);
//alert("after draw");
return cir;
}
demo
Remove the alert and Change:
setTimeout(popall(), 2000);
To:
setTimeout(popall, 2000);
I've been trying to figure this out for a couple of days now but I can't seem to get it right.
Basically, I have some divs whose parent has a CSS perspective and rotateX 3D transformations applied and I need to get the actual on-screen coordinates of those divs.
Here's a jsfiddle with an example of what I mean (albeit not working properly).
https://jsfiddle.net/6ev6d06z/3/
As you can see, the vertexes are off (thanks to the transformations of its parents)
I've tried using
getBoundingClientRect()
but that doesn't seem to be taking the 3D transforms into consideration.
I don't know if there's an already established method to get what I need but otherwise I guess there must be a way of calculating the coordinates using the matrix3D.
Any help is appreciated.
As it is there is not a builtin way to get the actual 2d coordinates of each vertex of the transformed element. In the case of all the APIs (such as getBoundingClientRect), they return a bounding rectangle of the transformed element represented as a 2point rectangle [(top,left), (bottom,right)].
That being said, you can absolutely get the actual coordinates with a little bit of effort and matrix math. The easiest thing to do would be to use a premade matrix library to do the math (I've head good things about math.js but have not used it), although it is certainly doable yourself.
In pseudo-code for what you will need to do:
Get the untransformed bounds of the transformed parent element in the document coordinate system.
Get the untransformed bounds of the target element in the document coordinate system.
Compute the target's untransformed bounds relative to the parent's untransformed bounds.
a. Subtract the top/left offset of (1) from the bounds of (2).
Get the css transform of the parent element.
Get the transform-origin of the parent element (defaults to (50%, 50%)).
Get the actual applied transform (-origin * css transform * origin)
Multiply the four vertices from (3) by the computed transform from (6).
Perform the homogeneous divide (divide x, y, z by the w component) to apply perspective.
Transform the projected vertices back into the document coordinate system.
Fun!
And then for fun in real code: https://jsfiddle.net/cLnmgvb3/1/
$(".target").on('click', function(){
$(".vertex").remove();
// Note: The 'parentOrigin' and 'rect' are computed relative to their offsetParent rather than in doc
// coordinates. You would need to change how these offsets are computed to make this work in a
// more complicated page. In particular, if txParent becomes the offsetParent of 'this', then the
// origin will be wrong.
// (1) Get the untransformed bounds of the parent element. Here we only care about the relative offset
// of the parent element to its offsetParent rather than it's full bounding box. This is the origin
// that the target elements are relative to.
var txParent = document.getElementById('transformed');
var parentOrigin = [ txParent.offsetLeft, txParent.offsetTop, 0, 0 ];
console.log('Parent Origin: ', parentOrigin);
// (2) Get the untransformed bounding box of the target elements. This will be the box that is transformed.
var rect = { left: this.offsetLeft, top: this.offsetTop, right: this.offsetLeft + this.offsetWidth, bottom: this.offsetTop + this.offsetHeight };
// Create the vertices in the coordinate system of their offsetParent - in this case <body>.
var vertices =
[
[ rect.left, rect.top, 0, 1 ],
[ rect.right, rect.bottom, 0, 1 ],
[ rect.right, rect.top, 0, 1 ],
[ rect.left, rect.bottom, 0, 1 ]
];
console.log('Original: ', vertices);
// (3) Transform the vertices to be relative to transformed parent (the element with
// the CSS transform on it).
var relVertices = [ [], [], [], [] ];
for (var i = 0; i < 4; ++i)
{
relVertices[i][0] = vertices[i][0] - parentOrigin[0];
relVertices[i][1] = vertices[i][1] - parentOrigin[1];
relVertices[i][2] = vertices[i][2];
relVertices[i][3] = vertices[i][3];
}
// (4) Get the CSS transform from the transformed parent
var tx = getTransform(txParent);
console.log('Transform: ', tx);
// (5) Get the CSS transform origin from the transformed parent - default is '50% 50%'
var txOrigin = getTransformOrigin(txParent);
console.log('Transform Origin: ', txOrigin);
// (6) Compute the full transform that is applied to the transformed parent (-origin * tx * origin)
var fullTx = computeTransformMatrix(tx, txOrigin);
console.log('Full Transform: ', fullTx);
// (7) Transform the vertices from the target element's bounding box by the full transform
var txVertices = [ ];
for (var i = 0; i < 4; ++i)
{
txVertices[i] = transformVertex(fullTx, relVertices[i]);
}
console.log('Transformed: ', txVertices);
// (8) Perform the homogeneous divide to apply perspective to the points (divide x,y,z by the w component).
var projectedVertices = [ ];
for (var i = 0; i < 4; ++i)
{
projectedVertices[i] = projectVertex(txVertices[i]);
}
console.log('Projected: ', projectedVertices);
// (9) After the transformed vertices have been computed, transform them back into the coordinate
// system of the offsetParent.
var finalVertices = [ [], [], [], [] ];
for (var i = 0; i < 4; ++i)
{
finalVertices[i][0] = projectedVertices[i][0] + parentOrigin[0];
finalVertices[i][1] = projectedVertices[i][1] + parentOrigin[1];
finalVertices[i][2] = projectedVertices[i][2];
finalVertices[i][3] = projectedVertices[i][3];
}
// (10) And then add the vertex elements in the 'offsetParent' coordinate system (in this case again
// it is <body>).
for (var i = 0; i < 4; ++i)
{
$("<div></div>").addClass("vertex")
.css('position', 'absolute')
.css('left', finalVertices[i][0])
.css('top', finalVertices[i][1])
.appendTo('body');
}
});
function printMatrix(mat)
{
var str = '';
for (var i = 0; i < 4; ++i)
{
for (var j = 0; j < 4; ++j)
{
str += (' ' + mat[i][j]);
}
str += '\r\n';
}
console.log(str);
}
function getTransform(ele)
{
var st = window.getComputedStyle(ele, null);
var tr = st.getPropertyValue("-webkit-transform") ||
st.getPropertyValue("-moz-transform") ||
st.getPropertyValue("-ms-transform") ||
st.getPropertyValue("-o-transform") ||
st.getPropertyValue("transform");
var values = tr.split('(')[1],
values = values.split(')')[0],
values = values.split(',');
var mat = [ [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1] ];
if (values.length === 16)
{
for (var i = 0; i < 4; ++i)
{
for (var j = 0; j < 4; ++j)
{
mat[j][i] = +values[i * 4 + j];
}
}
}
else
{
for (var i = 0; i < 3; ++i)
{
for (var j = 0; j < 2; ++j)
{
mat[j][i] = +values[i * 2 + j];
}
}
}
return mat;
}
function getTransformOrigin(ele)
{
var st = window.getComputedStyle(ele, null);
var tr = st.getPropertyValue("-webkit-transform-origin") ||
st.getPropertyValue("-moz-transform-origin") ||
st.getPropertyValue("-ms-transform-origin") ||
st.getPropertyValue("-o-transform-origin") ||
st.getPropertyValue("transform-origin");
var values = tr.split(' ');
var out = [ 0, 0, 0, 1 ];
for (var i = 0; i < values.length; ++i)
{
out[i] = parseInt(values[i]);
}
return out;
}
function createTranslateMatrix(x, y, z)
{
var out =
[
[1, 0, 0, x],
[0, 1, 0, y],
[0, 0, 1, z],
[0, 0, 0, 1]
];
return out;
}
function multiply(pre, post)
{
var out = [ [], [], [], [] ];
for (var i = 0; i < 4; ++i)
{
for (var j = 0; j < 4; ++j)
{
var sum = 0;
for (var k = 0; k < 4; ++k)
{
sum += (pre[k][i] * post[j][k]);
}
out[j][i] = sum;
}
}
return out;
}
function computeTransformMatrix(tx, origin)
{
var out;
var preMul = createTranslateMatrix(-origin[0], -origin[1], -origin[2]);
var postMul = createTranslateMatrix(origin[0], origin[1], origin[2]);
var temp1 = multiply(preMul, tx);
out = multiply(temp1, postMul);
return out;
}
function transformVertex(mat, vert)
{
var out = [ ];
for (var i = 0; i < 4; ++i)
{
var sum = 0;
for (var j = 0; j < 4; ++j)
{
sum += +mat[i][j] * vert[j];
}
out[i] = sum;
}
return out;
}
function projectVertex(vert)
{
var out = [ ];
for (var i = 0; i < 4; ++i)
{
out[i] = vert[i] / vert[3];
}
return out;
}
Note: The accepted answer is not cross browser compatible. This has to do with the stupidly diverse ways browsers calculate offset properties.
I changed the answer above to use
var rect=this.getBoundingClientRect()
and the results is more cross-browser compatible.
https://jsfiddle.net/2znLxda2/
I am trying to incrementally draw 3 lines which are 120 degrees from each other from a point using html5 canvas. The vertex of each lines will become another 3 new center point and spawns another 3 lines at each center and it repeats this..
My problem is, the incremental speed becomes slower and slower (or the drawing becomes slower) as more items are drawn. (maybe something happens in my code but I am not quite familiar how canvas exactly works...). You can copy the code and run it in your local browser to see what I means.
Please see my code (it is very easy to understand) and tell me what causes this.
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="canvas" ></canvas>
<script>
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
canvas.width= window.innerWidth;
canvas.height= window.innerHeight;
// some staring test values
var centerPt={x:canvas.width/2,y:canvas.height/2};
var radius=100;
var angle=0;
// calculate the 3 endpoints at 120 degree separations
var endPt000=anglePoint(centerPt,90);
var endPt120=anglePoint(centerPt,210);
var endPt240=anglePoint(centerPt,330);
var length = 0;
var maxLength = 100;
var centreSet = new Array();
centreSet = getCentres();
var counter = 0;
var end = centreSet.length;
init();
function init() {
start(centreSet[0].x, centreSet[0].y);
}
function start(myX, myY) {
centerPt.x = myX;
centerPt.y = myY;
animate(centerPt, length);
}
function animate(centerPt,length) {
// update
// clear
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw stuff
draw(centerPt,length);
length = length + 1;
// request new frame
if(length < maxLength){
requestAnimFrame(function() {
animate(centerPt,length);
});
}
else{
if(counter < end){
counter = counter + 1;
centerPt.x = centreSet[counter].x;
centerPt.y = centreSet[counter].y;
endPt000=anglePoint(centerPt,90);
endPt120=anglePoint(centerPt,210);
endPt240=anglePoint(centerPt,330);
length = 0;
setTimeout(function(){animate(centerPt, length);},600);
}
}
}
// draw a red center dot
// draw 3 blue endpoint dots
// draw 3 lines from center going slider% of the way to the endpoints
function draw(centerPt,sliderValue){
var pct=sliderValue;
ctx.clearRect(0,0,canvas.width,canvas.height);
line(centerPt,pointAtPercent(centerPt,endPt000,pct),"green");
line(centerPt,pointAtPercent(centerPt,endPt120,pct),"green");
line(centerPt,pointAtPercent(centerPt,endPt240,pct),"green");
}
// calc XY at the specified angle off the centerpoint
function anglePoint(centerPt,degrees){
var x=centerPt.x-radius*Math.cos( degrees*Math.PI/180 );
var y=centerPt.y-radius*Math.sin( degrees*Math.PI/180 );
return({x:x,y:y});
}
// just draw a line from point1 to point2
function line(pt1,pt2,color){
// ctx.beginPath();
ctx.moveTo(pt1.x,pt1.y);
ctx.lineTo(pt2.x,pt2.y);
ctx.strokeStyle=color;
ctx.lineWidth=2;
ctx.stroke();
}
// calc XY which is a specified percent distance from pt1 to pt2
function pointAtPercent(pt1,pt2,sliderValue) {
// calculate XY at slider% towards pt2
var x = pt1.x + (pt2.x-pt1.x) * sliderValue/100;
var y = pt1.y + (pt2.y-pt1.y) * sliderValue/100;
return({x:x,y:y});
}
//the following are used to get all the center points...
function getCentres() {
var x = window.innerWidth/2;
var y = window.innerHeight/2;
centreSet[0] = centerPt;
var ref = 0;
var end = 0;
var b = true;
var tempCenter = centerPt;
for(var j = 0; j < 5; j++){
tempCenter = centreSet[ref];
end = end + 1;
centreSet[end] = anglePoint(tempCenter,90);
end = end + 1;
centreSet[end] = anglePoint(tempCenter,210);
end = end + 1;
centreSet[end] = anglePoint(tempCenter,330);
ref = ref+1;
}
return centreSet;
}
</script>
</body>
</html>
The problem is you are appending and appending the path. This means that each time you call stroke() the new line together with all the old lines are stroked. You won't see this clearly as the old lines are drawn on top in the same location. And as more and more lines are added the more time it takes to stroke them..
To prevent this you need to break the path. Do this with beginPath().
If you activate your out-commented line it should work fine:
function line(pt1,pt2,color){
ctx.beginPath(); //<-- activate this
ctx.moveTo(pt1.x,pt1.y);
ctx.lineTo(pt2.x,pt2.y);
ctx.strokeStyle=color;
ctx.lineWidth=2;
ctx.stroke();
}