How to make a circular progress countdown timer? - javascript

Can you help me make this code into a countdown setup...that code counts from 0-10. I want to make it from 10-0.. I'm not really good in jquery. help please..
<canvas height="200" width="200" id="counter"/>
</body>
<script type="application/javascript">
var counter = document.getElementById('counter').getContext('2d');
var no = 0;
var pointToFill = 4.72;
var cw = counter.canvas.width;
var ch = counter.canvas.height;
var diff;
function fillCounter(){
diff = ((no/10) * Math.PI*2*10);
counter.clearRect(0,0,cw,ch);
counter.lineWidth = 15;
counter.fillStyle = '#fff';
counter.strokeStyle = '#F5E0A9';
counter.textAlign = 'center';
counter.font = "25px monospace";
counter.fillText(no+'sec',100,110);
counter.beginPath();
counter.arc(100,100,90,pointToFill,diff/10+pointToFill);
counter.stroke();
if(no >= 10)
{
clearTimeout(fill);
}
no++;
}
var fill = setInterval(fillCounter,1000);
</script>

Here is the demo: https://codepen.io/creativedev/pen/ERwGej
var counter = document.getElementById('counter').getContext('2d');
var no = 10;
var pointToFill = 4.72;
var cw = counter.canvas.width;
var ch = counter.canvas.height;
var diff;
function fillCounter() {
diff = ((no / 10) * Math.PI * 2 * 10);
counter.clearRect(0, 0, cw, ch);
counter.lineWidth = 15;
counter.fillStyle = '#000';
counter.strokeStyle = '#F5E0A9';
counter.textAlign = 'center';
counter.font = "25px monospace";
console.log(no);
counter.fillText(no + 'sec', 100, 110);
counter.beginPath();
console.log(diff)
counter.arc(100, 100, 90, pointToFill, diff / 10 + pointToFill);
counter.stroke();
if (no == 0) {
clearTimeout(fill);
}
no--;
}
var fill = setInterval(fillCounter, 1000);

Related

JS windows.onload does not work

onload that create 2 graphs and display them. they both worked when they where onclick="draw1()" but when i change them to onload only the last graph works with the onload
My First Graph
<script>
window.onload = function draw1() {
var n = "114,19,20,21,22,23,24";
var values = n.split(',');
var canvas = document.getElementById('myCanvas1');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
for (var i =0; i<values.length; i++) {
skipint ++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X,canvas.height - pers,width,pers);
}
ctx.fillStyle = '#050505';
ctx.font="22px bold Arial";
ctx.fillText(' 0 %',0,canvas.height);
ctx.fillText(' 50 %',0,canvas.height /2 + 11);
ctx.fillText('100 %',0,canvas.height - canvas.height + 22);
}
</script>
My 1st canvas:
<canvas id="myCanvas1">
</canvas>
My Second graph
<script>
window.onload = function draw2() {
var n = "22,22,23,24";
var values = n.split(',');
//get the myCanvas2 byID
var canvas = document.getElementById('myCanvas2');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
//skips evry 3 bars
for (var i =0; i<values.length; i++) {
skipint ++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X,canvas.height - pers,width,pers);
}
ctx.fillStyle = '#050505';
ctx.font="22px bold Arial";
ctx.fillText(' 0 %',0,canvas.height);
ctx.fillText(' 50 %',0,canvas.height /2 + 11);
ctx.fillText('100 %',0,canvas.height - canvas.height + 22);
}
</script>
My second canvas
<canvas id="myCanvas2">
</canvas>
Question:
How do i get both my graphs to work with window.onload?
You can declare each function, and then create a single function to call them both. I think it's easier to debug if you declare the functions outside of the event handler and then call them with the onload handler.
<script>
function draw1() {
var n = "114,19,20,21,22,23,24";
var values = n.split(',');
var canvas = document.getElementById('myCanvas1');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
for (var i = 0; i < values.length; i++) {
skipint++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X, canvas.height - pers, width, pers);
}
ctx.fillStyle = '#050505';
ctx.font = "22px bold Arial";
ctx.fillText(' 0 %', 0, canvas.height);
ctx.fillText(' 50 %', 0, canvas.height / 2 + 11);
ctx.fillText('100 %', 0, canvas.height - canvas.height + 22);
}
</script>
<p>My first canvas</p>
<canvas id="myCanvas1">
</canvas>
<script>
function draw2() {
var n = "22,22,23,24";
var values = n.split(',');
//get the myCanvas2 byID
var canvas = document.getElementById('myCanvas2');
var ctx = canvas.getContext('2d');
var width = 26; //bar width
var X = 60 // 60; // first bar position
var base = canvas.height;
var skipint = 0;
//skips evry 3 bars
for (var i = 0; i < values.length; i++) {
skipint++;
var h = values[i];
var pers = h * (base / 100);
ctx.fillRect(X, canvas.height - pers, width, pers);
}
ctx.fillStyle = '#050505';
ctx.font = "22px bold Arial";
ctx.fillText(' 0 %', 0, canvas.height);
ctx.fillText(' 50 %', 0, canvas.height / 2 + 11);
ctx.fillText('100 %', 0, canvas.height - canvas.height + 22);
}
</script>
<p>My second canvas</p>
<canvas id="myCanvas2">
</canvas>
<script>
window.onload = function() {
draw1();
draw2();
}
</script>

