How to draw a star by using canvas HTML5?

2019-02-17 14:41发布

问题:

Am trying to draw a star using canvas, but the code is not running. I want to understand: what are the steps to measure the Y and X coordinate? How to find them? to draw any shape?

<html>
 <head>
   <meta charset = "utf-8">
   <title>Drawing Lines</title>
 </head>
 <body>
   <canvas id = "drawLines" width = "400" height = "200" 
     style = "border: 1px solid Black;">
   </canvas>
   <script>
     var canvas = document.getElementById("drawLines");
     var context = canvas.getContext("2d")

     canvas.beginPath(); 
     canvas.moveTo(50,50);
     canvas.lineTo(120,150);
     canvas.lineTo(0,180); 
     canvas.lineTo(120,210);
     canvas.lineTo(50,310);  
     canvas.lineTo(160,250);
     canvas.lineTo(190,370);
     canvas.lineTo(220,250);
     canvas.lineTo(330,310);
     canvas.lineTo(260,210);
     canvas.lineTo(380,180);
     canvas.closePath();
     canvas.stroke();
   </script>
 </body>
</html>

回答1:

A star is basically a regular polygon with alternating points on an inner and an outer radius.

Here's an example of a flexible function to draw a star shape.

You can set the position, #spikes and the inner & outer radius of the spikes:

Example code and a Demo: http://jsfiddle.net/m1erickson/8j6kdf4o/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>
<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    function drawStar(cx,cy,spikes,outerRadius,innerRadius){
      var rot=Math.PI/2*3;
      var x=cx;
      var y=cy;
      var step=Math.PI/spikes;

      ctx.beginPath();
      ctx.moveTo(cx,cy-outerRadius)
      for(i=0;i<spikes;i++){
        x=cx+Math.cos(rot)*outerRadius;
        y=cy+Math.sin(rot)*outerRadius;
        ctx.lineTo(x,y)
        rot+=step

        x=cx+Math.cos(rot)*innerRadius;
        y=cy+Math.sin(rot)*innerRadius;
        ctx.lineTo(x,y)
        rot+=step
      }
      ctx.lineTo(cx,cy-outerRadius);
      ctx.closePath();
      ctx.lineWidth=5;
      ctx.strokeStyle='blue';
      ctx.stroke();
      ctx.fillStyle='skyblue';
      ctx.fill();
    }

    drawStar(100,100,5,30,15);

}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>


回答2:

Those functions, lineTo(), moveTo(), stroke(), etc... belong to the context object, not the canvas object. Are you checking your developer console (f12 in Chrome)? You would see that these functions are undefined.



回答3:

The function can be shorter with coordinate translate:

function strokeStar(x, y, r, n, inset) {
    ctx.save();
    ctx.beginPath();
    ctx.translate(x, y);
    ctx.moveTo(0,0-r);
    for (var i = 0; i < n; i++) {
        ctx.rotate(Math.PI / n);
        ctx.lineTo(0, 0 - (r*inset));
        ctx.rotate(Math.PI / n);
        ctx.lineTo(0, 0 - r);
    }
    ctx.closePath();
    ctx.fill();
    ctx.restore();
}


回答4:

As mentioned by @v-rubinetti, you are trying to call methods incorrectly.

While it can be easy to draw a simple star in canvas by coding, it's complicated for drawing advanced things. You can use a open-source Vector graphics software like Inkscape along with the ink2canvas extension to draw advanced vector graphics and save them to a html5 document.

