Animate line graph on canvas - javascript

i,m new in js, i ve got task, where i have to animate line graph, but i can't understand how to make it re-render onClick with animation, pls, help me
there's code that's ,make random graph with random points, i need to make smooth animation on click's with new point's
const canvas = document.getElementById('graph')
const ctx = canvas.getContext('2d')
function drawCords() {
ctx.fillStyle = "black";
ctx.lineWidth = 2.0;
ctx.beginPath();
ctx.moveTo(30, 10);
ctx.lineTo(30, 480);
ctx.lineTo(680, 480);
ctx.stroke();
}
function randomIntFromInterval(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
const rndInt = randomIntFromInterval(2, 10)
const counterForX = (650/rndInt).toFixed()
var rndIntForX = 0
const oneLineX = [];
const oneLineY = [];
canvas.addEventListener('click',()=>start())
function start() {
drawFrame()
}
function drawPoint() {
for (let i = 0; i < rndInt; i++) {
rndIntForX += +counterForX
const rndIntForY = randomIntFromInterval(10, 480)
oneLineX.push(rndIntForX)
oneLineY.push(rndIntForY)
ctx.beginPath();
ctx.arc(rndIntForX, rndIntForY, 4, 0, 2*Math.PI, false);
ctx.fillStyle = 'white';
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = 'black';
ctx.stroke();
}
}
function drawLine(){
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = '1';
ctx.moveTo(oneLineX[0],oneLineY[0]);
for (let i=1; i<10; i++){
ctx.lineTo(oneLineX[i],oneLineY[i]);
ctx.lineCap = "round";
}
ctx.stroke();
ctx.closePath();
}
function drawFrame() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawCords()
drawPoint()
drawLine()
setTimeout("drawFrame()", 20);
}
drawCords()
i, ve tried many things, but the didn't worked

Related

How do i update canvas using js continuously?

