2

Playing with a breakout clone and wanted to make rounded corner powerups.

Can someone point me in the right direction?

Thanks!

Todd Vance
  • 4,627
  • 7
  • 46
  • 66
  • 1
    Duplicate of [How to draw a rounded Rectangle on HTML Canvas?](http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas); see [this answer](http://stackoverflow.com/a/7838871/405017) in particular. And next time, search the site or web for answers first, please. – Phrogz Mar 13 '12 at 22:38

2 Answers2

6

A simple way is to use quadraticCurveTo to smooth out corners

enter image description here

let roundRect = (ctx, x0, y0, x1, y1, r, color) => {
      var w = x1 - x0;
      var h = y1 - y0;
      if (r > w/2) r = w/2;
      if (r > h/2) r = h/2;
      ctx.beginPath();
      ctx.moveTo(x1 - r, y0);
      ctx.quadraticCurveTo(x1, y0, x1, y0 + r);
      ctx.lineTo(x1, y1-r);
      ctx.quadraticCurveTo(x1, y1, x1 - r, y1);
      ctx.lineTo(x0 + r, y1);
      ctx.quadraticCurveTo(x0, y1, x0, y1 - r);
      ctx.lineTo(x0, y0 + r);
      ctx.quadraticCurveTo(x0, y0, x0 + r, y0);
      ctx.closePath();
      ctx.fillStyle = color;
      ctx.fill();
  },
  ctx = document.getElementById("canvas").getContext("2d");
  
roundRect(ctx, 50, 50, 150, 100, 5, "#F00");
roundRect(ctx, 50, 110, 100, 160, 10, "#00F");
roundRect(ctx, 53, 113, 97, 157, 7, "#0F0");
<canvas id="canvas" width="200" height="180"></canvas>
6502
  • 112,025
  • 15
  • 165
  • 265
  • Nice graphic, but it's far simpler to use the `arcTo`, no? (As evidenced in the duplicate question I found and linked to while you were presumably writing up your answer.) – Phrogz Mar 14 '12 at 01:20
  • 2
    @Phrogz: Using a bezier arc makes trivial to have anisotropic rounding and the difference between a quarter circle and a quadratic bezier arc is IMO small enough to be acceptable in most cases. Canvas `arc/arcTo` are in my opinion quite badly designed (and I even found compatibility problems in the past between browsers): I normally use `arc` just to draw full circles. You are right about duplicates, but IMO a bezier quadratic is better for this use. – 6502 Mar 14 '12 at 06:40
3

You can do what's shown on this article by Juan Mendes:

HTML:

<canvas id="rounded-rect" width="600" height="600">
    <!-- Insert fallback content here -->
</canvas>​

JavaScript:

CanvasRenderingContext2D.prototype.roundRect = function(x, y, width, height, radius, fill, stroke) {
    if (typeof stroke == "undefined") {
        stroke = true;
    }
    if (typeof radius === "undefined") {
        radius = 5;
    }
    this.beginPath();
    this.moveTo(x + radius, y);
    this.lineTo(x + width - radius, y);
    this.quadraticCurveTo(x + width, y, x + width, y + radius);
    this.lineTo(x + width, y + height - radius);
    this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    this.lineTo(x + radius, y + height);
    this.quadraticCurveTo(x, y + height, x, y + height - radius);
    this.lineTo(x, y + radius);
    this.quadraticCurveTo(x, y, x + radius, y);
    this.closePath();
    if (stroke) {
        this.stroke(stroke);
    }
    if (fill) {
        this.fill(fill);
    }
};

// Now you can just call
var ctx = document.getElementById("rounded-rect").getContext("2d");
// Manipulate it again
ctx.strokeStyle = "#2d6";
ctx.fillStyle = "#abc";
ctx.roundRect(100, 200, 200, 100, 50, true);

As you can see on this JsFiddle

DarkAjax
  • 15,955
  • 11
  • 53
  • 65