For example, here is a 25-pointed Star drawn in Inkscape and saved using ink2canvas extension:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Inkscape Output</title>
</head>
<body>
    <canvas id='canvas' width='320' height='320'></canvas>
    <script>
    var ctx = document.getElementById("canvas").getContext("2d");
    ctx.save();
    ctx.lineJoin = 'miter';
    ctx.strokeStyle = 'rgb(0, 0, 0)';
    ctx.lineCap = 'butt';
    ctx.lineWidth = 1.000000;
    ctx.fillStyle = 'rgb(255, 255, 0)';
    ctx.beginPath();
    ctx.transform(0.506236, 0.000000, 0.000000, 0.505711, 82.274469, 51.410524);
    ctx.moveTo(342.857130, 449.505040);
    ctx.lineTo(234.764940, 344.516400);
    ctx.lineTo(279.468630, 488.419550);
    ctx.lineTo(200.881970, 359.847880);
    ctx.lineTo(208.393950, 510.347410);
    ctx.lineTo(164.250710, 366.271350);
    ctx.lineTo(134.098980, 513.910810);
    ctx.lineTo(127.172840, 363.383190);
    ctx.lineTo(61.251941, 498.885850);
    ctx.lineTo(91.978093, 351.364870);
    ctx.lineTo(-5.569921, 466.216610);
    ctx.lineTo(60.877887, 330.971560);
    ctx.lineTo(-62.167941, 417.955810);
    ctx.lineTo(35.826363, 303.484630);
    ctx.lineTo(-104.985860, 357.135850);
    ctx.lineTo(18.397601, 270.631190);
    ctx.lineTo(-131.333260, 287.578290);
    ctx.lineTo(9.686712, 234.475540);
    ctx.lineTo(-139.554650, 213.653670);
    ctx.lineTo(10.241036, 197.289490);
    ctx.lineTo(-129.133450, 140.006950);
    ctx.lineTo(20.025741, 161.409550);
    ctx.lineTo(-100.724450, 71.265628);
    ctx.lineTo(38.426018, 129.090210);
    ctx.lineTo(-56.112700, 11.748970);
    ctx.lineTo(64.285711, 102.362200);
    ctx.lineTo(1.898679, -34.803371);
    ctx.lineTo(95.979959, 82.904945);
    ctx.lineTo(69.664621, -65.466342);
    ctx.lineTo(131.517300, 71.941014);
    ctx.lineTo(142.927140, -78.313274);
    ctx.lineTo(168.664780, 70.159311);
    ctx.lineTo(217.082890, -72.536949);
    ctx.lineTo(205.088300, 77.671789);
    ctx.lineTo(287.472380, -48.500313);
    ctx.lineTo(238.499240, 94.006409);
    ctx.lineTo(349.672790, -7.713676);
    ctx.lineTo(266.798250, 118.136810);
    ctx.lineTo(399.775840, 47.260185);
    ctx.lineTo(288.207210, 148.546780);
    ctx.lineTo(434.633360, 112.967060);
    ctx.lineTo(301.380910, 183.325570);
    ctx.lineTo(452.055130, 185.278350);
    ctx.lineTo(305.491610, 220.287880);
    ctx.lineTo(450.946490, 259.650470);
    ctx.lineTo(300.281000, 257.111240);
    ctx.lineTo(431.377070, 331.410340);
    ctx.lineTo(286.076510, 291.481900);
    ctx.lineTo(394.576520, 396.049020);
    ctx.lineTo(263.770630, 321.240230);
    ctx.closePath();
    ctx.fill();
    ctx.stroke();
    ctx.restore();
    </script>
</body>
</html>


回答5:

//function to draw star with N spikes
//centered on a circle of radius R, centered on (cX,cY)
function star(R, cX, cY, N) {
  //star draw
  ctx.beginPath();
  ctx.moveTo(cX + R,cY);
  for(var i = 1; i <= N * 2; i++)
  {
    if(i % 2 == 0){
      var theta = i * (Math.PI * 2) / (N * 2);
      var x = cX + (R * Math.cos(theta));
      var y = cY + (R * Math.sin(theta));
    } else {
      var theta = i * (Math.PI * 2) / (N * 2);
      var x = cX + ((R/2) * Math.cos(theta));
      var y = cY + ((R/2) * Math.sin(theta));
    }

    ctx.lineTo(x ,y);
  }
  ctx.closePath();
  ctx.stroke();
}