I have a .js file with a simple animation that I'd like to use as a website's background. I'm able to put it onto the page and all that- but the text appears below the animation instead of over it. I've tried looking up solutions but all I've been able to find is instructions for making setting a .png/.jpg as the background. I'm very new to programming, so I haven't the slightest idea how I'd do this. Thanks for any help.
EDIT: Here's the code I'm trying to use!
<!DOCTYPE html>
<html>
<head>
<title>Scrolling Page</title>
</head>
<body style="background-color: black;">
<canvas id="canvas1"></canvas>
<h1>Text</h1>
<p>text</p>
</body>
</html>
<script src="mainscript.js"></script>
mainscript.js is:
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
can.width = 9200;
can.height = 630;
var img = new Image();
img.src = "tempimage.png";
window.onload = function() {
var imgWidth = 0;
var scrollSpeed = 10;
function loop()
{
ctx.drawImage(img, imgWidth, 0);
ctx.drawImage(img, imgWidth - can.width, 0);
imgWidth -= scrollSpeed;
if (-imgWidth == can.width)
imgWidth = 0;
window.requestAnimationFrame(loop);
}
loop();
Because we're not talking about using just a picture as a background and instead an HTML canvas element that is being animated, you'll need to use CSS to layer the canvas element that you want to use as a background behind the rest of the page content. To do that, you can position the background element with position:absolute and then place it behind everything else with z-index:-1.
<!DOCTYPE html>
<html>
<head>
<title>Scrolling Page</title>
<style>
#canvas1 {
position:absolute; /* Take the element out of the normal document flow */
z-index:-1; /* Place the element behind normal content */
top:0; /* Start at top of viewport */
left:0; /* Start at left edge of viewport */
}
</style>
</head>
<body>
<canvas id="canvas1"></canvas>
<h1>Text</h1>
<p>text</p>
<script>
var can = document.getElementById("canvas1");
var ctx = can.getContext('2d');
can.width = 9200;
can.height = 630;
var img = new Image();
img.src = "https://cdn.pixabay.com/photo/2019/02/19/19/45/thumbs-up-4007573__340.png";
window.onload = function() {
var imgWidth = 0;
var scrollSpeed = 10;
function loop() {
ctx.drawImage(img, imgWidth, 0);
ctx.drawImage(img, imgWidth - can.width, 0);
imgWidth -= scrollSpeed;
if (-imgWidth == can.width) {
imgWidth = 0;
}
window.requestAnimationFrame(loop);
}
loop();
}
</script>
</body>
</html>
Related
I am currently having issues with displaying images in the HTML canvas. I am still new and I am quite tired so its likely theres somthing stupid I did not do. Heres the code:
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
canvas.height = 695;
canvas.width = 1515;
//Images
const BG = new Image();
BG.src = "C:\Users\MSI\Documents\ABGG Remastered\StartImg.png"
ctx.drawImage(BG, 0, 0);
<!DOCTYPE html>
<html>
<body>
<canvas id="canvas"></canvas>
<script src="C:\Users\MSI\Documents\ABGG Remastered\mainScript.js">
</script>
<style>
canvas {
border: 1px solid;
}
</style>
</body>
</html>
Thanks for the help!
Loading an image is not instantly so you need to wait for it to be loaded first which you can do with the onload function of the image
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
canvas.height = 695;
canvas.width = 1515;
//Images
const BG = new Image();
BG.src = "https://images3.alphacoders.com/899/thumb-1920-899727.jpg"
BG.onload = () => {ctx.drawImage(BG, 0, 0);}
<!DOCTYPE html>
<html>
<body>
<canvas id="canvas"></canvas>
<script src="C:\Users\MSI\Documents\ABGG Remastered\mainScript.js">
</script>
<style>
canvas {
border: 1px solid;
}
</style>
</body>
</html>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
canvas.height = 695;
canvas.width = 1515;
//Images
const BG = new Image();
BG.addEventListener('load', function() {
ctx.drawImage(BG, 20,20);
})
BG.src = "C:\\Users\\dhrum\\Documents\\Projects\\WizemenDesktop\\WizemenDesktop\\Assets\\icon.png"
</script>
I changed to code to this and it works. First of all, I'd recommend using a method to wait for the image to load, and then draw it (slow servers or large files can take a little to load, and hence wont be drawn if not loaded).
Second of all, your issue that that \ escapes the character, and you'd want to do \\, where the first \ will escape the 2nd \ which would make the actual value of the string with only 1 \.
To understand what escaping a character means, you can go here
I am trying to build a basic game and somehow got really hung up on the first few steps. I am trying to create a canvas, the the color of the canvas, and then append to a div element. Every time I load this I either get an error, or nothing. Even if the 2 console.logs load properly. Please help!
My HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Dodge</title>
<script src="//code.jquery.com/jquery.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.6/journal/bootstrap.min.css" rel="stylesheet" integrity="sha256-fHWoqb8bPKjLiC7AuV6qy/lt0hrzfwM0ciyAu7Haf5w= sha512-3t2GeiCRNeKhZnUaUMygGiLKZzb/vPhvfw3y1Rt2FCwKuRaLVrOCTpavIYsZ4xqM52mbO7M93NaXbm/9dOA2Og==" crossorigin="anonymous">
<script src="../../../game.js">
</script>
</head>
<body>
<center>
<h1 id="h1">Dodge the enemy by pressing the left and right arrow keys!</h1>
<button
id="play"
class="btn btn-primary">Play game!</button>
</br>
</br>
<button
id="again"
class="btn btn-primary">Play Again!</button>
<div id="play-area">
</div>
</center>
</body>
</html>`
And heres the JS:
$(function () {
function createCanvas(width, height, id) {
var canvas = document.createElement("canvas");
var id2 = "#" + id;
canvas.width = width;
canvas.height = height;
canvas.id = id;
$(id2).css("color", "lawngreen");
$("#game-area").append(canvas);
}
$("#play").click(function () {
console.log("hello");
createCanvas(900, 900, "game-canvas");
console.log("hi!");
});
});
First you create the canvas object correctly, but you should also append it to the body. This is done after basic parameters are set.
After that you can manipulate the css with jQuery.
It works in my fiddle.
Check it out here: https://jsfiddle.net/xu15q5h8/
I changed your code to point out how it correctly works:
$(function () {
function createCanvas(width, height, id) {
var canvas = document.createElement('canvas');
var body = document.getElementsByTagName("body")[0];
canvas.id = id;
canvas.width = width;
canvas.height = height;
body.appendChild(canvas);
$('canvas').css('background-color', 'rgba(158, 167, 184, 0.2)');
cursorLayer = document.getElementById("CursorLayer");
console.log(cursorLayer);
}
$("#play").click(function () {
console.log("hello");
createCanvas(900, 900, "game-canvas");
alert("hi!");
});
});
Why not just draw the color onto the canvas instead of using CSS.
function createCanvas(width, height, id) {
var canvas = document.createElement("canvas");
var id2 = "#" + id;
canvas.width = width;
canvas.height = height;
canvas.id = id;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "lawngreen";
ctx.fillRect (0, 0, width, height);
$("#play-area").append(canvas);
}
Here is the modified code demo.
I need to get the color of any pixel my mousepointer is currently hovering.
I found several solutions for canvas elements, but none for a background image defined in CSS for a element.
How can I achieve this?
Combining the answers from Get a CSS value with JavaScript and How to get a pixel's x,y coordinate color from an image?, I was able to simulate what you are looking for: JSFiddle
<html>
<head>
<style type="text/css">
#test {
background-image: url('http://jsfiddle.net/img/logo.png');
background-color: blue;
background-repeat: no-repeat;
height: 30px;
width: 100%;
}
#hidden {
display: none;
}
</style>
<script type="text/javascript">
var div = document.getElementById("test");
var style = window.getComputedStyle(div);
div.onmousemove = function(e) {
var path = style.getPropertyValue('background-image');
path = path.substring(4, path.length-1);
var img = document.getElementById("i1");
img.src = path;
var canvas = document.getElementById("c1");
canvas.width = img.width;
canvas.height = img.height;
canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);
var pixelData = canvas.getContext('2d').getImageData(event.offsetX, event.offsetY, 1, 1).data;
var values = document.getElementById("values");
values.innerHTML = 'R: ' + pixelData[0] + '<br>G: ' + pixelData[1] + '<br>B: ' + pixelData[2] + '<br>A: ' + pixelData[3];
};
</script>
</head>
<body>
<div id="test"></div>
<div id="hidden">
<img id="i1" src="" />
<canvas id="c1"></canvas>
</div>
<div id="values"></div>
</body>
</html>
I retrieved the computed style (var style = window.getComputedStyle(div);) outside of the mouse move function for performance reasons, but if the background image is going to change dynamically, then it may need to be moved into the function.
There are some possible browser constraints for using getComputedStyle.
SCALING
You could try editing the code to adjust for the scale:
var h = parseInt(style.getPropertyValue("width")),
w = parseInt(style.getPropertyValue("height"));
var img = document.getElementById("i1");
img.src = path;
var canvas = document.getElementById("c1");
canvas.width = h;
canvas.height = w;
canvas.getContext('2d').drawImage(img, 0, 0, w, h);
This also includes a change to the CSS: JSFiddle
This question about crossfading images already gave an answer to the crossfading solution in Canvas. I am trying to do the same thing, only difference is that i am trying to fade images that are loaded on runtime.
The images are loaded propperly but no fade is visible. Is this not working because of the loaded images? Thanks.
HTML
<div id="wrapper">
<canvas id="bg1"></canvas>
<canvas id="bg2"></canvas>
</div>
JS
var toggle = true;
var canvas = document.getElementById('bg1');
canvas.width = $(document).width();
canvas.height = $(document).height();
var ctx = canvas.getContext('2d');
var canvas2 = document.getElementById('bg2');
canvas2.width = $(document).width();
canvas2.height = $(document).height();
var ctx2 = canvas2.getContext('2d');
var image = new Image();
image.src = 'download1.jpg';
var image2 = new Image();
image2.src = 'download2.jpg';
image.onload = function() {
ctx.drawImage(image, 0, 0, 200, 100);
ctx2.drawImage(image2, 0, 0, 200, 100);
};
$('#wrapper').click(function () {
if (toggle)
{
$('#bg2').fadeIn();
$('#bg1').fadeOut();
}
else
{
$('#bg1').fadeIn();
$('#bg2').fadeOut();
}
toggle = !toggle;
});
Yep, you need to give your images time to load.
But also, jQuery cannot do fadeIn/fadeout on a canvas element so you will have to do that manually.
Demo: http://jsfiddle.net/m1erickson/zw9S4/
Code:
<!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(){
$("#fade").hide();
var imageURLs=[]; // put the paths to your images here
var imagesOK=0;
var imgs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-2.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg");
loadAllImages();
//
function loadAllImages(){
for (var i=0; i<imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
$("#fade").show();
ctx.drawImage(imgs[0],0,0);
}
};
img.onerror=function(){alert("image load failed");}
img.crossOrigin="anonymous";
img.src = imageURLs[i];
}
}
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var fadeOutIndex=imgs.length-1;
var fadeInIndex=0;
var fadePct=0;
function animateFade(){
if(fadePct>100){return;}
requestAnimationFrame(animateFade);
ctx.clearRect(0,0,canvas.width,canvas.height);
draw(imgs[fadeInIndex],fadePct/100);
draw(imgs[fadeOutIndex],(1-fadePct/100));
fadePct++;
}
function draw(img,opacity){
ctx.save();
ctx.globalAlpha=opacity;
ctx.drawImage(img,0,0);
ctx.restore();
}
$("#fade").click(function(){
fadePct=0;
if(++fadeOutIndex == imgs.length){fadeOutIndex=0;}
if(++fadeInIndex == imgs.length){fadeInIndex=0;}
animateFade();
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="fade">Fade to next Image</button><br>
<canvas id="canvas" width=204 height=204></canvas><br>
</body>
</html>
Try to fade in/out the images directly on the canvas instead of fading in and out the canvas elements (or there is not really any point using the canvas as you could use image elements instead).
First, of course, wait for the images to load:
var isBusy = false, /// for fade loop
count = 2; /// number of images to load
image = new Image();
image2 = new Image();
/// setup load handler
image.onload = image2.onload = handleLoad;
image.src = 'download1.jpg';
image2.src = 'download2.jpg';
function handleLoad() {
count--;
if (count === 0) {
/// when loaded draw a single image onto canvas
ctx.drawImage(image, 0, 0, ctx.canvas.width, ctx.canvas.height);
}
};
Now we can change the click handler a little bit around and use canvas only to do the fade in of the next image:
$('#wrapper').click(function () {
var img, /// current image to fade in
opacity = 0; /// current globalAlpha of canvas
/// if we're in a fade exit until done
if (isBusy) return;
isBusy = true;
/// what image to use
img = toggle ? image2 : image;
/// fade in
(function fadeIn() {
/// set alpha
ctx.globalAlpha = opacity;
/// draw image with current alpha
ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
/// increase alpha to 1, then exit resetting isBusy flag
opacity += 0.02;
if (opacity < 1)
requestAnimationFrame(fadeIn);
else
isBusy = false;
})();
toggle = !toggle;
});
Online demo
Hope this helps.
I want to make a responsive canvas using size in percentage and once user will resize the window the canvas adjust relatively.
I am able to scale the canvas by using below code but the only problem is as i scale the window size the mouse drawing disappear.
<style>
body{margin:0px;padding:0px;background:#a9a9a9;}
#main{
display:block;
width:80%;
padding:50px 10%;
height:300px;
}
canvas{display:block;background:#fff;}
</style>
</head>
<body>
<div id="main" role="main">
<canvas id="paint" width="100" height="100">
< !-- Provide fallback -->
</canvas>
</div>
<script>
var c = document.getElementById('paint');
var ctx = c.getContext('2d');
var x = null;
var y;
c.onmousedown = function(e){
x = e.pageX - c.offsetLeft;
y = e.pageY - c.offsetTop;
ctx.beginPath();
ctx.moveTo(x,y);
}
c.onmouseup = function(e){
x=null;
}
c.onmousemove = function(e){
if(x==null) return;
x = e.pageX - c.offsetLeft;
y = e.pageY - c.offsetTop;
ctx.lineTo(x,y);
ctx.stroke();
}
$(document).ready( function(){
//Get the canvas &
var c = $('#paint');
var container = $(c).parent();
//Run function when browser resizes
$(window).resize( respondCanvas );
function respondCanvas(){
c.attr('width', $(container).width() ); //max width
c.attr('height', $(container).height() ); //max height
//Call a function to redraw other content (texts, images etc)
}
//Initial call
respondCanvas();
});
</script>
Thanks.
Dealing with contents when resizing a canvas
If you resize the canvas, the drawn content is always erased. That's how canvas behaves.
You can either redraw the content after resizing or you can save the content as image data and restore after resizing (see canvas.toDataURL).
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/V6SVz/
<!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; padding:10px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// draw some content
ctx.lineWidth=3;
ctx.fillStyle="blue";
ctx.strokeStyle="red";
ctx.rect(50,50,100,50);
ctx.fill();
ctx.stroke();
ctx.font="14px Verdana";
ctx.fillStyle="white";
ctx.fillText("Scale Me",65,75);
function saveResizeAndRedisplay(scaleFactor){
// save the canvas content as imageURL
var data=canvas.toDataURL();
// resize the canvas
canvas.width*=scaleFactor;
canvas.height*=scaleFactor;
// scale and redraw the canvas content
var img=new Image();
img.onload=function(){
ctx.drawImage(img,0,0,img.width,img.height,0,0,canvas.width,canvas.height);
}
img.src=data;
}
$("#resizer").click(function(){ saveResizeAndRedisplay(1.5); });
}); // end $(function(){});
</script>
</head>
<body>
<button id="resizer">Click to resize the canvas</button><br/>
<canvas id="canvas" width=200 height=150></canvas>
</body>
</html>
c.attr('width', $(container).width() ); //max width
c.attr('height', $(container).height() ); //max height
the above code is equivalent to clearRect which is used to clear the canvas .so you cannot adjust the width and height if you want to retain what was drawn previously.
as a solution you can create a new canvas with required width and draw the content of previous canvas using drawImage(c) c is the canvas object .then you have to delete the canvas
I also had the same issue that your are facing in mu application, and after reading about it i came to this conclusion that the behavior of the canvas element is such that it clears itself after re-sizing, the only fix for this is to add a listener for the window re-size event and redraw the canvas when the event if fired.
$(window).resize(function(e) {
// function to redraw on the canvas
});
$(document).ready(function(e){
var c = $('#example'); // getting the canvas element
var ct = c.get(0).getContext('2d');
var container = $(c).parent();
$(window).resize( respondCanvas ); //handling the canvas resize
function respondCanvas(){
// makign the canvas fill its container
c.attr('width', $(container).width() ); //max width
c.attr('height', ($(container).height() -20 )); //max height
}
respondCanvas();
make_image('images/india.png',1,1);
}
Hope it helps.
Source
I've created a jQuery plugin that handles HTML5 canvas resizing. It was built to bridge the gap between mobile and desktop users. It is still a WIP but it is extensible, and has some basic drawing functions built in.
http://trsanders.github.io/responsive-sketchpad/
below is the code what I was trying to do:
<head>
<style>
#main {
display:block;
width:80%;
height:300px;
background:#e0e0e0;
}
canvas {
display:block;
background:#fff;
border:1px solid red;
}
</style>
<script>
$(function(){
var container=document.getElementById("main");
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// draw some content
//alert(canvas.width);
var w=$(container).width();
var h=$(container).height();
$(window).resize( saveResizeAndRedisplay );
function saveResizeAndRedisplay(){
// save the canvas content as imageURL
var data=canvas.toDataURL();
// resize the canvas
canvas.width = $(container).width();
canvas.height = $(container).height();
//alert($(container).width());
// scale and redraw the canvas content
var img=new Image();
img.onload=function(){
ctx.drawImage(img,0,0,img.width,img.height);
}
img.src=data;
}
saveResizeAndRedisplay();
});
</script>
</head>
<body>
<div id="main" role="main">
<canvas id="canvas" width=200 height=150></canvas>
</div>
<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = null;
var y;
canvas.onmousedown = function(e){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
ctx.beginPath();
ctx.moveTo(x,y);
}
canvas.onmouseup = function(e){
x=null;
}
canvas.onmousemove = function(e){
if(x==null) return;
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
ctx.lineTo(x,y);
ctx.stroke();
}
</script>
</body>
I use this method:
var context = document.getElementById('paint').getContext('2d');
var canvas = context.canvas;
function responsive(width){
var p = width / canvas.width;
canvas.width *= p;
canvas.height *= p;
var scaleFactor = context.scaleFactor || 1;
context.scale(p * scaleFactor, p * scaleFactor);
context.scaleFactor = p * scaleFactor;
}
var mq = window.matchMedia("(min-width: 735px)");
mq.addListener(applyChanges);
applyChanges();
function applyChanges(){
if(!mq)
responsive(350);
else
responsive(735);
}
I had the same problem. My solution is using CSS3's property zoom to the parent's container of the canvas:
<div id="parent_div">
<div id="constructor_div">
<canvas width="600" height="900">
</div>
</div>
<script>
constructor_zoom();
$(window).resize(function() {
constructor_zoom();
});
function constructor_zoom()
{
var parent_width = $('#parent_div').width();
var item_width = $('#constructor_div').width();
var coef = 0.1;
$('.constructor_image').css('zoom', parent_width/item_width - coef);
}
</script>
coef - coefficient to make indents of the canvas from the parent's borders. You may make it zero.
I hope it helps to somebody :-)