HTML5 - Clearing canvas with multiple animations - where is the main draw loop? - html

I have a mixture of static, interactive, and animated objects in my canvas. I can't seem to find a way to clear the draw loop in a global way such that there is no 'smearing' in any of the objects. My code is below. Any help greatly appreciated.
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var mouseX = 300;
var mouseY = 300;
var inc = 0;
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
ctx.clearRect(0, 0, canvas.width, canvas.height);
moveThing();
drawBezier();
drawCircle();
drawInteractive();
var putPoint = function (e) {
// update mouse
mouseX = e.clientX;
mouseY = e.clientY;
// clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBezier();
drawCircle();
drawInteractive();
}
canvas.addEventListener("mousemove", putPoint);
function drawBezier() {
for (var i = 0; i < 100; i++) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.bezierCurveTo(200, mouseX, 900, -300, i * 20, 600 + Math.random() * 30);
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
ctx.stroke();
ctx.closePath();
}
}
function drawCircle() {
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
}
function drawInteractive() {
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(mouseX, mouseY - 40, 100, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
function moveThing() {
inc++;
// ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.arc(95, 50 + inc, 40, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
requestAnimationFrame(moveThing);
}
</script>

I have refactored your code a little creating a function update which is the main loop of the canvas.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var mouseX = 300;
var mouseY = 300;
var inc = 0;
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
update();
var putPoint = function (e) {
// update mouse
mouseX = e.clientX;
mouseY = e.clientY;
// clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBezier();
drawCircle();
drawInteractive();
}
canvas.addEventListener("mousemove", putPoint);
function drawBezier() {
for (var i = 0; i < 100; i++) {
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.bezierCurveTo(200, mouseX, 900, -300, i * 20, 600 + Math.random() * 30);
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
ctx.stroke();
ctx.closePath();
}
}
function drawCircle() {
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
}
function drawInteractive() {
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(mouseX, mouseY - 40, 100, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
moveThing();
drawBezier();
drawCircle();
drawInteractive();
requestAnimationFrame(update);
}
function moveThing() {
inc++;
ctx.beginPath();
ctx.fillStyle = "blue";
ctx.arc(95, 50 + inc, 40, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
}
<canvas id="myCanvas" />

Related

HTML5 get base64 code of image created in canvas

var ctx;
function roundedImage() {
var img = new Image();
img.onload = function() {
ctx.beginPath();
ctx.arc(160, 150, 75, 0, Math.PI * 2, true); //draw the circle
ctx.lineWidth = 5;
ctx.strokeStyle = 'white';
ctx.stroke();
ctx.clip();
ctx.closePath();
ctx.drawImage(img, 80, 70, 160, 160);
};
img.src = "xxxxx";
img.crossOrigin = "Anonymous";
}
function fillText(name) {
ctx.fillStyle = 'white';
ctx.font = '40pt Calibri';
ctx.fillText(name, 100, 100);
}
function backImg() {
var background = new Image();
background.src = "xxxxx";
background.onload = function(){
ctx.drawImage(background, 3, 3, canvas.width - 7, canvas.height - 7);
roundedImage()
}
}
function createCanvas(width, height) {
var canvas = document.createElement("canvas");
canvas.id = "canvas";
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
}
function admire() {
createCanvas(400,625)
backImg()
var original64 = canvas.toDataURL
console.log(original64);
}
window.onload = admire();
Everything is working fine but I am unable to get the base64 code. I am getting this in console "ƒ toDataURL() { [native code] }" How can I get base64 of canvas created.
And I want to show that base64 image in another canvas. How can I do that?

Move image smoothly on an HTML5 canvas

I am moving an inserted image within a Canvas.
HTML
<div id="left">move left</div>
jQuery:
let MoveLeft=0;
$("#left").on("click", function(){
MoveLeft+=10;
});
In the canvas function
function(){
.....
var LeftPos=100; //default
If(MoveLeft!=0)
LeftPos=LeftPos + MoveLeft;
}
ctx.drawImage(img,0,0,imgW,imgH,LeftPos,0,imgW,imgH);
This works, but the movement takes place in a single jump. How do I translate the image smoothly? Like an animation?
let GlassesUp = 0;
$('.MoveGlasses').on("click", function(event) {
if ($(this).hasClass("MoveGlassesUp")) {
GlassesUp += 10;
}
drawMe();
});
var canvas = document.getElementById('cv');
ctx = canvas.getContext('2d');
// core drawing function
var drawMe = function() {
var ImgGlasses = document.getElementById('glasses');
canvas.width = 400;
canvas.height = 400;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, canvas.width, canvas.height);
var GUp = 50;
if (GlassesUp != 0) {
GUp = GUp - GlassesUp;
//alert(GUp)
}
ctx.drawImage(ImgGlasses, 0, 0, 250, 250, 50, GUp, 250, 250);
}
drawMe();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="MoveGlasses MoveGlassesUp">Up</div>
<canvas id="cv"></canvas>
<img src="https://image.flaticon.com/icons/svg/126/126514.svg" style="height:60px;width:100px;opacity:0" id="glasses" />
The draw function displaces the image by 0.7 per 100ms. You can adjust these two parameters.
let GlassesUp = 0;
var t;
$('.MoveGlassesUp').on("click", function(event) {
clearInterval(t)
t = setInterval(function() {
GlassesUp += 0.7;
drawMe();
}, 100);
setTimeout("clearInterval(t)", 1000)
});
$('.MoveGlassesDown').on("click", function(event) {
clearInterval(t)
t = setInterval(function() {
GlassesUp -= 0.7;
drawMe();
}, 100);
setTimeout("clearInterval(t)", 1000)
});
var canvas = document.getElementById('cv');
ctx = canvas.getContext('2d');
// core drawing function
var drawMe = function() {
var ImgGlasses = document.getElementById('glasses');
canvas.width = 400;
canvas.height = 400;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, canvas.width, canvas.height);
var GUp = 50;
if (GlassesUp != 0) {
GUp = GUp - GlassesUp;
//alert(GUp)
}
ctx.drawImage(ImgGlasses, 0, 0, 250, 250, 50, GUp, 250, 250);
}
drawMe();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<button class="MoveGlasses MoveGlassesUp">up</button>
<button class="MoveGlasses MoveGlassesDown">down</button>
<hr/>
<canvas id="cv"></canvas>
<img src="https://image.flaticon.com/icons/svg/126/126514.svg" style="height:60px;width:100px;opacity:0" id="glasses" />

how to free draw a straight line in html 5 canvas and get the coordinates of the line?

How to draw a line in html 5 canvas?
I achived to draw an rectangle but how to draw a straight line. Here is my code.
function redraw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (!path.length)
return;
ctx.beginPath();
ctx.moveTo.apply(ctx, path[0]);
for (var i = 1,
len = path.length; i < len; ++i)
ctx.lineTo.apply(ctx, path[i]);
ctx.strokeStyle = '#000';
ctx.stroke();
var start = new Date;
var bounds = contextBoundingBox(ctx);
ms.value = ms.value * 1 + Math.round(((new Date) - start - ms.value) / 4);
ctx.strokeStyle = '#c00';
ctx.strokeRect(bounds.x, bounds.y, bounds.w, bounds.h);
}
This above code is for drawing the rectangle, please modify the code to draw a straight line.
DEMO
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
//add event listner to canvas
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mousemove', mouseMove, false);
canvas.addEventListener('mouseup', mouseUp, false);
var mouseDown = false;
var points = [];
var lines = [];
var linePoint = [];
var stPoint;
var endPoint;
var imageObj = new Image();
imageObj.onload = function() {
ctx.drawImage(imageObj, 0, 0, canvas.width, canvas.height);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
function Point(x, y) {
this.x = x;
this.y = y;
}
function lineP(stPoint, endPoint) {
this.stPoint = stPoint;
this.endPoint = endPoint;
}
function mouseDown(e) {
mouseDown = true;
stPoint = new Point(e.layerX, e.layerY); //get start point for line
}
function mouseMove(e) {
if (!mouseDown) return;
ctx.clearRect(0, 0, canvas.width, canvas.height); //clear canvas
ctx.drawImage(imageObj, 0, 0, canvas.width, canvas.height); //redraw image
drawLines(); //draw previous lines
ctx.beginPath();
ctx.moveTo(stPoint.x, stPoint.y);
ctx.lineTo(e.layerX, e.layerY);
ctx.stroke();
ctx.closePath();
}
function mouseUp(e) {
mouseDown = false;
endPoint = new Point(e.layerX, e.layerY); //get end point
linePoint.push(new lineP(stPoint, endPoint)); //store line points for next draw
console.log(linePoint);
}
//draw all lines from stored point
function drawLines() {
linePoint.forEach(function(item) {
ctx.beginPath();
ctx.moveTo(item['stPoint'].x, item['stPoint'].y);
ctx.lineTo(item['endPoint'].x, item['endPoint'].y);
ctx.stroke();
ctx.closePath();
})
}
canvas {
border: 1px solid #999;
}
<canvas id="canvas" width="300" height="300"></canvas>
On mouse down store start value of line and on mouse up store end point of line. (event.layerX,event.layerY) will give the point cordinate.

Can not draw a circle on top of rectangle in html5

I am using html5 and I want to draw a circle on top of a rectangle so I used the following html code:
<canvas id="myCanvas" style="z-index: 1;width:70%;height: 70%;float: left;">
<canvas id="c1" style="z-index: 2;width:10%;height: 10%;float: left;"></canvas>
and following js code:
$(document).ready(function() {
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.rect(10,10,$("#myCanvas").height(),$("#myCanvas").width());
ctx.fillStyle = 'yellow';
ctx.fill();
ctx.stroke();
var canvas = document.getElementById('c1');
var context = canvas.getContext('2d');
var centerX = $("#myCanvas").height()/ 2;
var centerY = $("#myCanvas").width() / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
});
and here is the jfiddle link:
jfiddle
Now the problem is that the circle is not shown and I do not know what is the problem!!!
Can anyone help me?
Are you sure you need two canvases? I would do it on one.
$(document).ready(function() {
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.rect(10,10,$("#myCanvas").height(),$("#myCanvas").width());
ctx.fillStyle = 'yellow';
ctx.fill();
ctx.stroke();
var centerX = $("#myCanvas").height()/ 2;
var centerY = $("#myCanvas").width() / 2;
var radius = 70;
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = 'green';
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = '#003300';
ctx.stroke();
});
http://jsfiddle.net/7FuL9/2/
Why do you need two canvas tags to do this? This can be done with just one canvas. Here is a JSBin that draws a circle on top of a rectangle.

Draw a pin on Canvas using HTML5

I need to draw a pin like: http://www.clipartbest.com/clipart-9czEGGdRi using HTML5 on a Canvas.
Here's what I have: http://jsfiddle.net/u5jNR/
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var x = canvas.width / 2;
var y = canvas.height / 2;
var radius = 75;
var startAngle = .9 * Math.PI;
var endAngle = 2.1 * Math.PI;
var counterClockwise = false;
context.beginPath();
context.arc(x, y, radius, startAngle, endAngle, counterClockwise);
context.lineWidth = 15;
// line color
context.strokeStyle = 'black';
context.stroke();
var radius = 20;
context.beginPath();
context.arc(x, y, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.stroke();
the problem I am having is I don't know how to extend the two ends.
Thanks in advance
Here's an example of using path commands to draw a pin.
Assume you have an object defining the pin's x,y & color:
var pin = { x:x, y:y, color:color };
Then you can draw that pin like this:
function drawPin(pin){
ctx.save();
ctx.translate(pin.x,pin.y);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.bezierCurveTo(2,-10,-20,-25,0,-30);
ctx.bezierCurveTo(20,-25,-2,-10,0,0);
ctx.fillStyle=pin.color;
ctx.fill();
ctx.strokeStyle="black";
ctx.lineWidth=1.5;
ctx.stroke();
ctx.beginPath();
ctx.arc(0,-21,3,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle="black";
ctx.fill();
ctx.restore();
}