JS windows.onload does not work - javascript

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>

Related

Identify points in each quadrant of a canvas

How do you divide a canvas into four quadrants (top-left, bottom-left, top-right, bottom-right) and then identify points drawn at random in each quadrant?
Here is my not so futile attempt:
var myCanvas = document.getElementById("showCanvas");
var myContext = myCanvas.getContext("2d");
var xAxis = [];
var yAxis = [];
for (var i = 0; i < 4; i++) {
var x = Math.floor(Math.random() * 600);
var y = Math.floor(Math.random() * 350);
var r = 5;
xAxis.push(x);
yAxis.push(y);
myContext.arc(x, y, r, 0, 2 * Math.PI, true);
myContext.closePath();
myContext.fill();
}
var startingPoint = xAxis[0] + ", " + yAxis[0];
var endingPoint = xAxis[3] + ", " + yAxis[3];
var horizontalSlash = myCanvas.width / 2;
var verticalSlash = myCanvas.height / 2;
var remainder = horizontalSlash % verticalSlash;
<canvas id="showCanvas"></canvas>
And the result should show up in these tags:
<h3>The starting point of the line is: <label id="sumPoints">e.g. top, right</label></h3>
<h3>The end point of the line is: <label id="sumPoints">e.g. bottom, left</label></h3>
The suggestion to check the point's coordinates is correct...
Here is an example using a bit of math.
const canvas = document.getElementById("showCanvas");
const ctx = canvas.getContext("2d");
const names = [
["top left", "bottom left"],
["top right", "bottom right"]
]
var points = []
for (var i = 0; i < 4; i++) {
var x = Math.random() * canvas.width
var y = Math.random() * canvas.height
var quadrant = names[Math.floor(x / (canvas.width / 2))][Math.floor(y / (canvas.height / 2))]
points.push({ x, y, quadrant })
ctx.arc(x, y, 5, 0, 2 * Math.PI);
ctx.fillText(quadrant, x-8, y-8)
ctx.closePath();
ctx.fill();
}
console.log(points[0])
canvas {
border:2px dotted gray;
}
<canvas id="showCanvas" width=200 height=200></canvas>

Why does it take longer to draw various colors than one color, both one pixel at a time?

This was narrowed down from a much larger script, but you can see that drawing a gradient based on the x value takes much more time than just passing it value 255.
Why should this matter? In either case, they are both drawing one pixel at a time, and they are both doing the work to derive the value of x.
By the way, my goal is not to find a faster way of drawing gradients.
var canvas = document.getElementById('canvas')
canvas.width = 600
canvas.height = 600
var ctx = canvas.getContext('2d')
init();
function init()
{
requestAnimationFrame(draw)
}
function draw()
{
const t0 = performance.now();
for(x = 0; x < canvas.width; x++)
{
for(y = 0; y < canvas.height; y++)
{
setPixelWhiteColor(x,x,y)
//setPixelWhiteColor(255,x,y) // <- faster?
}
}
const t1 = performance.now();
document.getElementById("debug1").innerHTML = t1 - t0
requestAnimationFrame(draw)
}
function setPixelWhiteColor(w,x,y)
{
ctx.fillStyle = "rgb("+w+","+w+","+w+")";
ctx.fillRect( x, y, 1, 1 );
}
<canvas id="canvas"></canvas>
<div id="debug1"></div>
I had to work with raw image data using putImageData like Wiktor said:
var canvas = document.getElementById('canvas')
canvas.width = 600
canvas.height = 600
var ctx = canvas.getContext('2d')
var id = ctx.getImageData(0, 0, canvas.width, canvas.height);
var pixels = id.data;
init();
function init()
{
requestAnimationFrame(draw)
}
function draw()
{
const t0 = performance.now();
for(x = 0; x < canvas.width; x++)
{
for(y = 0; y < canvas.height; y++)
{
var w = x
if(w > 255){
w = 255
}
setPixelWhiteColor(w,x,y)
}
}
putImageData()
const t1 = performance.now();
document.getElementById("debug1").innerHTML = t1 - t0
requestAnimationFrame(draw)
}
function setPixelWhiteColor(w,x,y)
{
var r = w
var g = w
var b = w
var off = (y * id.width + x) * 4;
pixels[off] = r;
pixels[off + 1] = g;
pixels[off + 2] = b;
pixels[off + 3] = 255;
}
function putImageData(){
ctx.putImageData(id, 0, 0);
}
<html>
<body>
<canvas id="canvas"></canvas>
<div id="debug1"></div>
<div id="debug2"></div>
<script>
</script>
</body>
</html>