Manually draw yaxis in time intervals using Teechart

I am using Teechart library to display y axes in the time intervals of 1 second. Chart1.axes.left.increment = 1; helps me to increment the yaxis in the interval of 1. What i need is to lay out dotted lines in between these Solid lines. I want to manually add the line series for dotted lines in time interval of 0.20 seconds. How can I use line series to add dotted lines here.
function draw_TeeChart() {
var w = window.innerWidth, h = window.innerHeight;
// Initialize Teechart[![enter image description here][1]][1]
Chart1 = new Tee.Chart("canvas");
document.getElementById("canvas").style.position = "relative";
document.getElementById("canvas").width= Math.round(0.82*w);document.getElementById("canvas").height= Math.round(0.89*h); //Chart1.bounds.x = Math.round(0.01*w);
Chart1.bounds.x = 14;Chart1.bounds.y= 10;
Chart1.bounds.width = Math.round(chartW*w);Chart1.bounds.height= Math.round(0.88*h);
Chart1.legend.visible = false; Chart1.panel.transparent = true;
Chart1.title.visible = false;Chart1.axes.bottom.title.text = " ";
Chart1.axes.left.increment = 1;
Chart1.axes.bottom.increment=1;
Chart1.axes.bottom.innerTicks.visible = true;
Chart1.axes.bottom.ticks.length = 9;
Chart1.axes.bottom.ticks.stroke.fill = "blue";
Chart1.axes.bottom.minorTicks.visible = true;
Chart1.axes.bottom.minorTicks.length = 4;
Chart1.axes.bottom.minorTicks.count = 4;
Chart1.axes.bottom.minorTicks.stroke.fill = "green";
// var dottedLines = Chart1.axes.bottom.increment=.2;
// var increment = 0.20;
// var dottedLines = Chart1.axes.bottom.grid.format.stroke.dash = [5,3];
// var solidLines = Chart1.axes.bottom.increment=1;
// for(increment =0.20;increment<100;increment =increment+0.20){
// if (increment % 1 == 0) {
// Chart1.axes.bottom.increment=1;
// }
// else {
// Chart1.axes.bottom.increment=0.20;
// Chart1.axes.bottom.grid.format.stroke.dash = [5,3];
// }
// }
Chart1.walls.back.format.fill = wallColorCode;
Chart1.walls.back.format.shadow.visible = false;
document.body.style.cursor = "pointer";
document.getElementById("EventCount").value = event_time.length.toFixed(0);
}
Image1:
Image2:
Here an example showing how you could extend the bottom axis adding a new innerGrid property and using it at drawLabel override.
var Chart1;
function draw() {
Chart1 = new Tee.Chart("canvas1");
var line1 = Chart1.addSeries(new Tee.Line());
line1.data.values = [10, 20, 30, 20, 50];
Chart1.legend.visible = false;
Chart1.axes.bottom.setMinMax(0, 5);
Chart1.axes.bottom.increment = 1;
Chart1.axes.bottom.innerTicks.visible = true;
Chart1.axes.bottom.ticks.length = 9;
Chart1.axes.bottom.ticks.stroke.fill = "blue";
Chart1.axes.bottom.minorTicks.visible = true;
Chart1.axes.bottom.minorTicks.length = 4;
Chart1.axes.bottom.minorTicks.count = 4;
Chart1.axes.bottom.minorTicks.stroke.fill = "green";
Chart1.axes.bottom.innerGrid = [];
Chart1.axes.bottom.innerGrid.increment = 0.20;
Chart1.axes.bottom.innerGrid.format = new Tee.Format(Chart1);
Chart1.axes.bottom.innerGrid.format.stroke.fill = Chart1.axes.bottom.grid.format.stroke.fill;
Chart1.axes.bottom.innerGrid.format.stroke.dash = [5, 3];
Chart1.axes.bottom.oldDrawLabel = Chart1.axes.bottom.drawLabel;
Chart1.axes.bottom.drawLabel = function(value, r) {
this.oldDrawLabel(value, r);
var c = this.chart.ctx,
rect = this.chart.chartRect,
f = this.innerGrid.format,
tmpX;
var tmpValue = value + this.innerGrid.increment;
while (tmpValue < value + this.increment) {
tmpX = Chart1.axes.bottom.calc(tmpValue);
if ((tmpX > rect.x) && (tmpX < rect.x + rect.width)) {
c.beginPath();
c.moveTo(tmpX, rect.y);
c.lineTo(tmpX, rect.y + rect.height);
f.stroke.prepare();
c.stroke();
}
tmpValue += this.innerGrid.increment;
}
//draw innerGrid between the axis minimum and the first label. Happens when scrolled
if (value - this.increment <= this.minimum) {
tmpValue = value - this.innerGrid.increment;
while (tmpValue > value - this.increment) {
tmpX = Chart1.axes.bottom.calc(tmpValue);
if ((tmpX > rect.x) && (tmpX < rect.x + rect.width)) {
c.beginPath();
c.moveTo(tmpX, rect.y);
c.lineTo(tmpX, rect.y + rect.height);
f.stroke.prepare();
c.stroke();
}
tmpValue -= this.innerGrid.increment;
}
}
};
Chart1.draw();
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://www.steema.com/files/public/teechart/html5/latest/src/teechart.js" type="text/javascript"></script>
</head>
<body onload="draw()">
<canvas id="canvas1" width="500" height="300">
This browser does not seem to support HTML5 Canvas.
</canvas>
</body>
</html>

Create radial Timer

I Want to create an radial timer.
The Problem is, the arc are not painting correctly, when i try to set the start and end angle.
Thats, what i want:
Here is my code:
var Timer = function Timer(selector) {
var _width = 134;
var _height = 134;
var _x = _width / 2;
var _y = _height / 2;
var _canvas = null;
var _context = null;
var _percentage = 0;
var _background = '#000000';
var _foreground = '#FF0000';
this.init = function init(selector) {
var element = document.querySelector(selector);
_canvas = document.createElement('canvas');
_canvas.setAttribute('width', _width);
_canvas.setAttribute('height', _height);
element.parentNode.replaceChild(_canvas, element);
_context = _canvas.getContext('2d');
this.paint();
};
this.clear = function clear() {
_context.clearRect(0, 0, _width, _height);
};
this.start = function start(seconds) {
var current = seconds;
var _watcher = setInterval(function AnimationInterval() {
_percentage = 100 * current / seconds;
if(_percentage < 0) {
_percentage = 0;
clearInterval(_watcher);
} else if(_percentage > 100) {
_percentage = 100;
clearInterval(_watcher);
}
this.paint();
console.log(_percentage + '%');
--current;
}.bind(this), 1000);
};
this.paint = function paint() {
this.clear();
this.paintBackground();
this.paintForeground();
};
this.paintForeground = function paintForeground() {
_context.beginPath();
_context.arc(_x, _y, 134 / 2 - 5, -(Math.PI / 2), ((Math.PI * 2) * _percentage) - (Math.PI / 2), false);
_context.lineWidth = 8;
_context.strokeStyle = _foreground;
_context.stroke();
};
this.paintBackground = function paintBackground() {
_context.beginPath();
_context.arc(_x, _y, 134 / 2 - 5, 0, Math.PI * 2, false);
_context.lineWidth = 10;
_context.strokeStyle = _background;
_context.stroke();
};
this.init(selector);
};
var timer = new Timer('timer');
timer.start(10);
<timer></timer>
Can you tell me, what i make wrong?

How to change the zoom factor to only zoom OUT on Ken Burns effect?

I am helping a friend with a website, and he is using the Ken Burns Effect with Javascript and Canvas from this site https://www.willmcgugan.com/blog/tech/post/ken-burns-effect-with-javascript-and-canvas/
for a slide-show. It works perfectly, but he would like to change the zoom effect to where all of the images zoom OUT, instead of alternating between zooming in and out.
After about a week of "scrambling" the code unsuccessfully, he posted a question about it on the site. The reply he received was (quote) "That's definitely possible, with a few tweaks of the code. Sorry, no time to give you guidance at the moment, but it shouldn't be all that difficult" (end quote).
I can't seem to figure it out either, so I'm hoping that someone here may be of help. Below is the code as posted on the willmcgugan.com website. Any help on how to change the zoom effect would be greatly appreciated.
(function($){
$.fn.kenburns = function(options) {
var $canvas = $(this);
var ctx = this[0].getContext('2d');
var start_time = null;
var width = $canvas.width();
var height = $canvas.height();
var image_paths = options.images;
var display_time = options.display_time || 7000;
var fade_time = Math.min(display_time / 2, options.fade_time || 1000);
var solid_time = display_time - (fade_time * 2);
var fade_ratio = fade_time - display_time
var frames_per_second = options.frames_per_second || 30;
var frame_time = (1 / frames_per_second) * 1000;
var zoom_level = 1 / (options.zoom || 2);
var clear_color = options.background_color || '#000000';
var images = [];
$(image_paths).each(function(i, image_path){
images.push({path:image_path,
initialized:false,
loaded:false});
});
function get_time() {
var d = new Date();
return d.getTime() - start_time;
}
function interpolate_point(x1, y1, x2, y2, i) {
// Finds a point between two other points
return {x: x1 + (x2 - x1) * i,
y: y1 + (y2 - y1) * i}
}
function interpolate_rect(r1, r2, i) {
// Blend one rect in to another
var p1 = interpolate_point(r1[0], r1[1], r2[0], r2[1], i);
var p2 = interpolate_point(r1[2], r1[3], r2[2], r2[3], i);
return [p1.x, p1.y, p2.x, p2.y];
}
function scale_rect(r, scale) {
// Scale a rect around its center
var w = r[2] - r[0];
var h = r[3] - r[1];
var cx = (r[2] + r[0]) / 2;
var cy = (r[3] + r[1]) / 2;
var scalew = w * scale;
var scaleh = h * scale;
return [cx - scalew/2,
cy - scaleh/2,
cx + scalew/2,
cy + scaleh/2];
}
function fit(src_w, src_h, dst_w, dst_h) {
// Finds the best-fit rect so that the destination can be covered
var src_a = src_w / src_h;
var dst_a = dst_w / dst_h;
var w = src_h * dst_a;
var h = src_h;
if (w > src_w)
{
var w = src_w;
var h = src_w / dst_a;
}
var x = (src_w - w) / 2;
var y = (src_h - h) / 2;
return [x, y, x+w, y+h];
}
function get_image_info(image_index, load_callback) {
// Gets information structure for a given index
// Also loads the image asynchronously, if required
var image_info = images[image_index];
if (!image_info.initialized) {
var image = new Image();
image_info.image = image;
image_info.loaded = false;
image.onload = function(){
image_info.loaded = true;
var iw = image.width;
var ih = image.height;
var r1 = fit(iw, ih, width, height);;
var r2 = scale_rect(r1, zoom_level);
var align_x = Math.floor(Math.random() * 3) - 1;
var align_y = Math.floor(Math.random() * 3) - 1;
align_x /= 2;
align_y /= 2;
var x = r2[0];
r2[0] += x * align_x;
r2[2] += x * align_x;
var y = r2[1];
r2[1] += y * align_y;
r2[3] += y * align_y;
if (image_index % 2) {
image_info.r1 = r1;
image_info.r2 = r2;
}
else {
image_info.r1 = r2;
image_info.r2 = r1;
}
if(load_callback) {
load_callback();
}
}
image_info.initialized = true;
image.src = image_info.path;
}
return image_info;
}
function render_image(image_index, anim, fade) {
// Renders a frame of the effect
if (anim > 1) {
return;
}
var image_info = get_image_info(image_index);
if (image_info.loaded) {
var r = interpolate_rect(image_info.r1, image_info.r2, anim);
var transparency = Math.min(1, fade);
if (transparency > 0) {
ctx.save();
ctx.globalAlpha = Math.min(1, transparency);
ctx.drawImage(image_info.image, r[0], r[1], r[2] - r[0], r[3] - r[1], 0, 0, width, height);
ctx.restore();
}
}
}
function clear() {
// Clear the canvas
ctx.save();
ctx.globalAlpha = 1;
ctx.fillStyle = clear_color;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.restore();
}
function update() {
// Render the next frame
var update_time = get_time();
var top_frame = Math.floor(update_time / (display_time - fade_time));
var frame_start_time = top_frame * (display_time - fade_time);
var time_passed = update_time - frame_start_time;
function wrap_index(i) {
return (i + images.length) % images.length;
}
if (time_passed < fade_time)
{
var bottom_frame = top_frame - 1;
var bottom_frame_start_time = frame_start_time - display_time + fade_time;
var bottom_time_passed = update_time - bottom_frame_start_time;
if (update_time < fade_time) {
clear();
} else {
render_image(wrap_index(bottom_frame), bottom_time_passed / display_time, 1);
}
}
render_image(wrap_index(top_frame), time_passed / display_time, time_passed / fade_time);
if (options.post_render_callback) {
options.post_render_callback($canvas, ctx);
}
// Pre-load the next image in the sequence, so it has loaded
// by the time we get to it
var preload_image = wrap_index(top_frame + 1);
get_image_info(preload_image);
}
// Pre-load the first two images then start a timer
get_image_info(0, function(){
get_image_info(1, function(){
start_time = get_time();
setInterval(update, frame_time);
})
});
};
})( jQuery );
If you want the simplest solution, I forked and modified your Codepen here:
http://codepen.io/jjwilly16/pen/NAovkp?editors=1010
I just removed a conditional that controls whether the zoom is moving out or in.
if (image_index % 2) {
image_info.r1 = r1;
image_info.r2 = r2;
}
else {
image_info.r1 = r2;
image_info.r2 = r1;
}
Changed to:
image_info.r1 = r2;
image_info.r2 = r1;
Now it only zooms out :)