I've got this piece of code that draws a ball and i want to continuously pass in different cooridinates in order to make it move around but when the refresh rate gets way too high, canvas stops updating. How do i force canvas to update and redraw everything with the arguments passed in?
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
function determinePosition(x, y) {
var trueX = x + 120;
var trueY = y + 80;
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
}
while(true){
determinePosition(x, y);
}
<div class="gcircle">
<canvas id="circle" width="240px" height="160"></canvas>
</div>
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
function determinePosition(x, y) {
//clear the canvas
ctx.clearRect(0, 0, c.width, c.height);
var trueX = x + 120;
var trueY = y + 80;
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
}
//set random location for each 0.5 sec
setInterval(function() {
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
determinePosition(x, y);
}, 500)
<div class="gcircle">
<canvas id="circle" width="240px" height="160"></canvas>
</div>
`
Drawing should always happen in a requestAnimationFrame loop. requestAnimationFrame runs at your monitor's refresh rate, so it's the fastest any animation can run. You can set it up like this:
var c = document.getElementById("circle");
var ctx = c.getContext("2d");
var x = Math.floor(Math.random() * 50);
var y = Math.floor(Math.random() * 50);
var trueX = 0;
var trueY = 0;
function determinePosition(x, y) {
trueX = x + 120;
trueY = y + 80;
}
requestAnimationFrame(function draw() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.beginPath();
ctx.arc(trueX, trueY, 10, 0, 2 * Math.PI);
ctx.fillStyle = "black";
ctx.fill();
ctx.strokeStyle = "black";
ctx.stroke();
requestAnimationFrame(draw);
})
determinePosition(x, y);

How to draw this out using a timer in javascript?

I am trying to get this snowflake design to be "drawn out" using a "timer" on javascript. In one of the examples, this is how a circle is drawn:
http://jsfiddle.net/avanhout13/9opengv7/1/
var t = 0;
var c = document.getElementById("myCanvas");
var R = c.width/2;
var ctx = c.getContext("2d");
function doDrawing() {
t = 0;
// Clear the Canvas
ctx.clear();
// Create a random color
var timesRun = 0;
var color = '#'+Math.floor(Math.random()*16777215).toString(16);
// Initial x and y
var x = R+R*Math.cos(0);
var y = R+R*Math.sin(0);
// Start the Drawing
ctx.beginPath();
ctx.strokeStyle = color;
ctx.moveTo(x,y);
//Use the timer to create drawing
var interval = setInterval(function(){
timesRun += 1;
if(timesRun === 65){
clearInterval(interval); }
drawCircle();}, 20);
}
function drawCircle()
{
t += 0.1;
x = Math.floor(R+R*Math.cos(t));
y = Math.floor(R+R*Math.sin(t));
ctx.lineTo(x,y);
ctx.stroke();
}
CanvasRenderingContext2D.prototype.clear =
CanvasRenderingContext2D.prototype.clear || function (preserveTransform) {
if (preserveTransform) {
this.save();
this.setTransform(1, 0, 0, 1, 0, 0);
}
this.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (preserveTransform) {
this.restore();
}
};
This is the snowflake design. I want to do a similar drawing technique but cannot seem to figure out how to get it to actively be drawn when the "draw" button is clicked.
https://jsfiddle.net/avanhout13/g8xs9Ljf/
let canvas = document.getElementById('snowflake'),
ctx = canvas.getContext('2d'),
maxLevel = 2,
branches = 7;
canvas.width = 1000;
canvas.height = 1000;
ctx.translate(canvas.width / 2, canvas.height / 2);
let angle = Math.PI * 2 + Math.random();
for (let i = 0; i < 6; i++) {
drawLine(0);
ctx.rotate(Math.PI * 2 / 6);
}
function drawLine(level) {
if (level > maxLevel) return;
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(200, 0);
ctx.stroke();
for (let i = 1; i < branches + 1; i++) {
ctx.save();
ctx.translate(200 * i / (branches + 1), 0);
ctx.save();
ctx.rotate(angle);
drawLine(level + 1);
ctx.restore();
ctx.save();
ctx.rotate(-angle);
drawLine(level + 1);
ctx.restore();
ctx.restore();
}
}
Any idea of how to get this to draw? Thank you.
Make sure that your js code isn't loaded in file type, otherwise you can not use the function by input it's name in the html tag directly.
In JSFiddle, it could be change by the select label on the top left corner of your js window.
Hope this could be help.
<html lane='en'>
<head>
<meta charset='utf-8'>
<title> Snowflake Spirograph</title>
</head>
<body>
<button onclick="draw()">Start Drawing</button>
<canvas id="snowflake" width="1000" height="1000"></canvas>
</body>
</html>
const canvas = document.getElementById('snowflake');
const ctx = canvas.getContext('2d');
const maxLevel = 2;
const branches = 7;
ctx.translate(canvas.width / 2, canvas.height / 2);
let angle = Math.PI * 2 + Math.random();
function draw() {
for (let i = 0; i < 6; i++) {
drawLine(1);
ctx.rotate(Math.PI * 2 / 6);
}
}
function drawLine(level) {
if (level > maxLevel) return;
ctx.strokeStyle = "black";
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(200, 0);
ctx.stroke();
for (let i = 1; i < branches + 1; i++) {
ctx.save();
ctx.translate(200 * i / (branches + 1), 0);
ctx.save();
ctx.rotate(angle);
drawLine(level + 1);
ctx.restore();
ctx.save();
ctx.rotate(-angle);
drawLine(level + 1);
ctx.restore();
ctx.restore();
}
}

How to clear a circle drawn with arc in javascript?

I am having problems when drawing a circle. How do I clear it?
I also still want to maintain the transparent background as much as possible as I am planning on making particles rain down. I also would want to not use images to lower the load on the server.
var canvas = document.getElementById("canvas");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext("2d");
const ParticleFactory = function(){
this.interval = 100;
this.lastOutput = Date.now();
this.particles = [];
}
ParticleFactory.prototype.tick = function(){
if (Date.now() > this.lastOutput + this.interval) {
const particle = new Particle(500, 100, 4);
this.particles.push(particle);
this.lastOutput = Date.now();
}
for (var i=0; i < this.particles.length; i++) {
this.particles[i].tick();
};
}
ParticleFactory.prototype.draw = function(){
for (var i=0; i < this.particles.length; i++) {
this.particles[i].draw();
};
}
ParticleFactory.prototype.del = function(toDelete){
this.particles = this.particles.filter(item => item !== toDelete);
}
const Particle = function(x, y, r){
this.x = x;
this.y = y;
this.r = r;
}
Particle.prototype.tick = function(){
this.x -= 0.1;
}
Particle.prototype.draw = function(){
ctx.beginPath();
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI, false);
ctx.fillStyle = "rgb(0, 0, 255)";
ctx.fill();
ctx.closePath();
}
// Definitions
let particleFactory = new ParticleFactory;
function draw(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
particleFactory.draw();
}
function tick(){
particleFactory.tick();
draw()
window.requestAnimationFrame(tick)
}
document.addEventListener("DOMContentLoaded", function() {
tick();
});
ctx.clearRect() doesn't clear the curcle that is being draws every tick by Particle.draw()
The dot moves and leaves a trail behind even when ctx.clearRect() is run before every draw.

Isometric 3d collision detection

I'm making an isometric map for a game, I can draw it, but I don't know how to implement a sort of 3d collision detection without Threejs or other 3d library.
It is possible? Maybe make the block an Object can help? I have searched, but I found only libraries.
This is my JavaScript code:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight,
stop = false;
var tw, th;
var player;
setup();
draw();
function setup(){
ctx.translate(width/2,50);
tw = 60; //tile width
th = 30; // tile height
player = new Player(2,3,3);
};
function draw(){
ctx.clearRect(-width/2,-50,width*1.5,height+50);
for(var i = 0; i < 5; i++){
for(var j = 0; j < 5; j++){
drawBlock(i,j,1,tw,th);
}
}
if(!stop){
requestAnimationFrame(draw);
}
}
function drawBlock(x,y,z,w,h){
var top = "#eeeeee",
right = '#cccccc',
left = '#999999';
ctx.save();
ctx.translate((x-y)*w/2,(x+y)*h/2);
ctx.beginPath();
ctx.moveTo(0,-z*h);
ctx.lineTo(w/2,h/2-z*h);
ctx.lineTo(0,h-z*h);
ctx.lineTo(-w/2,h/2-z*h);
ctx.closePath();
ctx.fillStyle = "black";
ctx.stroke();
ctx.fillStyle = top;
ctx.fill();
ctx.beginPath();
ctx.moveTo(-w/2,h/2-z*h);
ctx.lineTo(0,h-z*h);
ctx.lineTo(0,h);
ctx.lineTo(0,h);
ctx.lineTo(-w/2,h/2);
ctx.closePath();
ctx.fillStyle = "black";
ctx.stroke();
ctx.fillStyle = left;
ctx.fill();
ctx.beginPath();
ctx.moveTo(w/2,h/2-z*h);
ctx.lineTo(0,h-z*h);
ctx.lineTo(0,h);
ctx.lineTo(0,h);
ctx.lineTo(w/2,h/2);
ctx.closePath();
ctx.fillStyle = "black";
ctx.stroke();
ctx.fillStyle = right;
ctx.fill();
ctx.restore();
}
function drawTile(x,y,stroke,col){
ctx.save();
ctx.translate((x-y)*tw/2,(x+y)*th/2);
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(tw/2,th/2);
ctx.lineTo(0,th);
ctx.lineTo(-tw/2,th/2);
ctx.closePath();
if(stroke){
ctx.stroke();
}else{
ctx.fillStyle = col;
ctx.fill();
}
ctx.restore();
}
function Player(x,y,z){
this.x = x;
this.y = y;
this.z = z;
this.w = 10; //width
this.h = 10; //height
}
canvas{
width:100%;
height:100%;
}
<canvas id="canvas"></canvas>
What you're after is cube collision. The first result I get for googling that is an article on MDN named 3D collision detection:
Mathematically this would look like so:
f(A,B) = (AminX <= BmaxX ∧ AmaxX >= BminX) ∧ (AminY <= BmaxY ∧ AmaxY >= BminY) ∧ (AminZ <= BmaxZ ∧ AmaxZ >= BminZ)
And in JavaScript, we'd use this:
function intersect(a, b) {
return (a.minX <= b.maxX && a.maxX >= b.minX) &&
(a.minY <= b.maxY && a.maxY >= b.minY) &&
(a.minZ <= b.maxZ && a.maxZ >= b.minZ);
}

Radial chart using js and html5 canvas element

I'm trying to make circular chart on html5 canvas el.
(function () {
var ctx = document.getElementById('canvas').getContext('2d');
var counter = 0;
var start = 4.72;
var cW = ctx.canvas.width;
var cH = ctx.canvas.height;
var diff;
var maxVal = 44;
function progressChart(){
diff = ((counter / 100) * Math.PI*2*10).toFixed(2);
ctx.clearRect(0, 0, cW, cH);
ctx.lineWidth = 15;
ctx.fillStyle = '#ff883c';
ctx.strokeStyle = '#ff883c';
ctx.textAlign = 'center';
ctx.font = '25px Arial';
ctx.fillText(counter+'%', cW*.5, cH*.55, cW);
ctx.beginPath();
ctx.arc(70, 70, 60, start, diff/10+start, false);
ctx.stroke();
if(counter >= maxVal){
clearTimeout(drawChart);
}
counter++;
}
var drawChart = setInterval(progressChart, 20);
})();
<canvas id="canvas" width="140" height="140"></canvas>
I want to add doughnut background before browser start drawing fill chart. Unfortunately, I need to use ctx.clearRect() because I've got strange visual effect. Is any way to combine this two rings?
Yes, there is a way and that is, drawing another arc for doughnut background, before drawing fill chart.
Also, you should use requestAnimationFrame() instead of setInterval(), for better efficiency.
var ctx = document.getElementById('canvas').getContext('2d');
var counter = 0;
var start = 4.72;
var cW = ctx.canvas.width;
var cH = ctx.canvas.height;
var diff;
var maxVal = 44;
var rAF;
function progressChart() {
diff = ((counter / 100) * Math.PI * 2 * 10).toFixed(2);
ctx.clearRect(0, 0, cW, cH);
ctx.lineWidth = 15;
ctx.fillStyle = '#ff883c';
ctx.textAlign = 'center';
ctx.font = '25px Arial';
ctx.fillText(counter + '%', cW * .5, cH * .55, cW);
// doughnut background
ctx.beginPath();
ctx.arc(70, 70, 60, 0, Math.PI * 2, false);
ctx.strokeStyle = '#ddd';
ctx.stroke();
// fill chart
ctx.beginPath();
ctx.arc(70, 70, 60, start, diff / 10 + start, false);
ctx.strokeStyle = '#ff883c';
ctx.stroke();
if (counter >= maxVal) {
cancelAnimationFrame(rAF);
return;
}
counter++;
rAF = requestAnimationFrame(progressChart);
}
progressChart();
<canvas id="canvas" width="140" height="140"></canvas>

Categories