Clear canvas button in Javascript/HTML not working - javascript

So my code displays an html page with some text on it and then below that I have a "clear Canvas" button which I would like to have clear the canvas once pushed and then be able to draw on this blank canvas. My clear canvas button isn't working, it isn't doing anything once pushed. I'm using a call back in order to perform the canvas clear and the html file is connected to a javascript file which then draws things on the new cleared canvas. The first code here is the .html file with the canvas that is being cleared that also has the.js file joined to it.
I tried context.Rect(x, y, w, h);
and canvas.width.canvas.width;
and neither seem to work. I'm using Chrome
<html><head></head>
<h3> </h3>
<body >
<canvas id="main" width="300" height="500"></canvas>
<script>
var canvas = document.getElementById("main");
var context = canvas.getContext('2d');
context.fillStyle = "#008000";
context.rect(0,0,300,300);
context.fill();
</script>
</body></html>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="user-scalble=no,initial-scale=1.0,maximum-scale=1.0" />
<style>
body { padding:10px; margin:0px; background-color: #FF9; }
#main { margin: 10px auto 0px auto; }
</style>
<script src=".js"></script>
</head>
<body >
<button id="clear">Clear Canvas</button><br>
<canvas id="main" width="300" height="500"></canvas>
</body>
</html>
//end of .html file
// JavaScript Document
// wait until window is fully loaded into browser
window.onload = function()
{
// so smart phone does not move/resize image when touched
document.ontouchmove = function(e)
{
e.preventDefault();
}
var canvas = document.getElementById('main');
// Number of pixels used by the Clear button above canvas
var canvasTop = canvas.offsetTop;
var context = canvas.getContext('2d');
var lastX, lastY;
context.strokeStyle = #FA8072;
context.lineCap = 'round';
context.lineJoin = 'round';
context.lineWidth = 8;
context.fill();
// Function to Clear the Canvas
function clear()
{
context.fillStyle = 'blue'
context.rect( 0, 0, 300, 500);
context.fill();
}
// Function Dot (to start a new line or just a point)
function dot(x,y)
{
context.beginPath();
context.fillStyle = '#D2691E';
// draw tiny circle
context.arc(x,y,1,0, Math.PI*2, true);
context.fill();
context.closePath();
}
// Handle the Clear button
var clearButton = document.getElementById('clear');
// set callback funct. clear()for future touch events
clearButton.onclick = clear;
clear(); // do a clear canvas now
} // end window.onload

You've got a typo on this line:
context.strokeStyle = #FA8072;
You need quotes:
context.strokeStyle = '#FA8072';
With that fixed it seems to work: http://jsfiddle.net/eMSXU/
(By the way, you might like to press the "Tidy Up" button in the fiddle to see how your code should've been indented...)

Related

Removing text in HTML5 Canvas?

I'm working on a HTML5 Canvas project and have some text drawn on the screen. Right now, it appears and just stay there, but what I need is for it to disappear after a few seconds so that every time it's called it's not just new text being drawn on top of the old text.
I tried clearRect() but that completely clears the entire rectangle and removes some of my background too, which I don't want.
Is there a way to do this?
I'm drawing the text with this basic function:
function drawText() {
ctx.font = "30px Arial";
ctx.fillText("Please wait...", 575, 130);
}
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<button onclick="showTheText()">Click to show text</button>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
function showTheText() {
var myText = {
text: 'Hello World',
x: 0,
y: 75,
fill: 1
};
drawText(myText, context);
// wait one second before starting animation
setTimeout(function() {
animate(myText, canvas, context);
}, 1000);
}
function drawText(myText, context) {
context.font="30px Arial";
context.fillStyle="rgb(0, 0, 0, " + myText.fill + ")";
context.fillText(myText.text, myText.x, myText.y);
}
function animate(myText, canvas, context) {
// clear
context.clearRect(0, 0, canvas.width, canvas.height);
// !!!!!!!! redraw your background !!!!!!!!
// then redraw your text with new opacity
myText.fill -= .1;
drawText(myText, context);
// request new frame
if (myText.fill > -.1) {
setTimeout(function() {
animate(myText, canvas, context);
}, 2000 / 60);
}
}
</script>
</body>
</html>
Hope this can help you. What it does it immediately draws the text (and the rest of your background, you didn't provide it), then sets up a recursive timeout that will clear the rect, redraw your background, decrement the amount of opacity to apply to the text's fill, and redraw the text as well. You can slow it down by changing the time of the last setTimeout.
I adapted it from this example: https://www.html5canvastutorials.com/advanced/html5-canvas-animation-stage/
you can create a simple function to delete ,
you will need some values. For example, font height. width of character ... etc ,
for example in this case , you can use the following function , With few modifications :
function removeText(x,y,txt_length,font_height,char_width,ctx) {
ctx.clearRect(x, y-font_height ,char_width*txt_length,font_height);
}
and this function for write your string :
function drawText(x,y,text,ctx) {
ctx.font = "30px Arial";
ctx.fillText(text,x,y);
}
The same parameters x and y are passed to the functions and txt_length = text.length;
Once you've drawn text to canvas, it's no longer text - it's just a bunch of pixels! Since those pixels overwrite what is already there, there's no way to delete just the text.
Generally what you can do is re-draw the entire scene without the text, if you want to get rid of it.
You could also try re-drawing the text in the same position using the background color, which would remove the text, but this only works if the text is on a solid background.
To achieve expected use below option of fillStyle in clearText function
Create another function clearText with fillStyle white color with same text and x , y coordinates
Call clearText function from the drawText
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
function drawText() {
clearText()
ctx.font = "30px Arial";
ctx.fillStyle = "black";
ctx.fillText("Please wait...", 575, 130);
}
function clearText() {
ctx.font = "30px Arial";
ctx.fillStyle = "white";
ctx.fillText("Please wait...", 575, 130);
}
<button onclick="drawText()">draw text</button><br>
<canvas id="myCanvas" width="800" height="800"
style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>
code sample - https://codepen.io/nagasai/pen/oqOXxz

The countdown timer is not working properly when I insert few numbers such as 31,41,51,61

I want to show a countdown timer using JavaScript. However when I insert the current value to be 31,41,51,99,61,81 and few other numbers I am unable to get the Arc based on the inserted current value. The Arc should display the current value. As the number gets reducing, closer to Zero, the Arc should keep moving towards completing the circle.
I tried using HTML5 Canvas, I almost close to getting the answer but it's throwing some error.
The fields should have Maximum Value input text field and Current Value text field and a button which on clicked should display the Current Value Arc inside Canvas Element. Please help
<!-- Click event function, works when button is clicked -->
function clickevent()
{
var max=document.getElementById("maxsec").value;
var curr=document.getElementById("currsec").value;
myFunction(max,curr);
}
//This is the
function myFunction(maxvalue,currentvalue) {
//alert(maxvalue + ' ' + currentvalue);
if (currentvalue<=maxvalue)
{
var x = (2*3.14*currentvalue/maxvalue);
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
ctx.font="15px Georgia";
ctx.textAlign = "center";
ctx.fillText(currentvalue,c.width/2, c.height/2);
ctx.beginPath();
ctx.arc(75, 75, 50, x, 2 * Math.PI);
// ctx.lineWidth = 10;
// line color
ctx.strokeStyle = 'black';
ctx.stroke();
}
if (maxvalue==currentvalue)
{
ctx.clearRect(0, 0, c.width, c.height);
ctx.font="15px Georgia";
ctx.textAlign = "center";
ctx.fillText("Time Up",c.width/2, c.height/2);
ctx.textAlign="center";
}
}
<!DOCTYPE html>
<html>
<body>
<div>
Max Second: <input type="text" id="maxsec" value="300"><br/>
Current Second: <input type="text" id="currsec" value="150">
<button onclick="clickevent()">Click me</button>
<br/>
//This is the canvas section where the Arc or the curvature will be displayed.
<canvas id="myCanvas" width="150" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
</div>
</body>
</html>
You are passing the values as a string into the function instead of number, if you change the below lines of code, it works fine!
JS:
var max=parseInt(document.getElementById("maxsec").value);
var curr=parseInt(document.getElementById("currsec").value);
myFunction(max,curr);
JSFiddle Demo
Please use this attempt of making your timer using setTimeout() function as a reference and build your code!
JSFiddle Demo

How to change focus to new HTML5 Canvas element?

I have a bunch of canvas elements in my html file like so:
<canvas id="one"></canvas>
<canvas id="two"></canvas>
I'm using the arrow keys to move an object around #one, but I want to have that object "appear" in #two when it hits a point on #one, e.g. x=150 and y=55.
I tried using the jQuery focus() method when that coordinate was triggered, but the object stayed in #one. Any suggestions?
To make a canvas element focus-able, and therefor able to capture key-strokes, you simply add a tabIndex attribute to the element:
Now you can TAB between the elements and bind event-listeners to the canvas element directly.
Inside the handler you simply draw to the canvas you want based on whatever criteria you require.
Example
var canvases = document.querySelectorAll("canvas"),
i = 0;
while(canvas = canvases[i++]) {
canvas.width = 200;
canvas.tabIndex = 0;
canvas.addEventListener("keyup", process);
}
function process(e) {
var ctx = this.getContext("2d");
ctx.clearRect(0, 0, 200, 150);
ctx.fillText("KEY HERE: " + e.keyCode, 10, 10);
}
canvas {border:1px solid #999;margin:0 2px 2px 0; display:inline-block}
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
Rather than changing focus when that coordinate is hit, I think you need to change the <canvas> element (and associated context) you're drawing to, e.g.:
var theCanvas = document.getElementById("one");
var context = theCanvas.getContext("2d");
... your canvas drawing code here ...
if (posX < 150 && posY < 55) {
//clear the top canvas
context.clearRect(0, 0, theCanvas.width, theCanvas.height);
// switch to the second canvas
theCanvas = document.getElementById("two");
context = theCanvas.getContext("2d");
}
Here's a fiddle that borrows code from rectangleworld.com. Drag the circle into the upper left corner of the top canvas, and it should appear in the lower canvas.
JSFiddle
There is no such thing as focus on a canvas for this purpose.
Your both canvases need to listen for keypresses, while your code needs to decide what to draw on which canvas.
var canvas1 = document.getElementById("one");
var context1 = canvas1.getContext("2d");
var canvas2 = document.getElementById("two");
var context2 = canvas2.getContext("2d");
canvas1.width = canvas1.height = canvas2.width = canvas2.height = 50;
var obj = {x: 5, y: 5, w: 5};
function draw() {
canvas1.width = canvas2.width = canvas2.width;
context1.beginPath();
context1.rect(obj.x, obj.y, obj.w, obj.w);
context1.fillStyle = 'green';
context1.fill();
context2.beginPath();
context2.rect(obj.x - canvas1.width, obj.y, obj.w, obj.w);
context2.fillStyle = 'blue';
context2.fill();
}
window.addEventListener('keydown', function() {
if(++obj.x > canvas1.width + canvas2.width) obj.x = 5;
draw();
});
draw();
canvas {border: 1px solid black; margin: 10px;}
<canvas id="one"></canvas>
<canvas id="two"></canvas>
<p>Click inside this window to get focus and then <br>press any key to move the object to the right</p>
Of course, this can be optimized not to redraw both canvases on each tick, but you get the idea.

What does beginPath() and closePath() do exactly?

The question that I have is with context.beginPath() and context.closePath(). The code below will draw a circle in an arc around the screen until it disappears followed by a small dot which I would comment out because it is a .jpg which I do not know how to include.
My question is exactly what does the beginPath() do and also the closePath() do?
If I comment them out I get a wild result other than what I am expecting. I have looked on the internet but I have not seen the results like this.
Code with a question:
function drawTheBall() {
context.fillStyle = "#00AB0F"; //sets the color of the ball
context.beginPath();
context.arc(ball.x,ball.y,10,0,Math.PI*2,true); //draws the ball
context.closePath();
context.fill();
}
Working code below
HTML-Javascript
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH5EX10: Moving In Simple Geometric Spiral </title>
<script src="modernizr.js"></script>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {
canvasApp();
}
function canvasSupport () {
return Modernizr.canvas;
}
function canvasApp() {
var radiusInc = 2;
var circle = {centerX:250, centerY:250, radius:2, angle:0, radiusInc:2}
var ball = {x:0, y:0,speed:.1};
var points = new Array();
theCanvas = document.getElementById('canvasOne');
context = theCanvas.getContext('2d');
var pointImage = new Image();
pointImage.src = "point.png"; <-- Comment this line out
if (!canvasSupport()) {
return;
}
function erraseCanvas() {
context.clearRect(0,0,theCanvas.width,theCanvas.height);
}
function drawPathPoints() {
//Draw points to illustrate path
points.push({x:ball.x,y:ball.y});
for (var i= 0; i< points.length; i++) {
context.drawImage(pointImage, points[i].x, points[i].y,1,1);
}
}
function drawTheBall() {
context.fillStyle = "#00AB0F"; //sets the color of the ball
context.beginPath();
context.arc(ball.x,ball.y,10,0,Math.PI*2,true); //draws the ball
context.closePath();
context.fill();
}
function buildBall() {
ball.x = circle.centerX + Math.cos(circle.angle) * circle.radius;
ball.y = circle.centerY + Math.sin(circle.angle) * circle.radius;
circle.angle += ball.speed;
circle.radius += radiusInc;
}
function drawScreen () {
erraseCanvas();
buildBall();
drawPathPoints();
drawTheBall();
}
function gameLoop() {
window.setTimeout(gameLoop, 20);
drawScreen()
}
gameLoop();
}
</script>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvasOne" width="500" height="500">
Your browser does not support the HTML 5 Canvas.
</canvas>
</div>
</body>
</html>
beginPath()
beginPath() clears the current internal path object and its sub-paths, which accumulates path operations such as line, rect, arc, arcTo and so on, regardless of if they are filled or stroked.
closePath()
closePath() connects the current path, or sub-path, position with the first point on that path created either with beginPath() or moveTo() if that was used. The latter creates a sub-path on the current main path and only this sub-path gets closed.
Some methods do a closePath() implicit and temporary for you such as fill() and clip() which means it's not needed for those calls. In any case, it must be called before a stroke() (or fill(), if you chose to use that) is called.
One can perhaps understand this method better if one think of it as "closing the loop" rather than ending or closing the path [object] which it doesn't.
BeginPath will start a new path, unlike moveTo which will begin a new subpath
Close path will close the path. it probably isn't needed unless you want stroking to stroke the entire path without a gap
Close Path:
//An Open Box
ctx.moveTo(0 , 0);
ctx.lineTo(0 , 100);
ctx.lineTo(100, 100);
ctx.lineTo(100, 0);
ctx.stroke();
ctx.translate(150, 0);
//A closed box
ctx.moveTo(0 , 0);
ctx.lineTo(0 , 100);
ctx.lineTo(100, 100);
ctx.lineTo(100, 0);
ctx.closePath();
ctx.stroke();

drawing over an Image in HTML5 Canvas while preserving the image

In HTML5 Canvas, what's the simplest way to draw and move a line over an Image (already on the canvas), preserving the image underneath? (e.g. have a vertical line track the mouse X position)
My current canvas:
$(document).ready(function() {
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0,0);
}
imageObj.src = "http://example.com/some_image.png";
$('#myCanvas').click(doSomething);
});
You will have to do most of the ground-work with canvas which in this case you will have to implement the functionality to move the line and then redraw everything.
The steps can be:
Keep the line as an object which can self-render (method on the object)
Listen to mousemove (in this case) in order to move the line
For each move, redraw background (image) then render the line at its new position
You can redraw the background as a whole or you can optimize it to just draw over the last line.
Here is some example code of this and a live demo here:
var canvas = document.getElementById('demo'), /// canvas element
ctx = canvas.getContext('2d'), /// context
line = new Line(ctx), /// our custom line object
img = new Image; /// the image for bg
ctx.strokeStyle = '#fff'; /// white line for demo
/// start image loading, when done draw and setup
img.onload = start;
img.src = 'http://i.imgur.com/O712qpO.jpg';
function start() {
/// initial draw of image
ctx.drawImage(img, 0, 0, demo.width, demo.height);
/// listen to mouse move (or use jQuery on('mousemove') instead)
canvas.onmousemove = updateLine;
}
Now all we need to do is to have a mechnism to update the background and the line for each move:
/// updates the line on each mouse move
function updateLine(e) {
/// correct mouse position so it's relative to canvas
var r = canvas.getBoundingClientRect(),
x = e.clientX - r.left,
y = e.clientY - r.top;
/// draw background image to clear previous line
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
/// update line object and draw it
line.x1 = x;
line.y1 = 0;
line.x2 = x;
line.y2 = canvas.height;
line.draw();
}
The custom line object is in this demo very simple:
/// This lets us define a custom line object which self-draws
function Line(ctx) {
var me = this;
this.x1 = 0;
this.x2 = 0;
this.y1 = 0;
this.y2 = 0;
/// call this method to update line
this.draw = function() {
ctx.beginPath();
ctx.moveTo(me.x1, me.y1);
ctx.lineTo(me.x2, me.y2);
ctx.stroke();
}
}
If you are not gonna do anything specific with the image itself you can also set it as a background-image using CSS. You will still need to clear the canvas before redrawing the line though.
May this is not an actual answer, just in case you need it (in the future). Working with canvas would be better (and easier) with some library. I have tried EaselJS of CreateJS and find myself loving it.
You can have a look at it EaselJS
(I have done an example allow drawing and dragging image using EaselJS long time before)
You can get your "crosshairs" by listening to mousemove events and then:
clear the canvas
draw the image
draw your line at the mouse position
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/jEc7N/
<!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; padding:20px; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.lineWidth=2;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var img=new Image();
img.onload=function(){
canvas.width=img.width;
canvas.height=img.height;
ctx.drawImage(img,0,0);
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/KoolAidMan.png";
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(img,0,0);
ctx.beginPath();
ctx.moveTo(mouseX,0);
ctx.lineTo(mouseX,canvas.height);
ctx.moveTo(0,mouseY);
ctx.lineTo(canvas.width,mouseY);
ctx.stroke();
}
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
or just use 2 layers:
background layer has image and do not change,
top layer has line, what you can clear and redraw it lots of time without affecting background layer.

Categories