Why is my line not drawing over time?

I am trying to have a line draw to the canvas over a certain amount of time(ten seconds to be exact). I'm able to see that the script is counting to a certain time and then stopping, but I'm not seeing the line being drawn. Can anyone show me what I'm doing wrong?
$(document).ready(function(){
canvas = document.getElementById("test");
ctx = canvas.getContext("2d");
var count = 0;
var start_x = 0;
var start_y = 100;
var end_x = 50;
var end_y = 100;
var counter = setInterval(countNumbers, 1000);
ctx.beginPath();
ctx.moveTo(start_x, start_y);
console.log("Start");
function countNumbers(){
count += 1;
ctx.lineTo((start_x + count), start_y);
console.log(count);
if((start_x == end_x) || (count == 10)){
clearInterval(counter);
console.log("End");
}
}
ctx.lineWidth = 5;
ctx.strokeStyle = "white";
ctx.stroke();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="test"></canvas>
Try to move stroke inside the Interval. Because in your case stroke are called immediately without lineTo data. And after that lineTo are called in interval function and cannot be rendered without stroke.
$(document).ready(function(){
canvas = document.getElementById("test");
ctx = canvas.getContext("2d");
var count = 0;
var start_x = 0;
var start_y = 100;
var end_x = 50;
var end_y = 100;
var counter = setInterval(countNumbers, 1000);
ctx.beginPath();
ctx.moveTo(start_x, start_y);
console.log("Start");
function countNumbers(){
count += 1;
ctx.lineTo((start_x + count), start_y);
console.log(count);
if((start_x == end_x) || (count == 10)){
clearInterval(counter);
console.log("End");
ctx.lineWidth = 5; // <----- move here
ctx.strokeStyle = "white";
ctx.stroke();
}
}
})
Also ensure that you are not drawing white lines on white background
$(document).ready(function(){
canvas = document.getElementById("test");
ctx = canvas.getContext("2d");
var count = 0;
var start_x = 0;
var start_y = 100;
var end_x = 50;
var end_y = 100;
var counter = setInterval(countNumbers, 1000);
ctx.beginPath();
ctx.moveTo(start_x, start_y);
console.log("Start");
ctx.lineWidth = 5;
ctx.strokeStyle = "black";
function countNumbers(){
count += 1;
ctx.lineTo((start_x + count), start_y);
ctx.stroke();
console.log(count);
if((start_x == end_x) || (count == 10)){
clearInterval(counter);
console.log("End");
ctx.strokeStyle = "white";
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="test"></canvas>
I would count down for the step. This will allow you to figure out the step.
I modified your code to allow you to pass parameters into the interval function to minimize global scope variables. Since I passed a reference of the interval into itself, you no longer need to have global variables.
I created two function, the first will create a path and then stroke it. The second one will stroke a sub-line after each tick of the interval. I added a simple check for even-odd to swap between colors.
$(document).ready(function() {
var canvas = $('canvas#test')[0];
var ctx = canvas.getContext('2d');
var count = 10;
var start_x = 50, start_y = 50;
var end_x = 250, end_y = 150;
var delta_x = end_x - start_x, delta_y = end_y - start_y;
var step_x = delta_x / count, step_y = delta_y / count;
canvas.width = 300;
canvas.height = 200;
// Fill canvas with solid black.
ctx.rect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'black';
ctx.fill();
// Kick off the line stroke timer. No more global variables!
var counter = setInterval(function(opts) {
// Pass a reference to the timer into the interval.
strokeLineTimerLive(counter, opts);
}, 500, {
ctx : ctx,
n : count,
x1 : start_x,
y1 : start_y,
x2 : end_x,
y2 : end_y,
dx : step_x,
dy : step_y,
});
// After the interval has ended, the path is finally stroked.
function strokeLineTimer(timer, opts) {
if (!opts.init) {
console.log("Start");
opts.ctx.beginPath();
opts.ctx.moveTo(opts.x1, opts.y1);
opts.ctx.lineWidth = 5;
opts.ctx.strokeStyle = 'white';
opts.init = true;
}
opts.n -= 1;
opts.ctx.lineTo((opts.x1 += opts.dx), (opts.y1 += opts.dy));
console.log(opts.n);
if ((opts.x1 == opts.x2) || (opts.n == 0)){
clearInterval(timer);
opts.ctx.stroke();
console.log("End");
}
}
// After each tick of the interval, a line is stroked.
function strokeLineTimerLive(timer, opts) {
if (!opts.init) {
console.log("Start");
opts.ctx.beginPath();
opts.ctx.moveTo(opts.x1, opts.y1);
opts.ctx.lineWidth = 5;
opts.init = true;
}
opts.n -= 1;
opts.ctx.strokeStyle = opts.n % 2 == 0 ? 'white' : 'red';
opts.ctx.lineTo((opts.x1 += opts.dx), (opts.y1 += opts.dy));
opts.ctx.stroke();
console.log(opts.n);
if ((opts.x1 == opts.x2) || (opts.n == 0)){
clearInterval(timer);
console.log("End");
} else {
opts.ctx.beginPath();
opts.ctx.moveTo(opts.x1, opts.y1);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="test"></canvas>

Categories

Resources