I'm trying to create a canvas animation using the following image..
Please check the link. https://i.stack.imgur.com/Pv2sI.jpg
Like normal animation I'm trying to run this sprite sheet image but I'm failing somewhere.
Here is my code -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Untitled Document</title>
</head>
<body>
<canvas id='canvas'></canvas><br />
<button onclick='moveLeft()'>Left</button>
<button onclick='moveRight()'>Right</button>
<script>
var canvasWidth = 650;
var canvasHeight = 350;
var spriteWidth = 379;
var spriteHeight = 133;
var rows = 2;
var cols = 8;
var trackRight = 0;
var trackLeft = 1;
var width = spriteWidth/cols;
var height = spriteHeight/rows;
var curFrame = 0;
var frameCount = 8;
var x=0;
var y=200;
var srcX;
var srcY;
var left = false;
var right = true;
var speed = 12;
var canvas = document.getElementById('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
var ctx = canvas.getContext("2d");
var character = new Image();
character.src = "jpg.jpg";
function updateFrame(){
curFrame = ++curFrame % frameCount;
srcX = curFrame * width;
ctx.clearRect(x,y,width,height);
if(left && x>0){
srcY = trackLeft * height;
x-=speed;
}
if(right && x<canvasWidth-width){
srcY = trackRight * height;
x+=speed;
}
}
function draw(){
updateFrame();
ctx.drawImage(character,srcX,srcY,width,height,x,y,width,height);
}
function moveLeft(){
left = true;
right = false;
}
function moveRight(){
left = false;
right = true;
}
setInterval(draw,100);
</script>
</body>
</html>
But this doesn't seems to work properly. It running in weird state. like only the center area of the image. What Can I do?
Your spritesheet isn't done correctly, each steps has to be the same width otherwise you'll get a shift in your animation.
Moreover, you can animate a spritesheet using css only.
I took this spritesheet for the example : https://www.codeandweb.com/o/blog/2016/05/10/how-to-create-a-sprite-sheet/spritestrip-1536.png
<body>
<style>
#animSheet {
background-image: url("spritesheet.png");
width: 256px;
height: 256px;
animation: animSheet 1s steps(6) infinite;
}
#keyframes animSheet {
0% {
background-position: 1536px;
}
100% {
background-position: 0px;
}
}
</style>
<div id="animSheet"></div>
Related
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>
As the title says when i try to draw more then 1 image a something weird happens. while it does draw stuff in the correct locations at the correct sizes it only ends up using the last drawn image. So i end up getting the same image 3 times at different locations and sizes while they are supposed to be different images.
This is my code:
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>HTML5 Canvas</title>
<script src="jquery-3.2.1.js"></script>
<script src="main.js"></script>
</head>
<style>
#canvas:hover
{
/*cursor: none;*/
}
#canvas
{
}
body
{
margin: 0;
}
</style>
<body>
<form action="index.php" method="post" enctype="multipart/form-data">
<canvas id="canvas"></canvas>
</form>
</body>
</html>
Javascript:
$(document).ready(function(){
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var keys = [];
var framerate = 1000/60;
var img = new Image();
var x = innerWidth/2 - 150;
var y = innerHeight/2 - 75;
var speed = 10;
var imageArray =
[
"sky.png",
"road.png",
"car.png"
];
function drawMap()
{
img.src = imageArray[0];
ctx.drawImage(img,0,0,innerWidth,innerHeight/2);
console.log("Sky Finished Drawing");
img.src = imageArray[1];
ctx.drawImage(img,0,innerHeight/2,innerWidth,innerHeight/2);
console.log("Road Finished Drawing");
img.src = imageArray[2];
ctx.drawImage(img,x,y,300,150);
console.log("Car Finished Drawing");
}
drawMap();
var mouse = {
x : undefined,
y : undefined
}
window.addEventListener("keydown",function(e){
keys[e.keyCode] = true;
});
window.addEventListener("keyup",function(e){
keys[e.keyCode] = false;
});
setInterval(animate,framerate);
function animate()
{
if(keys[87]) //W
{
ctx.clearRect(0,0,innerWidth,innerHeight);
drawMap();
console.log("W");
y -= speed;
}
if(keys[65]) //A
{
ctx.clearRect(0,0,innerWidth,innerHeight);
drawMap();
console.log("A");
x -= speed;
}
if(keys[83]) //S
{
ctx.clearRect(0,0,innerWidth,innerHeight);
drawMap();
console.log("S");
y += speed;
}
if(keys[68]) //D
{
ctx.clearRect(0,innerHeight/2,innerWidth,innerHeight);
drawMap();
x += speed;
console.log("D");
}
}
});
You created one Image object and used the same one for each src, so it applied only the last image source.
Please create Image object for each image:
function drawMap()
{
var img1 = new Image();
img1.src = imageArray[0];
ctx.drawImage(img1,0,0,innerWidth,innerHeight/2);
console.log("Sky Finished Drawing");
var img2 = new Image();
img2.src = imageArray[1];
ctx.drawImage(img2,0,innerHeight/2,innerWidth,innerHeight/2);
console.log("Road Finished Drawing");
var img3 = new Image();
img3.src = imageArray[2];
ctx.drawImage(img3,x,y,300,150);
console.log("Car Finished Drawing");
}
Lately I learned a bit about strange attractors, and I created the following programm in JS:
var ctx, clock, width, height, pixSize;
var x,y,a,b,c,d;
window.onload = function(){
start();
};
function start(random=true){
window.cancelAnimationFrame(clock);
if(random){
a = 6*Math.random()-3;
b = 6*Math.random()-3;
c = 2*Math.random()-0.5;
d = 2*Math.random()-0.5;
}
canvasSetup();
clearCanvas();
x = Math.random()-Math.random();
y = Math.random()-Math.random();
clock = requestAnimationFrame(main);
}
function save(){
var text = JSON.stringify({
a:a,
b:b,
c:c,
d:d
});
window.prompt("Copy to clipboard: Ctrl+C", text);
}
function load(){
var input = JSON.parse(window.prompt("Import Save:"));
a = input.a;
b = input.b;
c = input.c;
d = input.d;
start(false);
}
function canvasSetup(){
canvas = document.getElementById('canvas');
width = window.innerWidth-5;
height = window.innerHeight-5;
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext('2d');
var min = Math.min(width,height);
var scale = min/4;
ctx.translate(width/2, height/2);
ctx.scale(scale, scale);
pixSize = 1/scale/2;
ctx.globalCompositeOperation = "lighter";
}
function clearCanvas(){
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0,0,width,height);
ctx.restore();
}
function main(){
for(var i=0;i<10000;i++){
var xnew = Math.sin(y*b)+c*Math.sin(x*b);
var ynew = Math.sin(x*a)+d*Math.sin(y*a);
x = xnew;
y = ynew;
plot(x,y,"rgb(50,5,1)");
}
clock = requestAnimationFrame(main);
}
function plot(x,y,color="white"){
ctx.fillStyle = color;
ctx.fillRect(x,-y,pixSize,pixSize);
}
body {
background-color: black;
color: white;
font-family: Consolas;
font-size: 13px;
margin: 0;
padding: 0;
}
#buttons{
position: absolute;
top: 0;
left: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Strange Attractor</title>
<link rel="stylesheet" href="style.css">
<script src="rules.js"></script>
<script src="script.js"></script>
</head>
<body>
<div align="center">
<canvas id="canvas"></canvas>
</div>
<div id="buttons">
<button onclick="start()">New Attractor</button><br>
<button onclick="save()">Save</button><br>
<button onclick="load()">Load</button>
</div>
</body>
</html>
It's taking 4 random Parameters (a,b,c,d) and uses the formular
var xnew = Math.sin(y*b)+c*Math.sin(x*b);
var ynew = Math.sin(x*a)+d*Math.sin(y*a);
x = xnew;
y = ynew;
for the new point. In some cases this indeed creates a fancy strange sttractor:
But in other cases I only get a single line or a few points. Is there a simple way to look at the parameters and find out, if the attrator they create will be strange?
I know, that I could save a bunch of values, compare them with each other and test in that way, if the picture might be intresting, but I'd love a different solution...
I hope you can help :)
EDIT:
To look at speccific values you can simply use the save and load buttons in the js sketch above...
I've seen this question asked many times here already, but no replies to those posts helped me out: I'm trying to load a Sprite using the PixiJS engine, but it's not showing up despite it being recognised and loggable using console.log(). What am I doing wrong?
I've followed the tutorial from this URL:
https://github.com/kittykatattack/learningPixi#introduction
My code is as follows:
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TITLE HERE</title>
<link rel='stylesheet' type='text/css' href='style/style.css'>'
<script src="js/pixi.min.js"></script>
<script src="js/init.js"></script>
</head>
<body>
<script>
init();
</script>
</body>
</html>
init.js
var sprites = {};
var stage = new PIXI.Container();
var renderer;
function init(){
createCanvas(288, 288, true);
}
function createCanvas(width, height, autoResize){
//Create the renderer
renderer = PIXI.autoDetectRenderer(width, height);
renderer.autoResize = autoResize;
renderer.view.setAttribute("id", "canvas");
//Add the canvas to the HTML document
document.body.appendChild(renderer.view);
newSprite("assets/tilesheet.png", "tilesheet");
}
function newSprite(src, name){
var texture = PIXI.Texture.fromImage(src);
var sprite = new PIXI.Sprite(texture);
sprites[name] = sprite;
stage.addChild(sprites["tilesheet"]);
renderer.render(stage);
}
And just in case
style.css
body{
background-color: #a9a9a9;
}
#canvas{
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 0;
margin: auto;
display: block;
position: absolute;
box-shadow: 0.5em 0.5em 0 0 #777;
}
/* <TABLET> */
#media (min-width: 61.5rem){
#canvas{
width: 25em;
height: 25em;
box-shadow: 1em 1em 0 0 #777;
}
}
/* <DESKTOP/TV> */
#media (min-width: 80.0rem){
}
This is my folder layout:
Project
|-assets
| \-tilesheet.png
|-js
| |-init.js
| \-pixi.min.js
|-style
| \-style.css
|-index.html
I hope someone can help me out.
UPDATE
The code now works as it should. Based on feedback by themoonrat (accepted answer), the code now looks like this:
var sprites = {};
var masks = {};
var stageWidth = 288;
var stageHeight = 288;
var spriteWidth = 32;
var spriteHeight = 32;
var gridWidth = stageWidth/spriteWidth;
var gridHeight = stageHeight/spriteHeight;
var stage = new PIXI.Container();
var renderer = PIXI.autoDetectRenderer(stageWidth, stageHeight);
function init(){
renderer.view.setAttribute("id", "canvas");
document.body.appendChild(renderer.view);
for(var x = 0; x < gridWidth; x++){
for(var y = 0; y < gridHeight; y++){
newSprite('assets/tilesheet.png', 'tilesheet'+(x+y), x*spriteWidth, y*spriteHeight);
}
}
sprites['tilesheet2'].position.x = 32;
sprites['tilesheet2'].position.y = -32;
console.log(sprites);
// start updating
update();
}
function newSprite(src, name, x, y){
var texture = PIXI.Texture.fromImage(src);
var sprite = new PIXI.Sprite(texture);
sprite.anchor.x = 0;
sprite.anchor.y = 0;
sprite.position.x = x;
sprite.position.y = y;
sprites[name] = sprite;
stage.addChild(sprite);
}
function update() {
requestAnimationFrame(update);
renderer.render(stage);
}
The main difference is the inclusion of the update() function. Where, as themoonrat suggested, the requestAnimationFrame() is situated
You are only rendering the screen once, and the manner in which you are using pixi is to let pixi request to load the image rather than supplying a preloaded image.
So the point at which you render, just after creating the sprite, the request to load the image has only just occurred. Pixi can't render a sprite with a texture that hasn't finished loading.
If you put the render part within a contently called requestAnimationFrame , then the image would be rendered as soon as it had loaded.
I need a little help about canvas and HTML5.
I have this code
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>HTML Canvas Flag Wave</title>
<style type="text/css" media="screen">
body { background:#eee }
#flag { position:absolute; top:50%; left:50% }
</style>
<script type="text/javascript">
var h = new Image;
h.onload = function(){
var flag = document.getElementById('flag');
var amp = 20;
flag.width = h.width;
flag.height = h.height + amp*2;
flag.getContext('2d').drawImage(h,0,amp,h.width,h.height);
flag.style.marginLeft = -(flag.width/2)+'px';
flag.style.marginTop = -(flag.height/2)+'px';
var timer = waveFlag( flag, h.width/10, amp );
};
h.src = 'gkhead.jpg';
function waveFlag( canvas, wavelength, amplitude, period, shading, squeeze ){
if (!squeeze) squeeze = 0;
if (!shading) shading = 100;
if (!period) period = 200;
if (!amplitude) amplitude = 10;
if (!wavelength) wavelength = canvas.width/10;
var fps = 30;
var ctx = canvas.getContext('2d');
var w = canvas.width, h = canvas.height;
var od = ctx.getImageData(0,0,w,h).data;
// var ct = 0, st=new Date;
return setInterval(function(){
var id = ctx.getImageData(0,0,w,h);
var d = id.data;
var now = (new Date)/period;
for (var y=0;y<h;++y){
var lastO=0,shade=0;
var sq = (y-h/2)*squeeze;
for (var x=0;x<w;++x){
var px = (y*w + x)*4;
var pct = x/w;
var o = Math.sin(x/wavelength-now)*amplitude*pct;
var y2 = y + (o+sq*pct)<<0;
var opx = (y2*w + x)*4;
shade = (o-lastO)*shading;
d[px ] = od[opx ]+shade;
d[px+1] = od[opx+1]+shade;
d[px+2] = od[opx+2]+shade;
d[px+3] = od[opx+3];
lastO = o;
}
}
ctx.putImageData(id,0,0);
// if ((++ct)%100 == 0) console.log( 1000 * ct / (new Date - st));
},1000/fps);
}
</script>
</head>
<body>
<canvas id="flag"></canvas>
</body>
</html>
The result is this:
http://www.americkiplakari.org/zastavanovo.html
Nice waving flag, but I have a problem, I'm not so good with canvas. I want to rotate canvas, I want to top of image be fixed and waves goes from top to bottom, is it possible to do that.
Ok here is simple solution, just rotate with CSS3, put canvas in another div and you are ready to go go....
<style type="text/css" media="screen">
body { background:#eee }
#flagunustra { position:absolute; top:50%; left:50% }
#flag{
margin-top:250px;
width:414px;
transform:rotate(90deg);
-ms-transform:rotate(90deg); /* IE 9 */
-moz-transform:rotate(90deg); /* Firefox */
-webkit-transform:rotate(90deg); /* Safari and Chrome */
-o-transform:rotate(90deg); /* Opera */
}
</style>
<div id="flagunustra">
<canvas id="flag"></canvas></div>