Skip to content
Advertisement

drawStar() with mouse inside canvas mouse up mouse down

What am I missing? The drawCircle and DrawPolygon (it is located in codepen https://codepen.io/mancod/pen/oNYdrVL work fine. I am still very new to all this still, and beat myself up as nothing in life should be this messy. A star is a circle as is a polygon. I get that the star has an inner and outer radius, but I cannot get this star. Thank you in advance for eyes that can fill in the part I am missing or have in the wrong order for function drawStar(). I have commented out the drawline and drawcircle. If you want to know it that even work you can view it on https://jsfiddle.net/mancod/mhbrqxk8/45/ where I have commented out the drawStar.

`enter code here`var canvas,
    context,
    dragging = false,
    dragStartLocation,
    snapshot;
    


`enter code here`function getCanvasCoordinates(event) {
    var x = event.clientX - canvas.getBoundingClientRect().left,
        y = event.clientY - canvas.getBoundingClientRect().top;

    return {x: x, y: y};
}

`enter code here`function takeSnapshot (){
 snapshot = context.getImageData(0, 0, canvas.width, canvas.height);
  
}

`enter code here`function restoreSnapshot() {
   context.putImageData(snapshot, 0, 0);
}


`enter code here`function drawLine(position) {
    context.beginPath();
    context.moveTo(dragStartLocation.x, dragStartLocation.y);
    context.lineTo(position.x, position.y);
    context.stroke();
}

`enter code here`// this is for making circles 
//d(P, Q) = p(x2 − x1)2 + (y2 − y1)2 {Distance formula}
//https://orion.math.iastate.edu/dept/links/formulas/form2.pdf
// comment out function to go back to drawing just straight lines.
function drawCircle (position) {
 var radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
   context.beginPath();
   context.arc(position.x, position.y, radius, 0, 2 * Math.PI, false);
   
   context.fill();
}

**function drawStar (position, points, outerRadius, innnerRadius) {
var coordinates=[],
radius = index%2 == 0? outerRadius : innerRadius,
index=0;
for (index = 0; index < points; index++) {
        coordinates.push({x: dragStartLocation.x + radius * Math.cos(angle), y: dragStartLocation.y - radius * Math.sin(angle)});
        angle += Math.PI / points;
        
context.beginPath();
context.drawStar(position, points, innerRadius, outerRadius);
    context.moveTo(coordinates[0].x, coordinates[0].y+outerRadius);
    //for (index = 1; index < points; index++) //{
        //context.lineTo(coordinates[index].x + radius *Math.cos(angle), coordinates[index].y + radius * Math.sin(angle));
    //}
}
    context.closePath();
}**




function dragStart(event) {
    dragging = true;
    dragStartLocation = getCanvasCoordinates(event);
  takeSnapshot();
}

function drag(event) {
    var position;
  
    if (dragging === true) {
    restoreSnapshot();
        position = getCanvasCoordinates(event);
        //to not see the radius line just reverse the order of the two below
      //drawCircle(position);
        //drawLine(position);
drawStar(position, 6, 2, 15);
    }
}

function dragStop(event) {
    dragging = false;
  restoreSnapshot();
    var position = getCanvasCoordinates(event);
    
      //to not see the radius line just reverse the order of the two below
  //drawCircle(position);
    //drawLine(position);
drawStar(postion,6, 2,15);
}


    canvas = document.getElementById("cv0");
    context = canvas.getContext('2d');
     context.strokeStyle = 'orange';
    
   context.fillStyle = 'hsl(' + 360*Math.random() +', 100%, 45%)';
 
    context.lineWidth = 5;

    canvas.addEventListener('mousedown', dragStart, false);
    canvas.addEventListener('mousemove', drag, false);
    canvas.addEventListener('mouseup', dragStop, false);

Advertisement

Answer

Let’s have a look at the parameter definition for the drawStar() function:

drawStar (position, points, outerRadius, innnerRadius)

and remind ourselves what a typical stylized star looks like

a star

Alright so far. There are two places the drawStar function gets called: inside draw and dragStop. In both cases you’re calling it like

drawStar(position, 6, 2, 15);

This means we pass 6 as the number of points for the star shape – if we look above we can see that star is made up of 10 points. The second mistake here is the hardcoded values 2 and 15 for the radius of the star. I think you want to dynamically size it according to the movement of the mouse, so we need to recalculate the radii on mouse move. Well as we don’t have a use for the two parameters we can get rid of it altogether and just call it like:

drawStar(position, 10);

Inside the drawStar function we need to calculate the points for the star shape like:

  for (index = 0; index < points; index++) {
    if (index % 2 == 0) {
      radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
    } else {
      radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2)) * 0.5;
    }
    coordinates.push({
      x: dragStartLocation.x + radius * Math.cos(angle),
      y: dragStartLocation.y - radius * Math.sin(angle)
    });
    angle += Math.PI / points * 2;
  }

