Mr.Banks
Mr.Banks

Reputation: 437

How to make a small triangle in a rectangle shape in canvas?

I want to add a small triangle similar to this example: JSFiddle

As you can see from the image there is a triangle in the middle of the side, I would like to have that in canvas.

This is what I have so far

// JavaScript for drawing on canvas
// applying colors + three triangles

function draw() {
  // canvas with id="myCanvas"
  var canvas = document.getElementById('myCanvas');
  if (canvas.getContext) {
    var ctx = canvas.getContext('2d');
    roundRect(ctx, 100, 100, 180, 60, 10, true);
  }
}


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

draw();
<canvas id="myCanvas" width="700" height="410">
  <p>Some default content can appear here.</p>
</canvas>
<p>Triangles!</p>

Upvotes: 1

Views: 1366

Answers (2)

Blindman67
Blindman67

Reputation: 54041

4 arcs for a rounded box plus a triangle to fit..

You can create a rounded box with just the rounded corners. Adding the triangle is just a matter of setting out the 3 points between drawing two corners.

The example draws two types of quote boxes, left and right.

The size, corner radius, triangle size and position are all set as arguments.

The animation is just to show the variations possible.

const ctx = canvas.getContext("2d");


// r is radius of corners in pixels
// quoteSize in pixels
// quotePos as fraction of avalible space 0-1
function roundedQuoteBoxLeft(x, y, w, h, r, quoteSize, quotePos) {

  // draw 4 corners of box from top, left, top right , bottom right, bottom left
  ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
  ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
  ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
  ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
  
  // make sure trianle fits
  if (quoteSize > h - r * 2) { quoteSize = h - r * 2 }

  // get triangle position
  var qy = (h - (r * 2 + quoteSize)) * quotePos + r + y;
  
  // draw triangle
  ctx.lineTo(x, qy + quoteSize);
  ctx.lineTo(x - quoteSize, qy + quoteSize / 2);
  ctx.lineTo(x, qy);

 // and add the last line back to start
  ctx.closePath();
}

function roundedQuoteBoxRight(x, y, w, h, r, quoteSize, quotePos) {

  // draw top arcs from left to right
  ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
  ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);

  // make sure trianle fits
  if (quoteSize > h - r * 2) { quoteSize = h - r * 2 }

  // get pos of triangle
  var qy = (h - (r * 2 + quoteSize)) * quotePos + r + y;

  // draw triangle
  ctx.lineTo(x + w, qy);
  ctx.lineTo(x + w + quoteSize, qy + quoteSize / 2);
  ctx.lineTo(x + w, qy + quoteSize);

  // draw remaining arcs
  ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
  ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);

  // and add the last line back to start
  ctx.closePath();
}


function sin(time) {
  return Math.sin(time) * 0.5 + 0.5;
}
requestAnimationFrame(drawIt)

function drawIt(time) {
  ctx.clearRect(0, 0, 500, 250);
  // get some sizes 
  var width = sin(time / 1000) * 100 + 100;
  var height = sin(time / 1300) * 50 + 100;
  var radius = sin(time / 900) * 20 + 5;
  var x = sin(time / 1900) * 20 + 20;
  var y = sin(time / 1400) * 50 + 10;
  var quotePos = sin(time / 700)
  var quoteSize = x - 10;
  
  
  // set up box render
  
  ctx.lineJoin = "round";
  ctx.strokeStyle = "#8D4";
  ctx.lineWidth = 4;
  ctx.fillStyle = "#482";
  
  // draw left quote box
  ctx.beginPath();
  roundedQuoteBoxLeft(x, y, width, height, radius, quoteSize, quotePos);
  ctx.fill();
  ctx.stroke()
  
  
  x += width + 10;
  width = 500 - x - quoteSize;
  
  // draw right quote box
  ctx.beginPath();
  roundedQuoteBoxRight(x, y, width, height, radius, quoteSize, quotePos);
  ctx.fill();
  ctx.stroke()

  /// animate
  requestAnimationFrame(drawIt)
}
<canvas id="canvas" width="500" height="250"></canvas>

Upvotes: 1

Nihal
Nihal

Reputation: 5334

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Your Canvas</title>

<style type="text/css"><!--
#container { position: relative; }
#imageTemp { position: absolute; top: 1px; left: 1px; }
--></style>

</head>
<body> 
<canvas id="imageView" width="600" height="500"></canvas>

<script type="text/javascript">
var canvas, context, canvaso, contexto;
canvaso = document.getElementById('imageView');
context = canvaso.getContext('2d');
context.lineWidth = 5;

context.strokeStyle = '#000000';
context.beginPath();
context.moveTo(143, 224);
context.lineTo(168, 191);
context.stroke();
context.closePath();

context.strokeStyle = '#000000';
context.beginPath();
context.moveTo(143, 221);
context.lineTo(169, 247);
context.stroke();
context.closePath();



context.strokeStyle = '#000000';
context.strokeRect(168, 124, 242, 182);
</script>
</body>
</html>

Upvotes: 0

Related Questions