I am reading through "Making Isometric Social Real-Time Games with HTML5, CSS3 and Javascript."
I am not far into it, and I have run into a canvas problem that has ahd me stumped for most of the day.
drawImage() does not seem to be drawing. I have researched the issue and have tried many permutations of pre-loading the image, but so far nothing is working.
Here is my code:
HTML:
<canvas id="game" width="100" height="100">
Your browser doesn't include support for the canvas element.
</canvas>
CSS:
html {
height:100%;
overflow:hidden
}
body {
margin:0px;
padding:0px;
height:100%;
}
and js:
window.onload = function() {
var canvas = document.getElementById('game');
canvas.width=document.body.clientWidth;
canvas.height=document.body.clientHeight;
var c = canvas.getContext('2d');
function showIntro() {
var phrase = "Click or tap screen to start";
c.clearRect (0, 0, canvas.width, canvas.height);
var grd = c.createLinearGradient(0, 0, canvas.width, canvas.height);
grd.addColorStop(0, "#9db7a0");
grd.addColorStop(1, "#e6e6e6");
c.fillStyle = grd;
c.fillRect (0, 0, canvas.width, canvas.height);
var logoImg = new Image();
logoImg.src = '../img/logo.png';
var originalWidth = logoImg.width;
logoImg.width = Math.round((50 * document.body.clientWidth) / 100);
logoImg.height = Math.round((logoImg.width * logoImg.height) / originalWidth);
var logo = {
img: logoImg,
x: (canvas.width/2) - (logoImg.width/2),
y: (canvas.height/2) - (logoImg.height/2)
}
c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height);
c.font = "bold 16px sans-serif";
var mt = c.measureText(phrase);
var xcoord = (canvas.width / 2 ) - (mt.width / 2);
c.fillStyle = '#656565'
c.fillText (phrase, xcoord, 30);
}
showIntro();
}
Any help would be appreciated!
You almost have it...
You just have to give the image time to load before drawing it.
You give an image time to load with this code:
var logoImg = new Image();
logoImg.onload = function() {
// At this point, the image is fully loaded
// So do your thing!
};
logoImg.src = "myPic.png";
Here is complete code and a Fiddle: http://jsfiddle.net/m1erickson/GKK39/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var c=canvas.getContext("2d");
function showIntro() {
var phrase = "Click or tap screen to start";
var logoImg=new Image();
logoImg.onload=function(){
c.clearRect (0, 0, canvas.width, canvas.height);
var grd = c.createLinearGradient(0, 0, canvas.width, canvas.height);
grd.addColorStop(0, "#9db7a0");
grd.addColorStop(1, "#e6e6e6");
c.fillStyle = grd;
c.fillRect (0, 0, canvas.width, canvas.height);
var originalWidth = logoImg.width;
logoImg.width = Math.round((50 * document.body.clientWidth) / 100);
logoImg.height = Math.round((logoImg.width * logoImg.height) / originalWidth);
var logo = {
img: logoImg,
x: (canvas.width/2) - (logoImg.width/2),
y: (canvas.height/2) - (logoImg.height/2)
}
c.drawImage(logo.img, logo.x, logo.y, logo.img.width, logo.img.height);
c.font = "bold 16px sans-serif";
var mt = c.measureText(phrase);
var xcoord = (canvas.width / 2 ) - (mt.width / 2);
c.fillStyle = '#656565'
c.fillText (phrase, xcoord, 30);
}
logoImg.src="http://dl.dropbox.com/u/139992952/car.png";
}
showIntro();
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
A simplified version of the above answer.
//Create Canvas
var canvas = document.createElement("canvas");
canvas.width = 720
canvas.height = 500;
//Get Context
var ctx = canvas.getContext("2d");
ctx .fillStyle = "black";
ctx .fillRect(0, 0, canvas.width, canvas.height);
//Load Image
var img = new Image();
img.src = "https://images.pexels.com/photos/3722151/pexels-photo-3722151.jpeg";
img.onload = function() {
ctx .drawImage(
img,
0,
0,
canvas.width,
canvas.height
);
};
//Add Canvas
canvas.id = "fatLady";
document.body.appendChild(canvas);
Try it on CodePen
https://codepen.io/hiteshsahu/pen/QWjrygb?editors=1111
Related
Hi i have problem with the tag Canvas.
I'm using bootstrap and i want create a canvas with an image where i can draw a dots after click with the mouse but because i'm using bootstrap the canvas area stretch and the dots are not in the same place i have click with the mouse
$().ready(function() {
showImage();
$("#image").click(function(e) {
getMousePositionAtClick(e);
});
function showImage() {
var canvas = document.getElementById('image');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'images/Piantina.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
};
}
function getMousePositionAtClick(e) {
var rect = image.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
alert(rect.left);
alert(rect.top);
drawPoint(x, y);
}
function drawPoint(x, y) {
var ctx = document.getElementById("image").getContext("2d");
ctx.fillStyle = "#000";
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2, true);
ctx.fill();
}
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-lg-8" id="columnCanvas">
<div class="card card-body">
<canvas id="image"></canvas>
</div>
</div>
As mentioned in comments above, a Canvas element is not responsive. Bootstrap on the other hand is meant to be responsive,. So to stop the scaling we can set the size. Looking at the spec for Canvas, the default size if not specified is 300px / 150px.. So in theory if we just set the Canvas CSS size to 300px/150px, this will also prevent the scaling, below is an example.
$().ready(function() {
showImage();
$("#image").click(function(e) {
getMousePositionAtClick(e);
});
function showImage() {
var canvas = document.getElementById('image');
var ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'images/Piantina.jpg';
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height);
};
}
function getMousePositionAtClick(e) {
var rect = image.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
alert(rect.left);
alert(rect.top);
drawPoint(x, y);
}
function drawPoint(x, y) {
var ctx = document.getElementById("image").getContext("2d");
ctx.fillStyle = "#000";
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2, true);
ctx.fill();
}
});
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-lg-8" id="columnCanvas">
<div class="card card-body">
<canvas id="image" style="width:300px;height:150px"></canvas>
</div>
</div>
I'm programming a canvas image to be able to zoom in/out after the control button is clicked.
The red ball normal size is 128x128px. when Zooming in too much...the image is clipped by its own container...how do I fix this?
working fiddle https://jsfiddle.net/vf8gvq7m/27/
This is what I've tried...
I want the zoom in to be correct without clipped image...
let M_GlassesZoom=1;
let L_GlassesZoom=1;
$('.ZoomGlasses').on("click",function(event) {
if($(this).hasClass("ZoomGlassesPlus")){
M_GlassesZoom+=0.5;
}
else if($(this).hasClass("ZoomGlassesLess")){
L_GlassesZoom+=0.5;
}
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 = 'blue';
ctx.fillRect(0,0,canvas.width, canvas.height);
var GlassesWidth=128;
var GlassesHeight=128;
if(M_GlassesZoom!=1){
GlassesWidth=GlassesWidth/M_GlassesZoom;
GlassesHeight=GlassesHeight/M_GlassesZoom;
}
if(L_GlassesZoom!=1){
GlassesWidth=GlassesWidth*L_GlassesZoom;
GlassesHeight=GlassesHeight*L_GlassesZoom;
}
ctx.drawImage(ImgGlasses, 0, 0, GlassesWidth, GlassesHeight, 50, 50, 128,128);
}
drawMe();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<button class="ZoomGlasses ZoomGlassesPlus">zoom +</button>
<button class="ZoomGlasses ZoomGlassesLess">zoom -</button><br/>
<canvas id="cv"></canvas>
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/Japan_small_icon.png" style="height:70px;width:70px;opacity:0" height=70 width=70 id="glasses" />
You have the destination width/height fixed to 128px so when the ball gets bigger than that it will get clipped. Naturally, the source width and height should be fixed and the destination calculated.
let M_GlassesZoom=1;
let L_GlassesZoom=1;
$('.ZoomGlasses').on("click",function(event) {
if($(this).hasClass("ZoomGlassesPlus")){
M_GlassesZoom+=0.5;
}
else if($(this).hasClass("ZoomGlassesLess")){
L_GlassesZoom+=0.5;
}
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 = 'blue';
ctx.fillRect(0,0,canvas.width, canvas.height);
var GlassesWidth=128;
var GlassesHeight=128;
if(M_GlassesZoom!=1){
GlassesWidth=GlassesWidth/M_GlassesZoom;
GlassesHeight=GlassesHeight/M_GlassesZoom;
}
if(L_GlassesZoom!=1){
GlassesWidth=GlassesWidth*L_GlassesZoom;
GlassesHeight=GlassesHeight*L_GlassesZoom;
}
ctx.drawImage(ImgGlasses, 0, 0, 128,128, 50, 50, GlassesWidth, GlassesHeight);
}
drawMe();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<button class="ZoomGlasses ZoomGlassesPlus">zoom +</button>
<button class="ZoomGlasses ZoomGlassesLess">zoom -</button><br/>
<canvas id="cv"></canvas>
<img src="https://upload.wikimedia.org/wikipedia/commons/d/d5/Japan_small_icon.png" style="height:70px;width:70px;opacity:0" height=70 width=70 id="glasses" />
I'm using the multiply value for the globalCompositeOperation property to apply a tint to a clipped region of an image. It works, but the bottom edge of the image sometimes gets a white border.
// Code goes here
document.addEventListener("DOMContentLoaded", function() {
var canvas = document.getElementById('myCanvas');
var img = new Image();
img.onload = function() {
render();
}
img.src = 'http://i.imgur.com/qiJkgK9.jpg';
function render() {
canvas.width = img.width * 2;
canvas.height = img.height * 2;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
ctx.save();
ctx.beginPath();
ctx.rect(200, 200, 200, 200);
ctx.clip();
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = 'red';
ctx.fill();
ctx.restore();
ctx.save();
ctx.beginPath();
ctx.rect(300, 100, 200, 200);
ctx.clip();
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = 'red';
ctx.fill();
ctx.restore();
}
});
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
How to prevent the border from appearing OR is there a better way to apply multiply tint to an image?
You can just use fillRect to the exact rectangle you're looking for instead of clip and fill, which is causing your clipping issue.
var canvas = document.getElementById('myCanvas');
function render() {
canvas.width = img.width * 2;
canvas.height = img.height * 2;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = 'red';
ctx.fillRect(200, 200, 200, 200);
ctx.fillRect(300, 100, 200, 200);
}
var img = new Image();
img.onload = render;
img.src = 'http://i.imgur.com/qiJkgK9.jpg';
<canvas id="myCanvas"></canvas>
i write a canvas rotate image and trying to add drop shadows.
anyone can help me to how i can add a different shadow style for images inside canvas. i need drop shadows like as this image for result :
enter image description here
context.shadowColor = "rgba( 0, 0, 0, 0.3 )";
context.shadowOffsetX = 6;
context.shadowOffsetY = 6;
context.shadowBlur = 3;
context.drawImage( brolly, 25, 250 );
full code :
window.addEventListener("load", init);
var canvas = document.getElementById('c');
canvas.width = 360;
canvas.height = 360;
var context = canvas.getContext('2d');
var counter = 0;
var logoImageh = new Image();
logoImageh.src = 'http://sirati.info/tmp/h.png';
var logoImagem = new Image();
logoImagem.src = 'http://sirati.info/tmp/m.png';
TO_RADIANS = Math.PI / 180;
function init() {
setInterval(loop, 100 / 30);
}
function loop() {
context.clearRect(0, 0, canvas.width, canvas.height);
drawRotatedImage(logoImageh, 180, 180, counter++);
drawRotatedImage(logoImagem, 180, 180, counter++);
counter += 1;
}
function drawRotatedImage(image, x, y, angle) {
context.save();
context.translate(x, y);
context.rotate(angle * TO_RADIANS);
context.drawImage(image, -(image.width / 2), -(image.height / 2));
context.restore();
}
body {
margin: 0px;
padding: 0px;
text-align: center;
}
canvas {
outline: 0;
border: 1px solid #000;
margin-left: auto;
margin-right: auto;
}
<html>
<head>
<title>Simple</title>
</head>
<body>
<canvas id='c'></canvas>
</body>
</html>
i write
Add shadows to your images using in-memory canvases.
Then drawImage those in-memory canvases instead of the images. Yes, drawImage can draw other canvases as well as images!
[Addition: example code using question's code as a basis]
var canvas = document.getElementById('c');
canvas.width = 360;
canvas.height = 360;
var context = canvas.getContext('2d');
var counter = 0;
TO_RADIANS = Math.PI / 180;
var nextTime=0;
var delay=1000/60*2;
var logoImageh = new Image();
logoImageh.onload=start;
logoImageh.src = 'http://sirati.info/tmp/h.png';
var logoImagem = new Image();
logoImagem.onload=start;
logoImagem.src = 'http://sirati.info/tmp/m.png';
var imageCount=2;
//
function start(){
canvasLogoImageh=addShadowToImage(logoImageh);
canvasLogoImagem=addShadowToImage(logoImagem);
requestAnimationFrame(loop);
}
function addShadowToImage(img){
var c=document.createElement('canvas');
var cctx=c.getContext('2d');
c.width=img.width;
c.height=img.height;
cctx.shadowColor='black';
cctx.shadowBlur=10;
cctx.drawImage(img,0,0);
return(c);
}
function loop(time) {
if(time<nextTime){requestAnimationFrame(loop);return;}
nextTime=time+delay;
context.clearRect(0, 0, canvas.width, canvas.height);
drawRotatedImage(canvasLogoImageh, 180, 180, counter++);
drawRotatedImage(canvasLogoImagem, 180, 180, counter++);
counter += 0.25;
requestAnimationFrame(loop);
}
function drawRotatedImage(image, x, y, angle) {
context.save();
context.translate(x, y);
context.rotate(angle * TO_RADIANS);
context.drawImage(image, -(image.width / 2), -(image.height / 2));
context.restore();
}
body{ background-color: ivory; }
canvas{border:1px solid red; margin:0 auto; }
<canvas id="c" width=300 height=300></canvas>
What needs to be done:
The pink object should move from the left to the right (by itself). And then when it's 5px from the edge it should rotate 90 degrees.
Does anyone know how to do this?
I haven't been learning javascript for a long time, and it's the first time I'm creating something using HTML5. So it's all new. I really hope you can help me understand the code better and how I can make it move and rotate.
<!DOCTYPE html>
<html>
<head>
<script>
var canvas, ctx;
window.onload = function draw() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
var height = 90;
var width = 40;
var radius = width / 2;
ctx.clearRect(0,0, canvas.width, canvas.height);
ctx.fillStyle = "#FFE2E8";
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.moveTo(20,20);
ctx.lineTo(70,20);
ctx.arc(70,40,20, -Math.PI/2, Math.PI/2);
ctx.lineTo(20,60);
ctx.lineTo(20,20);
ctx.closePath;
ctx.fill();
ctx.stroke();
requestAnimationFrame(draw);
}
function init() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
draw();
}
</script>
</head>
<body>
<canvas id="myCanvas" width="400" height="300" style="background:#00CC66">
</canvas>
</body>
</html>
var canvas, ctx;
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
var radius = 20;
var width = 70;
var margin = 5;
var offsetx = -20
var translate = {
x: 0,
y: 0,
xmax: canvas.width - margin - width + offsetx,
ymax: canvas.height - margin - width
};
var rotate = 0;
var to_radians = Math.PI / 180;
function draw() {
ctx.save();
ctx.translate(translate.x, translate.y);
if (translate.x >= translate.xmax) {
translate.x = translate.xmax;
if (rotate >= 90) {
rotate = 90;
} else {
rotate++;
}
ctx.rotate(rotate * to_radians);
} else {
translate.x++;
}
var height = 90;
var width = 40;
var radius = width / 2;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#FFE2E8";
ctx.strokeStyle = "black";
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(70, 20);
ctx.arc(70, 40, 20, -Math.PI / 2, Math.PI / 2);
ctx.lineTo(20, 60);
ctx.lineTo(20, 20);
ctx.closePath;
ctx.fill();
ctx.stroke();
ctx.restore();
requestAnimationFrame(draw);
}
function init() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
draw();
}
init();
<canvas id="myCanvas" width="400" height="300" style="background:#00CC66">
</canvas>