I have been trying to print arc in the html page. How can i remove the already drawn arch from the page?. i have written the below code.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="1200" height="1000"
style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
/*ctx.beginPath();
ctx.arc(600,500,20, 0.5*Math.PI,2*Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(600,500,40, 0.5*Math.PI,2*Math.PI);
ctx.stroke();
*/
var radius=20;
for (i=0; i<10; i++)
{
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(600,500,radius, 0.5*Math.PI, 2*Math.PI);
ctx.stroke();
radius= radius+30;
}
</script>
</body>
</html>
How can i achieve this?.
Call clearRect method:
ctx.clearRect(0, 0, 1200, 1000)
The four arguments are:
axis-X of left top corner of the area to wipe
axis-Y of left top corner of the area to wipe
width of the area to wipe
height of the area to wipe
So with this method, you could wipe either the whole canvas or just a certain part of it.
If you want to remove the whole previously drawn image please take a look at the other anwers. In the comments OP made it clear that this is not what he was trying to achieve. So instead I will answer the intended question:
How do I un-stroke a path?
A bitmap is not a vector graphic. You cannot simply remove or modify things you've drawn previously. By drawing on a canvas you modify the pixel color values of its image data. If you need to undo things you have to maintain a separate data structure with the relevant data yourself.
For example you could create a copy of the image data before drawing something. Then you could return to this snapshot afterwards. HTMLCanvasElement#toDataURL returns the complete image as an url which you can use as the src of an image. Later you can draw this image on the canvas to revert all subsequent changes. HTMLCanvasElement#toBlob does about the same but it returns a blob. This might consume less memory but it's a little more inconvenient to use. The most convenient method is CanvasRenderingContext2D#getImageData. You can even use it to copy only a small part of the image. This is useful if you have a big canvas but only modify pixels in a small region.
Another way to make modifications undoable is by maintaining a detailed list of your steps. For example whenever you draw an arc you store the exact parameters as one entry in the list. steps.push({type: 'stroke', style: 'rgb(0,0,0)', shapes: [{type: 'arc', x: 600, y: 500, radius: radius, from: 0.5 * Math.PI, to: 2 * Math.PI}]}) You can remove, rearrange or modify the elements in this list any way you like and have all necessary information to draw the resulting image from scratch. Basically you've implemented just another vector graphic library.
Related
I'm making a UI in Angular6 where I have a list that occupies the left third of the screen with selectable entries that upon selection reveal additional data of that entry.
the additional data does not move but the the selected line in the entries can because the list is scrollable and also selecting it will change which line is highlighted obviously.
I want to make it visually clear to the user that the additional data he is seeing corresponds to the entry selected in the list.
here's what I have now :
as you can see I've already helped out the user visually by highlighting the entry in the list and the whole additional data view in the same light blue
and here's my attempt at sealing the deal in terms of the view's clarity :
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="400" height="180">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(0, 20);
ctx.lineTo(400, 180);
ctx.lineTo(400, 40);
ctx.lineTo(0, 0);
ctx.fillStyle = '#9ec7e2';
ctx.fill();
</script>
<p><strong>Note:</strong> The canvas tag is not supported in Internet Explorer 8 and earlier versions.</p>
</body>
</html>
But I'm facing here a challenge I've never faced before : I need it to be dynamic and fluid.
I know I could JQuery-watch both select and scroll and also JQuery get X-Y coordinates of top and bottom corners of relevant divs, then redraw the canvas on every scroll and select call but that sounds extra poor performance-wise, and with a high probability of flashing (re-draws) while I scroll.
not to mention this all sounds extra clunky and poor execution,
Plus I'm fairly certain any resizing of the window or any other easy test would break the illusion.
Isn't there a new more "CSS3-SASS-SVG-Angular6" approach?
I want to draw a following chart in JavaScript. Basically, the goal is to draw some rectangles in a cartesian coordinate system. Each rectangle can be represented by 4 points, whose coordinates are given.
Does anyone know how to draw it? Is there any library to do so? Ideally, i would expect some example code that I could adjust a little bit, rather than drawing everything from scratch.
You have two main options:
SVG - vector graphics that are pretty similar to HTML (you have elements with attributes etc). you can also use CSS for styling SVG.
canvas - this is basically a bitmap on which you can draw with JS.
(HTML) - of caurse you could also use simple HTML + CSS.
Here are some tutorials about those two:
http://svgtutorial.com/manipulating-svg-with-javascript/
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes
There are bunch of 3rd party libraries to help with this like:
https://d3js.org/
http://dmitrybaranovskiy.github.io/raphael/
http://fabricjs.com/
http://paperjs.org/
Here is simple example with canvas:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.strokeRect(0, 0, 400, 200);
ctx.strokeRect(0, 200 - 20, 20, 20);
ctx.strokeRect(30, 200 - 70, 20, 70);
<canvas id="canvas" width="400" height="400"></canvas>
I've created a game that works with canvas, and i need it to be in a very low resolution to fit a software I'm working with. besically when I draw a diagonal line it should appear as a diagonal row of squares.
I did
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
but it's just blurry. How can I convert it?
the top picture is what it looks like now and the bottom is what i want it to look like
One approach is to use image smoothing disabled with a low-resolution canvas. Though you will get a blocky line, you will also get the anti-aliased pixels included. The only way to avoid this is to implement line algorithms etc. yourselves such as Bresenham (see below example).
You can also draw the lines, then run through the bitmap pixel by pixel and use a threshold value to filter the anti-aliased pixels away but this will give various results and is dependent on having isolated paths to work with, ie. draw to off-screen, filter with threshold, then draw result to main canvas.
An example:
var mctx = main.getContext("2d"),
lowRes = document.createElement("canvas"),
ctx = lowRes.getContext("2d");
// setup low-res canvas (invisible)
lowRes.width = 32;
lowRes.height = 20;
// setup main visible canvas
mctx.imageSmoothingEnabled =
mctx.msImageSmoothingEnabled =
mctx.mozImageSmoothingEnabled =
mctx.webkitImageSmoothingEnabled = false;
// draw a line to off-screen canvas
ctx.moveTo(0, lowRes.height);
ctx.lineTo(lowRes.width - 7, 4);
ctx.lineWidth=4;
ctx.strokeStyle = "#fff";
ctx.stroke();
// draw bacground on main canvas
mctx.fillRect(0,0,500,300);
// draw in low-res line
mctx.drawImage(lowRes, 0,0,lowRes.width,lowRes.height,
0,0,main.width,main.height);
<canvas id="main" width=500 height=300></canvas>
I would also like to propose to check out my Retro Context library (free/GPL3) which was made for this very reason. It has implemented all these line algorithms and has a full and simple API to access them (and much more "retro" related).
Optionally, you would need to implement these line algorithms yourselves. Here are some resources to help you get started if you chose this approach:
Bresenham line algorithm
Mid-point circle algorithm
This may be off topic but I'm not sure where else to go with this question. I'm just getting started with HTML5 canvas element and all of the incredibly powerful things it can do. I was hoping someone could offer some advise. When working with custom paths and bezier curves, what is the easiest/best way to visualize where the points belong on the canvas to achieve a desired effect. Right now it feels like I'm just guessing plotting points in any place hoping to end up with the right angle/shape that I want.
To be more specific I want to create a shape that will act as an image mask, and will later need to animate this shape. Much like this fiddle http://jsfiddle.net/jimrhoskins/dDUC3/1/ (someone else's work) but since I can't see where the picture is on the canvas or where any of the points are, I'm really just guessing at the approximate shape I need to make. I'm just wondering if there's a better way, or some function in javascript that can map the location of an image and give me at least a better place to start.
Here is what I know/have tried already
// Grab the Canvas and Drawing Context
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
// Create an image element
var img = document.createElement('IMG');
// When the image is loaded, draw it
img.onload = function () {
// Save the state, so we can undo the clipping
context.save();
// Create a shape, of some sort
context.beginPath();
context.moveTo(somex, somey);
context.bezierCurveTo(somexstart, someystart, somexcontrol, someycontro, somexend, someyend);
context.arcTo(somecoordinates);
context.closePath();
// Clip to the current path
context.clip();
context.drawImage(img, 0, 0);
// Undo the clipping
context.restore();
}
// Specify the src to load the image
img.src = "url";
How about opening the image in an SVG editor. Drawing a path on a layer above the image. Then open the SVG and copy the coordinates?
Try an SVG Editor. You can get the points there. You can add images too. SVG animation is used nowadays as well. If you have Adobe Illustrator, it will be easier to draw there and just save it as SVG.
Say I drew a rectangle on the canvas. Surely there is some sort of built in method to get the XY coordinates, and dimensions of that rectangle? But after some googling I came up with nothing. And just to clarify, I am not talking about the coordinates of the canvas element itself, but rather a shape/image that is drawn unto the canvas.
Any help is appreciated.
If you're talking about a 2D canvas drawing, then the drawing maps 1:1 with screen coordinates, so it is just location of <canvas> + location of the drawing.
To clarify, drawing on a <canvas> basically just changes the pixels of the canvas - after you draw to it, you can't reference the drawn object the same way you can reference an html element.
Canvas is 2D table (Array) of numbers (= pixels = colors). When drawing into canvas, you are just editing this table. When you draw into canvas (= change numbers in table), what should be the coordinates of your adjustment?
If you are drawing rectangles only and you can define the coordinates for your rectangle, you must know your coordinates inside a program, because you have just drawn it.
If you want your image to be separated into some "objects" (shapes), you should use SVG.
Basically, you should be using canvas as a means to output graphics to the screen and the rest of your logic goes straight into the JavaScript that powers your game/application. The best way to go about making something like this is to create objects and assign properties to them; in its simplest form that can look like this:
function Player(x, y)
{
this.x = x;
this.y = y;
}
var examplePlayerObject = new Player(20, 20);
By extending this object via prototyping you can create multiple copies of an object that has the exact same functions; such as draw. Drawing the player in this instance could just be a red square that is 20px*20px.
Player.prototype.draw = function()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = 'red';
context.fillRect(this.x, this.y, 20, 20);
}
Then, you should have an update step with some means of clearing what is on the screen and redrawing the parts which have changed.
function animationStep()
{
examplePlayerObject.x++;
examplePlayerObject.y++;
examplePlayerObject.draw();
}
This animation step should run each frame; look into requestAnimationFrame for smooth animation. Paul Irish has a good shim for older browsers. Add in requestAnimationFrame(animationStep) at the end of that function and you will have a red square moving slowly across the screen. Good luck!