How would one make this shape in an HTML5 canvas? - html

I'm wonder how you would go about and create a shape similar to this one below in HTML5 Canvas. It's more or less a cropped circle I guess, though my need would render it a synch different.
http://img826.imageshack.us/img826/5198/98359410.jpg
context.fillStyle = "#000";
context.beginPath();
context.arc(200,200,100,0,Math.PI*2,true);
context.closePath();
context.fill();
Now to crop the booger, I'm perplexed. Could anyone lend me a hand? Thanks!

context.globalCompositeOperation = 'destination-in';
context.fillRect(200, 220, 200, 100); //Or something similar
destination-in means, per MDC: The existing canvas content is kept where both the new shape and existing canvas content overlap. Everything else is made transparent.
Or conversly
context.fillRect(200, 220, 200, 100);
context.globalCompositeOperation = 'source-in';
//Draw arc...
source-in means: The new shape is drawn only where both the new shape and the destination canvas overlap. Everything else is made transparent
Both these methods will end up disrupting other content already drawn to canvas, if this is an issue, use clip
context.save();
context.beginPath();
//Draw rectangular path
context.moveTo(200, 220);
context.lineTo(400, 220);
context.lineTo(400, 320);
context.lineTo(200, 320);
context.lineTo(200, 220);
//Use current path as clipping region
context.clip();
//Draw arc...
//Restore original clipping region, likely the full canvas area
context.restore()

Related

HTML5 Canvas draw rectangle on image of canvas

I shown series of images into my canvas (series of medical images). I'd like to draw a rectangle on specific image. The reectangle will be disappeared if I scroll to other images. How can I do?
Below is my code. The rectangle is shown well but when I scroll to next image, the rectangle also keep display.
const context = eventData.canvasContext.canvas.getContext('2d');
context.beginPath();
context.strokeStyle = 'yellow';
context.lineWidth = 2;
context.rect(Number(203.353) - 13, Number(322.691) - 13, 25, 25);
context.stroke();
Thanks,
Lam

How can I draw a line with lineTo in HTML5 that has angles to match the Unit Circle?

If I have this,
var canvas = document.getElementById("my-canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(25, 25);
ctx.lineTo(150, 25);
ctx.rotate(Math.PI*7/4); //315 degrees
ctx.lineTo(150,90);
ctx.stroke();
It does not draw the line (the ctx.lineTo(150,90);) at the angle I thought it would which is from the end of the first lineTo at 25,25 to a 150,90 at a 45 degree angle. If I use -Math.PI*7/4 I get what looks like a 45 degree angle, but it points the wrong way. Math.PI*5/4 goes the wrong way or rotation.
My question asks about the Unit Circle. I don't really need them all at once, just the ability to know how to draw them if I need them.
The canvas is rotating this way:
Consider the following example, without the y offset:
Given by the code:
var canvas = document.getElementById("my-canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.moveTo(25, 0);
ctx.lineTo(250, 0);
ctx.rotate(45*Math.PI/180); //45 degrees
ctx.lineTo(150,0);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(0,0);
ctx.strokeStyle = '#ff0000';
ctx.lineTo(350,0);
ctx.font = "30px Arial";
ctx.fillText("New x axis",100,50);
ctx.stroke();
The red line is the new x axis, and the black line touches it exactly at a distance of 150 from the origin.
Now overlaying the same red line with your coordinates (and rotating by 45 degrees, so that it doesn't go off screen), we get
The black line ends at a point which is indeed (150,90), however at the new coordinate system. JSFiddle here
If you want the angle between the two line segments to be exactly what you pass in rotate(...), then keep drawing "horizontal" lines, but translate the origin to the end of each line segment, so you rotate about this point, not the top-left corner, using ctx.translate(<current point>). For example: https://jsfiddle.net/Douma37/65z1p38z/ (this goes off canvas, but has minimal interferance with your code).
Hope that helps!

Canvas inner stroke

I studied strokeStyle a bit but I cant find how to control the position of the stroke from inner/center/outer. It seems all stroke is outside the rectangle I draw. Is there anyway make the stroke be inner? (or even centered on the rectangle bounds)?
Thanks
Hope this helps!
Instead of doing:
ctx.fill();
ctx.stroke();
DO:
ctx.save();
ctx.clip();
ctx.lineWidth *= 2;
ctx.fill();
ctx.stroke();
ctx.restore();
Edit
For me I believe this works because the clip method removes any fill and stroke around the already present fill area, meaning the only place the stroke can go is on the inside because else it would be clipped off.
The default stroke do use centered stroke but there is unfortunately no parameter to control the alignment of the stroke so you would either have to calculate an offset value for the rectangle's position and size, or combine two rectangles and use for example the fill-rule evenodd:
var ctx = c.getContext("2d");
// default centered
ctx.lineWidth = 10;
ctx.strokeRect(10, 10, 100, 100);
ctx.lineWidth = 1;
ctx.strokeStyle = "red";
ctx.strokeRect(10, 10, 100, 100); // show main path
// inner
ctx.rect(150, 10, 100, 100);
ctx.rect(150+10, 10+10, 100-20, 100-20); // offset position and size
ctx.fill("evenodd"); // !important
ctx.strokeRect(150, 10, 100, 100);
<canvas id=c></canvas>
This answer "Draw outer and inner border around any canvas shape" shows how to use masking and compositing to precisely control the offset, both inwards and outwards of a stroke without the need to manipulate paths. It can be used for any canvas path no matter how complex.

HTML5 canvas adding dots/circles to canvas line - can i combine lines and circles to 'join the dots'?

I've made 2 Line paths with 'lineTo' which change direction at various points - these have plotted fine. These lines are rendered by canvas, not svg.
I need to add circles at the points in the lines where they change direction, namely at the lineTo points e.g: context.lineTo(149, 50). This would look like joining dots.
I don't know how to add these dots to the lines or if it is possible - can anyone advise please?
Thanks in advance. See below for the markup:
<div class="wrapper">
<canvas id="myCanvas" width="300" height="300"></canvas>
</div>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// attributes
context.lineWidth = 2;
context.lineJoin = 'round';
// left line
context.beginPath();
context.moveTo(10, 20);
context.lineTo(149, 50);
context.lineTo(50, 100);
context.lineTo(149, 150);
context.lineTo(109, 200);
context.strokeStyle = "red";
context.stroke();
// right line
context.beginPath();
context.moveTo(10, 20);
context.lineTo(109, 50);
context.lineTo(60, 110);
context.lineTo(109, 150);
context.lineTo(85, 200);
context.strokeStyle = "blue";
context.stroke();
</script>
I don't know if there is a specific function for drawing dots at turning points of a path, but why not drawing circles where you want them by yourself?
You can simply draw circles on the direction-changin-points by using the arc() method (here well explained). As you already know the coordinates from the lineTo() points, this should be a piece of cake ;)

HTML5 Canvas: position of drawing cursor

I can't find out how to get actual drawing cursor position after moveTo(). Check out my code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.moveTo(10, 20);
// here i want to get from "ctx" actual offset
ctx.lineTo(20,30);
ctx.closePath();
Is there any way or I have to store offset in my own variables offsetX, offsetY ?
I assume you mean you have a bunch of relative path commands and you want to move them.
For instance, to draw a triangle at the top-left you would write:
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(100,0);
ctx.lineTo(50,100);
ctx.closePath(); // makes the last line for you
ctx.stroke();
So what if you want to use the same path but draw the triangle starting at (175, 175) instead? Instead of changing your moveTo and all subsequent drawing command, all you have to do is translate the context.
ctx.save();
ctx.translate(175, 175);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(100,0);
ctx.lineTo(50,100);
ctx.closePath(); // makes the last line for you
ctx.stroke();
// save/restore lets you undo the translation so the next object starts at (0,0)
// you could just call ctx.translate(-175, -175); at the end instead though
ctx.restore();
Translating the context changes the origin of the drawing surface, and allows you to move all of your coordinates (temporarily or not) with it. This means you can define a bunch of paths and redraw them using the same commands all over the place using ctx.translate.
See both triangles here:
http://jsfiddle.net/qzYFC/