How to make a circular progress countdown timer?

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);

Canvas not drawing after using

I have a function that, when called, clears the canvas.
function ClearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
The problem I'm having is that when I try to draw something onto the canvas again using fillRect() the items I want to draw appear on the bottom of the canvas, only a few of them showing up. The second time I try, nothing shows up.
To see my full code and a test run, go here
var width = 50;
var height = 50;
var interpolate = d3.interpolate('white', 'black');
var elevation = [];
var colormap = [];
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var rectY = 0;
Generate2DArray(elevation, 0, width, height);
Generate2DArray(colormap, 0, width, height);
var gen = new SimplexNoise();
function Generate2DArray(EmptyArray, fill, width, height) {
for(var i = 0; i < height; i++) {
EmptyArray.push([]);
for(var j = 0; j < width; j++) {
EmptyArray[i][j] = fill;
}
}
}
function noise(nx, ny) {
// Rescale from -1.0:+1.0 to 0.0:1.0
return gen.noise2D(nx, ny) / 2 + 0.5;
}
function ClearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function GenTerrain() {
for(var y = 0; y < height; y++) {
for(var x = 0; x < width; x++) {
var nx = x/width - 0.5, ny = y/height - 0.5;
elevation[y][x] = noise(nx * 2.57, ny * 2.57);
colormap[y][x] = interpolate(elevation[y][x]);
ctx.fillStyle = colormap[y][x];
ctx.fillRect(x*10, y+rectY, 10, 10);
}
rectY += 9
}
}
Your rectY is being declared at the top of your code, at the global level:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var rectY = 0;
So, every time GenTerrain runs, it references that variable and adds to it:
rectY += 9
Fix it by encapsulating rectY inside GenTerrain so it starts at 0 each time the function is called.
function GenTerrain() {
var rectY = 0;
for(var y = 0; y < height; y++) {
for(var x = 0; x < width; x++) {
var nx = x/width - 0.5, ny = y/height - 0.5;
elevation[y][x] = noise(nx * 2.57, ny * 2.57);
colormap[y][x] = interpolate(elevation[y][x]);
ctx.fillStyle = colormap[y][x];
ctx.fillRect(x*10, y+rectY, 10, 10);
}
rectY += 9
}
}

Bar chart in javascript

The following code is my attempt to create a bar chart with javascript and the html 5 canvas:
var canvas = $("#chart");
var ctx = canvas.getContext("2d");
ctx.strokeFill = "green";
var margin = 5;
var bWidth = (canvas.width - (margin * results.length)) / results.length;
var max = results.sort()[results.length - 1];
var yScale = canvas.height / max;
for (result of results)
{
ctx.strokeRect();
}
The data I am trying to visualize looks like this:
[{"choice": "Yes", votes: 2}, {"choice": "No", votes: 1}, {"choice":"maybe", votes: 3}]
The questions are:
How can I compute the x and y axes for each element?
How can I print the choices under the bars?
There can be up to 20 choices and each can be up to 200 characters. How could this be handled?
After additional research the following is the solution:
var results = extractResults($("#results"));
var canvas = $("#chart");
var ctx = canvas.getContext("2d");
var margin = canvas.width * 0.005;
var bWidth = (canvas.width - (margin * results.length)) / results.length;
var max = Math.max.apply( Math, results );
var yScale = canvas.height / max;
var currX = margin;
ctx.font = "20px Arial"
for (i = 0; i < results.length; i++)
{
var bHeight = yScale * results[i];
ctx.fillStyle = "green";
ctx.fillRect(currX, canvas.height - bHeight, bWidth, bHeight);
ctx.fillStyle = "black";
ctx.fillText(i + 1, currX + bWidth / 2, canvas.height - canvas.height * 0.05, bWidth / 2);
currX += bWidth + margin;
}

Categories

Resources