hi im a newbie and im currently trying to build an app called sink ships.
I already drew the the circles with a css property and the tanks which look like this <------00000 are also moving with a with javascript I used for that the window.addEventlistener and giving each movement a property case going left right up down. Now I want the circle which symbolices the tanks to move down and up and up again and disappearing when I the bazooka touched the circle (tank) my code looking like this:
let circle = document.getElementById(".circle");
let moveBy = 10;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
window.addEventListener("load", () => {
circle.style.position = "absolute";
circle.style.left = 0;
circle.style.top = 0;
});
window.addEventListener("keyup", (e) => {
switch (e.key) {
case "ArrowLeft":
circle.style.left = parseInt(circle.style.left) - moveBy + "px";
break;
case "ArrowRight":
circle.style.left = parseInt(circle.style.left) + moveBy + "px";
break;
case "ArrowUp":
circle.style.top = parseInt(circle.style.top) - moveBy + "px";
break;
case "ArrowDown":
circle.style.top = parseInt(circle.style.top) + moveBy + "px";
break;
}
});
function drawBall() {
ctx.beginPath();
ctx.arc(x, y, 10, 0, Math.PI * 2);
ctx.fillStyle = "#0095DD";
ctx.fill();
ctx.closePath();
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBall();
x += dx;
y += dy;
}
setInterval(draw, 10);
.circle {
height: 100px;
width: 100px;
border-radius: 50%;
background-color: rgb(0, 0, 0);
text-align-last: grid;
justify-content: center;
align-items: center;
ast: right;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body style="background-color: rgb(177, 133, 133)">
<canvas id="myCanvas"></canvas>
<div id=".circle"><------000</div>
<div class="circle"></div>
</body>
</html>
Now my question could someone help me with a code that could make my circle move up and down I already copied a code from the internet maybe it could help with the first steps
The question is a little vague to me. I interpret it to mean that you want the large black circle to move up and down, the ASCII art to move with the keyboard, and if the front of the ASCII art touches the big circle, the big circle disappears.
Traditionally, one would write a game for the browser using a canvas object. In your code you have some content that is trying to use a canvas, but since you do not declare a canvas or create a canvas element in javascript, the canvas code is throwing exceptions. My recommendation would be stop using html elements and move to a canvas. However, to keep the answer as close to the origin code as possible, I'll provide some code that uses the original HTML elements followed by a canvas implementation.
Element-base solution
If you want to build the game using just html elements, you would need to make the following changes to your script:
// var canvas = document.getElementById("myCanvas");
// var ctx = canvas.getContext("2d");
// var x = canvas.width/2;
// var y = canvas.height-30;
let x = 100;
let y = 100;
let ticks = 0;
var dx = 2;
var dy = 100;
let bigCircle = document.getElementsByClassName('circle')[0];
// ctx.beginPath();
function drawBall() {
// ctx.arc(x, y, 10, 0, Math.PI*2);
// ctx.fillStyle = "#0095DD";
// ctx.fill();
// ctx.closePath();
}
function styleStringToNumber(string) {
return +(string.substring(0, string.length - 2));
}
function draw() {
//ctx.clearRect(0, 0, canvas.width, canvas.height);
// drawBall();
ticks++;
animatedY = Math.cos(ticks / 100) * 100 + dy;
bigCircle.style.top = animatedY;
let circleBoundary = document.getElementById(".circle").getBoundingClientRect();
let tip = { x: circleBoundary.left, y: (circleBoundary.top + circleBoundary.bottom) / 2 }
let distance = Math.sqrt((styleStringToNumber(bigCircle.style.top) + 50 - tip.y) ** 2 + (styleStringToNumber(bigCircle.style.left) + 50 - tip.x) ** 2)
if (distance < 50)
bigCircle.style.visibility = "hidden"
}
setInterval(draw, 10);
You also have some ill-formatted code in you css. You can resolve the issues to removing the end of the last line so it only reads "align-items: center;" and by appending a final closing curly brace.
Description
Lines that have to do with a canvas have been commented out
We get a reference to the big circle by querying for a list of elements with the class circle and grabbing the first one in the list.
We add a function "styleStringToNumber" that will take the positional data from the big circle's style and convert it from a string with a trailing "px" to a number.
Move the big circle up and down with time. There are many ways to do this. I chose to use a simple trigonometric function since it eases in and out of it's vertical movement.
Get the boundary of the element referenced by circle
Use the Pythagorean theorem to find the distance from the center of the big circle and the left side of the 'circle' bounding box.
If the distance is less than the radius of the big circle, then change the visibility to hidden.
Using a Canvas
If you were to convert to using a canvas, you could reproduce this behavior this:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv='X-UA-Compatible' content='IE=edge'>
<title>Page Title</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style>
html,
body {
overflow: hidden
}
</style>
</head>
<body onkeyup='keyup(event)'>
<canvas id="canv" width=640 height=480></canvas>
<script>
let ctx = document.querySelector("#canv").getContext("2d")
let asciiPosition = { x: 0, y: 10 }
let circlePosition = { x: 0, y: 0 }
let ticks = 0;
let showBigCircle = true;
function main() {
//update and draw every 10ms
setInterval(update, 10)
}
//Change the state of the game
function update() {
ticks++
circlePosition.y = Math.cos(ticks / 100) * 100 + 100;
//Check if they are in collision
let distance = Math.sqrt((asciiPosition.x - (circlePosition.x + 50))**2 + (asciiPosition.y - (circlePosition.y + 50))**2)
if(distance < 50)
showBigCircle = false;
draw();
}
//Draw the game
function draw() {
ctx.fillStyle = "lightgreen";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle = "black"
ctx.fillText("<------000", asciiPosition.x, asciiPosition.y)
if (showBigCircle) {
ctx.beginPath();
ctx.arc(circlePosition.x + 50, circlePosition.y + 50, 50, 0, Math.PI * 2);
ctx.fill();
}
}
//Respondto keyboard events
function keyup(e) {
let jump = 10;
switch (e.key) {
case 'ArrowLeft':
asciiPosition.x -= jump;
break;
case 'ArrowRight':
asciiPosition.x += jump;
break;
case 'ArrowUp':
asciiPosition.y -= jump;
break;
case 'ArrowDown':
asciiPosition.y += jump;
break;
}
}
//Start the game loop
main();
</script>
</body>
</html>
Related
I'm trying to implement zoom in an HTML5 Canvas. I came across other threads that explain how to do it, but they take advantage of the canvas' context, storing previous transformations. I want to avoid that.
So far I managed to do the following (https://jsfiddle.net/wfqzr538/)
<!DOCTYPE html>
<html>
<body style="margin: 0">
<canvas id="canvas" width="400" height="400" style="border: 1px solid #d3d3d3"></canvas>
<script>
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
let cursorX = 0,
cursorY = 0;
let zoom = 1;
canvas.onmousemove = mouseMove;
window.onkeydown = keyDown;
draw();
function mouseMove(evt) {
cursorX = evt.clientX;
cursorY = evt.clientY;
}
function keyDown(evt) {
if (evt.key == "p") {
zoom += 0.1;
}
if (evt.key == "m") {
zoom -= 0.1;
}
draw();
}
function draw() {
context.clearRect(0, 0, canvas.width, canvas.height);
const translationX = -cursorX * (zoom - 1);
const translationY = -cursorY * (zoom - 1);
context.translate(translationX, translationY);
context.scale(zoom, zoom);
context.fillRect(100, 100, 30, 30);
context.scale(1 / zoom, 1 / zoom);
context.translate(-translationX, -translationY);
}
</script>
</body>
</html>
The code above works If I zoom at the same location, but breaks as soon as I change it. For example, if I zoom in twice at the top left corner of the square, it works. However, if I zoom once at the top left corner, followed by zooming at the right bottom corner, it breaks.
I've been trying to fix this for a while now. I think it has something with not taking into account previous translations made in the canvas, but I'm not sure.
I'd really appreciate some help.
Not keeping previous state
If you don't want to keep the previous transform state then the is no way to do what you are trying to do.
There are many way to keep the previous state
Previous world state
You can transform all object's world state, in effect embedding the previous transform in the object's coordinates.
Eg with zoom and translate
object.x = object.x * zoom + translate.x;
object.y = object.y * zoom + translate.y;
object.w *= zoom;
object.h *= zoom;
then draw using default transform
ctx.setTransform(1,0,0,1,0,0);
ctx.fillRect(object.x, object.y, object.w, object.h);
Previous transformation state
To zoom at a point (absolute pixel coordinate) you need to know where the previous origin was so you can workout how far the zoom point is from that origin and move it correctly when zooming.
Your code does not keep track of the origin, in effect it assumes it is always at 0,0.
Example
The example tracks the previous transform state using an array that represents the transform. It is equivalent to what your code defines as translation and zoom.
// from your code
context.translate(translationX, translationY);
context.scale(zoom, zoom);
// is
transform = [zoom, 0, 0, zoom, translationX, translationY];
The example also changes the rate of zooming. In your code you add and subtract from the zoom, this will result in negative zooms, and when zooming in it will take forever to get to large scales. The scale is apply as a scalar eg zoom *= SCLAE_FACTOR
The function zoomAt zooms in or out at a given point on the canvas
const ctx = canvas.getContext("2d");
const transform = [1,0,0,1,0,0];
const SCALE_FACTOR = 1.1;
const pointer = {x: 0, y: 0};
var zoom = 1;
canvas.addEventListener("mousemove", mouseMove);
addEventListener("keydown", keyDown);
draw();
function mouseMove(evt) {
pointer.x = evt.clientX;
pointer.y = evt.clientY;
drawPointer();
}
function keyDown(evt) {
if (evt.key === "p") { zoomAt(SCALE_FACTOR, pointer) }
if (evt.key === "m") { zoomAt(1 / SCALE_FACTOR, pointer) }
}
function zoomAt(amount, point) {
zoom *= amount;
transform[0] = zoom; // scale x
transform[3] = zoom; // scale y
transform[4] = point.x - (point.x - transform[4]) * amount;
transform[5] = point.y - (point.y - transform[5]) * amount;
draw();
}
function draw() {
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.setTransform(...transform);
ctx.fillRect(100, 100, 30, 30);
}
function drawPointer() {
draw();
ctx.lineWidth = 1;
ctx.strokeStyle = "black";
const invScale = 1 / transform[0]; // Assumes uniform scale
const x = (pointer.x - transform[4]) * invScale;
const y = (pointer.y - transform[5]) * invScale;
const size = 10 * invScale;
ctx.beginPath();
ctx.lineTo(x - size, y);
ctx.lineTo(x + size, y);
ctx.moveTo(x, y - size);
ctx.lineTo(x, y + size);
ctx.setTransform(1, 0, 0, 1, 0, 0); // to ensure line width is 1 px
ctx.stroke();
ctx.font = "16px arial";
ctx.fillText("Pointer X: " + x.toFixed(2) + " Y: " + y.toFixed(2), 10, 20);
}
* {margin: 0px}
canvas { border: 1px solid #aaa }
<canvas id="canvas" width="400" height="400"></canvas>
Update
I have added the function drawPointer which uses the transform to calculate the pointers world position, render a cross hair at the position and display the coordinates.
I am trying to make a simple game. The green block is my game character. I used a the keydown event to make my character able to move right and left. When I hold down the right or left arrow key, the character keeps on accelerating. If you start by tapping the right or left arrow key, you will see that the space interval between where the character was and where it is increases as you click more. How can I make my character move at a constant speed with constant space intervals.
//variables
var canvas = document.getElementById("canvas");
var draw = canvas.getContext("2d");
var characterx = 20;
var charactery = window.innerHeight - 60;
var dx = 0.01;
var dy = 0.01;
//canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//main game function
function run() {
//loops the function
requestAnimationFrame(run);
//clears the screen
draw.clearRect(0, 0, canvas.width, canvas.height)
//draws the ground
draw.beginPath();
draw.fillStyle = "#823819";
draw.fillRect(0, canvas.height - 20, canvas.width, 20);
draw.fill();
draw.closePath();
//draws the main character
draw.beginPath();
draw.fillStyle = "#128522";
draw.fillRect(characterx, charactery, 40, 40);
draw.fill();
draw.closePath();
//key evevnts
window.addEventListener("keydown",function(event) {
if(event.keyCode == 39) {
characterx += dx;
}
});
window.addEventListener("keydown",function(event) {
if(event.keyCode == 37) {
characterx -= dx;
}
});
};
run();
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style type="text/css">
body {
margin: 0;
overflow: hidden;
}
canvas {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
Your event listeners should be added outside of your game loop.
Currently you are adding an extra listener for each keypress on every frame, meaning that on the first frame you will move dx * 1 for a keypress, but on frame 100 you will move dx * 100 for a single keypress.
This is also why your dx value had to be so low - I've increased it in the sample below, but you can adjust it as needed.
//variables
var canvas = document.getElementById("canvas");
var draw = canvas.getContext("2d");
var characterx = 20;
var charactery = window.innerHeight - 60;
var dx = 3.0;
var dy = 3.0;
//canvas size
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
//key evevnts
window.addEventListener("keydown",function(event) {
if(event.keyCode == 39) {
characterx += dx;
}
});
window.addEventListener("keydown",function(event) {
if(event.keyCode == 37) {
characterx -= dx;
}
});
//main game function
function run() {
//loops the function
requestAnimationFrame(run);
//clears the screen
draw.clearRect(0, 0, canvas.width, canvas.height)
//draws the ground
draw.beginPath();
draw.fillStyle = "#823819";
draw.fillRect(0, canvas.height - 20, canvas.width, 20);
draw.fill();
draw.closePath();
//draws the main character
draw.beginPath();
draw.fillStyle = "#128522";
draw.fillRect(characterx, charactery, 40, 40);
draw.fill();
draw.closePath();
};
run();
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<style type="text/css">
body {
margin: 0;
overflow: hidden;
}
canvas {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
I've taken nearly every possible countermeasure to prevent my program from drawing two dots instead of one on my chart. I want the dot in the middle to be shown, not the one in the top left. It seems to me the dot is being drawn once in the top left, matching the coordinates and everything, but then it draws a second dot with the translate method. Of course this is just speculation from what's happening on screen. The problem is occurring somewhere in the draw() function, init() function, or the anim() function - I can't pinpoint where the problem is.
let graph = document.getElementById('chart');
let c = graph.getContext('2d');
graph.height = 754;
graph.width = 754;
function algebra() {
xVertex = 2 * 10;
yVertex = 5 * 10;
let radius = 3;
let node = [];
function Node(xVertex, yVertex, radius) {
this.r = radius;
this.xV = xVertex;
this.yV = yVertex;
this.draw = function() {
c.beginPath();
c.arc(this.xV, this.yV, this.r, 0, Math.PI * 2, false);
c.fillStyle = "red";
c.fill();
c.translate(377, 377);
c.stroke();
c.closePath();
};
this.update = function() {
this.draw();
};
};
function init() {
node.push(new Node(xVertex, yVertex, radius));
anim();
};
function anim() {
requestAnimationFrame(anim);
for (let i = 0; i < node.length; i++) {
node[i].update(node);
};
c.clearRect(0, 0, graph.width, graph.height);
console.log(node);
};
init();
};
#graph {
left: 100px;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> Proof of concept </title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="graph">
<canvas id="chart"></canvas>
<div id="y-axis"></div>
<div id="x-axis"></div>
</div>
<div id="button" onclick="algebra()">
<div id="btext">Calculate</div>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
I think I found your errors:
1) When you call anim() it must first clear the canvas and then redraw all points.
2) Call the next animation frame after all points are drawn on the canvas
And the main problem:
3) You are doing a translate of the canvas origin on each point drawn (and a large one (377, 377)). Since the origin is changing at every iteration or point drawn also the canvas section that is being erased is moving. The two points you got were the first and second iterarions, the others were offscreen.
What you need to do is translate the canvas origin to its middle only once, just after:
let c = graph.getContext('2d');
graph.height = 754;
graph.width = 754;
//Translate the origin to the canvas' center (do this only once)
c.translate(graph.width/2, graph.height/2);
If the canvas origin has moved to the center, then you must also erase the canvas from -width/2 to width/2 and height/2 to height/2. To do this you must use:
c.clearRect(-graph.width/2, -graph.height/2, graph.width, graph.height);
Just for fun, I've added three more points to the node array and adding a random number between -1 and 1 to each coordinate in every iteration. This results in a Brownian like motion simulation.
let graph = document.getElementById('chart');
let c = graph.getContext('2d');
graph.height = 754;
graph.width = 754;
//Translate the origin to the canvas' center (do this only once)
c.translate(graph.width/2, graph.height/2);
function algebra() {
//Changed to 0 to plot at center
xVertex = 0;
yVertex = 0;
let radius = 3;
let node = [];
function Node(xVertex, yVertex, radius) {
this.r = radius;
this.xV = xVertex;
this.yV = yVertex;
this.draw = function() {
c.beginPath();
c.arc(this.xV, this.yV, this.r, 0, Math.PI * 2, false);
c.fillStyle = "red";
c.fill();
c.stroke();
c.closePath();
};
this.update = function() {
//this will generate random movement in x and y.
this.xV += Math.random()*2-1;
this.yV += Math.random()*2-1;
this.draw();
};
};
function init() {
node.push(new Node(xVertex, yVertex, radius));
node.push(new Node(xVertex, yVertex, radius));
node.push(new Node(xVertex, yVertex, radius));
node.push(new Node(xVertex, yVertex, radius));
anim();
};
function anim() {
//First clear the canvas then redraw
c.clearRect(-graph.width/2, -graph.height/2, graph.width, graph.height);
for (let i = 0; i < node.length; i++) {
node[i].update(node);
};
//After all are drawn, call the next Animation Frame
requestAnimationFrame(anim);
};
init();
};
#graph {
left: 100px;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title> Proof of concept </title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="graph">
<canvas id="chart"></canvas>
<div id="y-axis"></div>
<div id="x-axis"></div>
</div>
<div id="button" onclick="algebra()">
<div id="btext">Calculate</div>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
I would like to point out that I'm a beginner at this. So please, I hope you don't mind me asking questions to your solutions.
What I'm trying to construct here is a graphical animation of a ball falling to the ground from a height and then slowly, after several subsequent bounces, the ball just rolls on the base of the canvas.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>JavaScript examples</title>
<!-- As a shortcut, I included style information here rather than a separate file -->
<style>
canvas {
border: 1px solid gray;
}
</style>
<!-- incorporate jQuery -->
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<!-- now my written script -->
<script>
$(function(){
// initialise canvas and context
var canvas = document.getElementById('canvas');
// physical variables
var g = 0.1; // gravity
var fac = 0.8; // velocity reduction factor per bounce
var radius = 20; // ball radius
var color = "#0000ff"; // ball color
var intervalId
function initBall() {
// initialise position and velocity of ball
var x = 50;
var y = 50;
var horizontalvelocity = 2;
var verticalvelocity = 0;
}
function drawBall() {
with (context){
clearRect(0, 0, canvas.width, canvas.height); // clear canvas
fillStyle = color;
beginPath();
arc(x, y, radius, 0, 2*Math.PI, true);
closePath();
fill();
};
};
function render() {
// update velocity
verticalvelocity += g; // gravity
// update position
x += horizontalvelocity;
y += verticalvelocity;
// handle bouncing
if (y > canvas.height - radius){
y = canvas.height - radius;
verticalvelocity *= -fac;
}
// wrap around
if (x > canvas.width + radius){
x = -radius;
}
// update the ball
drawBall();
};
function init() {
<!-- get the rendering area for the canvas -->
context = $('#canvas')[0].getContext("2d");
WIDTH = $('#canvas').width();
HEIGHT = $('#canvas').height();
setInterval(update, 1000/60); // 60 frames per second
initBall();
<!-- start animation -->
intervalId = setInterval(render, 10);
}
$(document).ready(init);
</script>
</head>
<body>
<canvas id="canvas" width="700" height="500"></canvas>
</body>
</html>
I can't seem to detect the errors I made. Your ideas and solutions would be greatly appreciated. :)
Your issue relates to a scope issue : you are using x,y variables through all your code, so they should be global variables. But your issues are 1) is that you didn't declare them as global variable and 2) when you initialize x,y in initBall, you declare 2 local vars that are x,y, that will hide x,y global vars.
--> add with global scope :
var x,y ;
(by the way declare also
var horizontalvelocity = 2;
var verticalvelocity = 0;
)
--> remove the var declaration in
function initBall() {
// initialise position and velocity of ball
x = 50;
y = 50;
horizontalvelocity = 2;
verticalvelocity = 0;
}
When you put a picture named logo.png in the same directory as this html file and try to run it in a web browser the picture only appears 1 times out of 10 refreshes in IE and doesn't appear the first time in Firefox but does appear after further refreshes.
What the heck is going on ?
(drawImage() method is called in the showIntro() function)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Example 1 - Title Screen</title>
<script>
window.onload = function () {
var canvas = document.getElementById('myCanvas');
var c = canvas.getContext('2d');
var State = {
_current: 0,
INTRO: 0,
LOADING: 1,
LOADED: 2
}
window.addEventListener('click', handleClick, false);
window.addEventListener('resize', doResize, false);
doResize();
function handleClick() {
State._current = State.LOADING;
fadeToWhite();
}
function doResize() {
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
switch (State._current) {
case State.INTRO:
showIntro();
break;
}
}
function fadeToWhite(alphaVal) {
// If the function hasn't received any parameters, start with 0.02
var alphaVal = (alphaVal == undefined) ? 0.02 : parseFloat(alphaVal) + 0.02;
// Set the color to white
c.fillStyle = '#FFFFFF';
// Set the Global Alpha
c.globalAlpha = alphaVal;
// Make a rectangle as big as the canvas
c.fillRect(0, 0, canvas.width, canvas.height);
if (alphaVal < 1.0) {
setTimeout(function () {
fadeToWhite(alphaVal);
}, 30);
}
}
function showIntro() {
var phrase = "Click or tap the screen to start the game";
// Clear the canvas
c.clearRect(0, 0, canvas.width, canvas.height);
// Make a nice blue gradient
var grd = c.createLinearGradient(0, canvas.height, canvas.width, 0);
grd.addColorStop(0, '#ceefff');
grd.addColorStop(1, '#52bcff');
c.fillStyle = grd;
c.fillRect(0, 0, canvas.width, canvas.height);
var logoImg = new Image();
logoImg.src = './logo.png';
// Store the original width value so that we can keep
// the same width/height ratio later
var originalWidth = logoImg.width;
// Compute the new width and height values
logoImg.width = Math.round((50 * document.body.clientWidth) / 100);
logoImg.height = Math.round((logoImg.width * logoImg.height) / originalWidth);
// Create an small utility object
var logo = {
img: logoImg,
x: (canvas.width / 2) - (logoImg.width / 2),
y: (canvas.height / 2) - (logoImg.height / 2)
}
// Present the image
c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height);
// Change the color to black
c.fillStyle = '#000000';
c.font = 'bold 16px Arial, sans-serif';
var textSize = c.measureText(phrase);
var xCoord = (canvas.width / 2) - (textSize.width / 2);
c.fillText(phrase, xCoord, (logo.y + logo.img.height) + 50);
}
}
</script>
<style type="text/css" media="screen">
html { height: 100%; overflow: hidden }
body {
margin: 0px;
padding: 0px;
height: 100%;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="100" height="100">
Your browser doesn't include support for the canvas tag.
</canvas>
</body>
</html>
The problem is that you aren't waiting for the image to load when you call drawImage().
You could use something like:
logo.img.onload = function(){
c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height);
};
Although make sure you don't start modifying the canvas until this has happened.