As you can see where dynamically calculating the radius for the inner and outer points, pushing the points into the coordinates array and ultimately adding 36° to the angle variable (360°/10 points=36°)

Finally let’s iterate over the coordinates array and draw the lines to screen:

  context.beginPath();
  context.moveTo(coordinates[0].x, coordinates[0].y);
  for (index = 1; index < points; index++) {
    context.lineTo(coordinates[index].x, coordinates[index].y);
  }
  context.closePath();
  context.fill();

Here’s a working example based on your fiddle:

var canvas,
  context,
  dragging = false,
  dragStartLocation,
  snapshot;



function getCanvasCoordinates(event) {
  var x = event.clientX - canvas.getBoundingClientRect().left,
    y = event.clientY - canvas.getBoundingClientRect().top;

  return {
    x: x,
    y: y
  };
}

function takeSnapshot() {
  snapshot = context.getImageData(0, 0, canvas.width, canvas.height);

}

function restoreSnapshot() {
  context.putImageData(snapshot, 0, 0);
}


function drawLine(position) {
  context.beginPath();
  context.moveTo(dragStartLocation.x, dragStartLocation.y);
  context.lineTo(position.x, position.y);
  context.stroke();
}

// this is for making circles 
//d(P, Q) = p(x2 − x1)2 + (y2 − y1)2 {Distance formula}
//https://orion.math.iastate.edu/dept/links/formulas/form2.pdf
// comment out function to go back to drawing just straight lines.
function drawCircle(position) {
  var radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
  context.beginPath();
  context.arc(position.x, position.y, radius, 0, 2 * Math.PI, false);

  context.fill();
}

function drawStar(position, points) {

  var coordinates = [];
  var index;
  var radius;
  var angle = Math.PI / 2;
  for (index = 0; index < points; index++) {
    if (index % 2 == 0) {
      radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2));
    } else {
      radius = Math.sqrt(Math.pow((dragStartLocation.x - position.x), 2) + Math.pow((dragStartLocation.y - position.y), 2)) * 0.5;
    }
    coordinates.push({
      x: dragStartLocation.x + radius * Math.cos(angle),
      y: dragStartLocation.y - radius * Math.sin(angle)
    });
    angle += Math.PI / points * 2;
  }

  context.beginPath();
  context.moveTo(coordinates[0].x, coordinates[0].y);
  for (index = 1; index < points; index++) {
    context.lineTo(coordinates[index].x, coordinates[index].y);
  }
  context.closePath();
  context.fill();
}




function dragStart(event) {
  dragging = true;
  dragStartLocation = getCanvasCoordinates(event);
  takeSnapshot();
}

function drag(event) {
  var position;

  if (dragging === true) {
    restoreSnapshot();
    position = getCanvasCoordinates(event);
    //to not see the radius line just reverse the order of the two below
    //      drawCircle(position);
    //drawLine(position);
    drawStar(position, 10);
  }
}

function dragStop(event) {
  dragging = false;
  restoreSnapshot();
  var position = getCanvasCoordinates(event);

  //to not see the radius line just reverse the order of the two below
  // drawCircle(position);
  //drawLine(position);
  drawStar(position, 10);
}


canvas = document.getElementById("cv0");
context = canvas.getContext('2d');
context.strokeStyle = 'orange';

context.fillStyle = 'hsl(' + 360 * Math.random() + ', 100%, 45%)';

context.lineWidth = 5;

canvas.addEventListener('mousedown', dragStart, false);
canvas.addEventListener('mousemove', drag, false);
canvas.addEventListener('mouseup', dragStop, false);
#cv0 {
  border: solid gray;
}
<canvas id='cv0' width=400 height=300></canvas>
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement