PixiJS Sprite not loading - javascript

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.

Related

Using variable font inside WEBGL canvas, p5 js

I have a WEBGL canvas in which I am loading a 3d model. I also have a text in variable font which I create with createP. The problem is that I need the text to be between the background and the 3d model. But I can only have the text in front of the canvas (on top of 3d model). Is there any way I can achieve this?
Ps. Creating the text with text() does not allow me to have variable weight value.
let kalameh;
var cnv;
let img;
function preload(){
img = loadImage('assets/lines.png');
kalameh = loadModel('kalameh.obj');
}
function setup() {
cnv = createCanvas(700, 700, WEBGL);
var x = (windowWidth - width) / 2;
var y = (windowHeight - height) / 2;
cnv.position(x, y);
wordA = createP('my text');
}
function draw() {
background(220, 220, 220);
wordA.style('font-size', '110px');
wordA.style('font-weight', '200');
wordA.style('font-stretch', '200%');
wordA.style('align', 'center');
wordA.position(40,25);
image(img, -1*windowWidth/2, -1*windowHeight/2, windowWidth, windowHeight);
translate (0,0,100);
pointLight(255,255,255, -350,0,400);
pointLight(255,255,255, 350,0,400);
ambientMaterial(255);
noStroke();
scale (0.25);
model(kalameh);
}
You could create two sketches (and thus two canvases) and assign z-index properties of -1 and 1 to make them foreground and background sketches, respectively. You can then sandwich the paragraph element that you created between the two canvases by giving it a z-index of 0. You can then make the foreground sketch transparent by calling clear() at the beginning of the draw loop.
In the code snippet below, the 3D object is in front of the text paragraph, whereas the white square of the "background" is behind the text.
let testP;
new p5(function(p){
p.setup = function() {
const foregroundCanvas = p.createCanvas(400, 400, p.WEBGL);
foregroundCanvas.id("foregroundSketch");
foregroundCanvas.position(0, 0);
p.normalMaterial();
testP = p.createP("In front of background / behind object ")
testP.position(95, 115);
testP.id("sandwichedParagraph")
p.angleMode(p.RADIANS)
}
p.draw = function() {
p.clear();
//drag to move the world.
// p.orbitControl();
p.push();
let rotateAngle = p.sin(p.frameCount/50);
p.rotateX(rotateAngle/2);
p.rotateY(-rotateAngle);
p.rotateZ(rotateAngle);
p.box(200, 100, 40);
p.pop();
}
}, "foregroundSketch");
new p5(function(p){
p.setup = function() {
const backgroundCanvas = p.createCanvas(400, 400);
// backgroundCanvas.parent("wrapper")
backgroundCanvas.position(0, 0);
backgroundCanvas.id("backgroundSketch")
p.noStroke();
}
p.draw = function() {
p.background(200);
let shiftAmount = p.map(p.sin(p.frameCount/60), -1, 1, 80, 310);
p.rect(shiftAmount, 120, 40, 40);
}
}, "backgroundSketch");
html, body {
margin: 0;
padding: 0;
}
/* The sketch with the white square has z-index of -1 (background!) */
#backgroundSketch {
z-index: -1;
position: absolute;
}
/* The <p> has z-index of 0 (sandwiched between both sketches)*/
#sandwichedParagraph {
z-index: 0;
position: absolute;
}
/* The sketch with the object has z-index of 1 (foreground!)*/
#foregroundSketch {
z-index: 1;
position: absolute;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>

How do I make multiple moving squares on a canvas?

So far I have made a moving square that when the button is clicked in the HTML file, calls the draw() function and draws a red square in the canvas area that moves accross the canvas. How do I make it so that the same function draw() can create multiple moving sqaures?
Here's the code so far:
var x = 10;
var y = 10;
function draw(){
var can = document.getElementById("myCanvas");
var ctx = can.getContext("2d");
var x = 1;
setInterval(function(){
ctx.clearRect(0,0, can.width, can.height);
ctx.fillRect(x, 20, 75, 75);
ctx.fillStyle ="red";
x=x+5;
}, 500
);
}
Not sure that my solution is good, I'm just starting to learn js, but hope it will helpful.
// variables declaration. I suggest to use Arrays
// for store individual rectangle parameters.
// rectangle start coords x and y
var rcx = [];
var rcy = [];
// delta to move x, y
var dx = [];
var dy = [];
// rectangle size (if you want it variable)
var size =[];
// init canvas
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// create and collect rectangles parameters
// on window load (here 100 rectangles created)
// with unique coords, deltas to move,
// and sizes for each rectangle.
window.onload = function() {
for (var i=0; i<100; i++) {
// in this solution all parameters randomized,
// but you can set whatever you want.
rcx[i]=(Math.floor(Math.random() * Math.floor(canvas.width)));
rcy[i]=(Math.floor(Math.random() * Math.floor(canvas.height)));
dx[i]= (Math.floor(Math.random() * Math.floor(3))-1);
dy[i]=(Math.floor(Math.random() * Math.floor(3))-1);
size[i] = (Math.floor(Math.random() * Math.floor(8)));
}};
// it is optional, but i decide
// made function for rectangle declaration.
// It will looks more compact when rendering.
function rect(x, y, size){
ctx.fillRect(x, y, size, size/2 );
ctx.fillStyle = "rgba(255,255,255,1)";
}
// finally all together into function draw()
function draw(){
setInterval(function(){
ctx.clearRect(0,0, canvas.width, canvas.height);
for (var j=0; j<100; j++) {
// read arrays
// render rectangle with params from arrays
rect(rcx[j],rcy[j],size[j]);
// add delta to move (x,y)
// and rewrite new coords to arrays
rcx[j]=rcx[j]+dx[j];
rcy[j]=rcy[j]+dy[j]};
}, 100
);
};
//rendering animation
draw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
#canvas {
width: 500px;
height: 500px;
background-color: #ccc;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="js1.js"></script>
</body>
</html>
Sorry, didn't mention about button. So for the btn changes are simple.
Create btn div in html,
Add listener on this div. Рut params in arrays if button is pushed. Instead of generation by random as it was in my solution before.
Read arrays and render all rectangles from it.
// variables declaration. I suggest to use Arrays for store individual rectangle parameters.
// rectangle start coords x and y
var rcx = [];
var rcy = [];
// delta to move x, y
var dx = [];
var dy = [];
// rectangle size (if you want it variable)
var size =[];
//counter for created rectangles
var i=0;
// init canvas
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// create and collect rectangles parameters on btn push
// with unique coords, deltas to move, and sizes for each rectangle.
var btn =document.getElementById('btn');
btn.addEventListener( 'click', function() {
//count every time you push the btn and create rect
i=i+1;
//generate rect params x,y, delta x, delta y, size
rcx[i]=20;
rcy[i]=20;
dx[i]=1
dy[i]=0
size[i] = 8;
});
// it is optional, but i decide made function for rectangle declaration. It will looks more compact when rendering.
function rect(x, y, size){
ctx.fillRect(x, y, size, size/1.5);
ctx.fillStyle = "red";
}
// finally all together into function draw()
function draw(){
setInterval(function(){
ctx.clearRect(0,0, canvas.width, canvas.height);
for (var j=1; j<rcx.length; j++) {
// read arrays
// render rectangle with params from arrays
rect(rcx[j],rcy[j],size[j]);
// add delta to move (x,y) and rewrite new coords to arrays
rcx[j]=rcx[j]+dx[j];
rcy[j]=rcy[j]+dy[j]};
}, 100
);
};
//rendering animation
draw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
body{
margin: 0 auto;
padding: 0;
background-color: rgb(17, 0, 28);
}
#container{
position: relative;
margin-top: 10px;
margin-left: 50px;
}
#canvas {
z-index: 0;
position:fixed;
align-self: center;
justify-self: center;
width: 80vw;
height: 50vw;
background-color: #ccc;
}
#btn {
margin: 20px 20px 20px 0px;
padding: 10px;
position:static;
top: 30px;
font-family: 'Roboto', sans-serif;
width: 65px;
background-color: brown;
cursor: pointer;
}
#btn:hover {
background-color: red;
}
#btn:active {
background-color: coral;
}
</style>
</head>
<body>
<div id="container">
<div id="btn"> Push me </div>
<canvas id="canvas"></canvas>
</div>
<script src="js1.js"></script>
</body>
</html>

How can I check if an attractor is strange?

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...

How might I create a magnifying glass effect to magnify elements in a three.js or babylon.js 3d scene?

For quite a while now I've been trying to find a way to create a magnifying glass effect that will follow the mouse and magnify elements in a scene. Something like a rifle scope. Any ideas where to start?
Naturally, after formulating the question a solution occurred to me. Though, unfortunately, it isn't the native babylon.js solution I was looking for it still works. It uses divs and jquery to allow magnification of the source image that's used as a material on a plane within the 3D space.
The trick is in the 'overtarget' function where the mouse position over the target, having been converted to its percentage of the image's height and width, is used to move the magnified div inside the glass according to that percentage.
I've used php to get the image from a db then calculate its size just because that's how my project is structured. But you could start with any image and enter the ht and wd manually, of course.
Here's a demo: http://64.78.15.229/eyemap3Djs/magnify.html
I hope this is of some use to someone. Perhaps it could be used as a rifle scope in a game or something similar.
<?php
$studyID= $_GET['studyID'];
$myServer = "[your server]";
$myUser = "[you]";
$myPass = "[password]";
$myDB = "[db]";
$dbhandle = mssql_connect($myServer, $myUser, $myPass)
or die("Couldn't connect to SQL Server on $myServer");
$selected = mssql_select_db($myDB, $dbhandle)
or die("Couldn't open database $myDB");
$query = "SELECT * FROM [your table] WHERE id=".$studyID;
$result = mssql_query($query);
$numRows = mssql_num_rows($result);
while($row = mssql_fetch_array($result))
{
$imageFile= $row["imageFile"];
$mag= $row["mag"];
}
mssql_close($dbhandle);
$size = getimagesize($imageFile);
$ht=$size[1];
$wd=$size[0];
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html" charset="utf-8"/>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
<style>
html, body {
font-family: Verdana, Geneva, sans-serif;
font-size: 12px;
color: #333;
width : 100%;
height : 98%;
margin : 0;
padding : 0;
}
#renderCanvas {
width : 100%;
height : 100%;
touch-action: none;
z-index: 100;
}
#glass{
position:absolute;
overflow:hidden;
border:1px solid black;
border-radius: 50%;
padding-top: 0px;
padding-right: 0px;
padding-bottom: 0px;
padding-left: 0px;
pointer-events: none;
z-index: 100;
display:none;
}
#legend{
position:absolute;
font-size:10px;
font-family:Verdana, Geneva, sans-serif;
top:10px;
left:10px;
height:50px;
width:60px;
background-color:white;
z-index: 200;
}
</style>
<title>Magnifier</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="js/babylon.2.4.js"></script>
<script>
var studyID=<?php echo $studyID; ?>;
var imageFile="<?php echo $imageFile; ?>";
var mag=<?php echo $mag; ?>;
var picW=<?php echo $wd; ?>;
var picH=<?php echo $ht; ?>;
picW=picW*mag;
picH=picH*mag;
var percentage=picW/picH;
var svgW=1024;
var svgH=(1024/picW)*picH;
var glassH=200;
var glassW=200;
var scene;
var camera;
var cameraz=0;
var glassOff=false;
var leftPosition="";
var rightPosition="";
$(document).ready(function(){
$("#targetImg").attr({'src':imageFile});
$("#targetImg").css({'height':picH, 'width':picW});
});
window.addEventListener('DOMContentLoaded', function(){
var canvas = document.getElementById('renderCanvas');
var engine = new BABYLON.Engine(canvas, true);
var createScene = function () {
var scene = new BABYLON.Scene(engine);
var light = new BABYLON.PointLight("Omni", new BABYLON.Vector3(-25, 49, -40), scene);
this.angularSensibility = 5000;
cameraz=-1*(picW/140);
camera = new BABYLON.FreeCamera("FreeCamera", new BABYLON.Vector3(-0.6, -4, cameraz), scene);
camera.keysUp = [84]; // T
camera.keysDown = [66]; // B
camera.keysLeft = [70]; // L
camera.keysRight = [72]; // H
camera.angularSensibility = this.angularSensibility;
camera.attachControl(canvas, true);
//Ground
var ground = BABYLON.Mesh.CreatePlane("ground", 200.0, scene);
ground.material = new BABYLON.StandardMaterial("groundMat", scene);
ground.material.diffuseTexture = new BABYLON.Texture("textures/wallTile.jpg", scene);
ground.material.diffuseTexture.hasAlpha = true;
//ground.material.backFaceCulling = false;
ground.position = new BABYLON.Vector3(5, -10, -15);
ground.rotation = new BABYLON.Vector3(Math.PI / 2, 0, 0);
//target
var target = new BABYLON.Mesh.CreatePlane("target", 10, scene);
target.scaling.x = percentage;
target.material = new BABYLON.StandardMaterial("Mat", scene);
target.material.diffuseTexture = new BABYLON.Texture("<?php echo $imageFile; ?>", scene);
target.material.emissiveColor = new BABYLON.Color3(1, 1, 1); // self-illuminate
target.material.diffuseTexture.hasAlpha = true;
target.position = new BABYLON.Vector3(0, -5, -5);
scene.gravity = new BABYLON.Vector3(0, -0.9, 0);
scene.collisionsEnabled = true;
camera.checkCollisions = true;
camera.applyGravity = true;
camera.ellipsoid = new BABYLON.Vector3(1, 3, 1);
ground.checkCollisions = true;
target.checkCollisions = true;
return scene;
}
scene = createScene();
engine.runRenderLoop(function(){
scene.render();
});
window.addEventListener('resize', function(){
engine.resize();
});
window.addEventListener("mousemove", function (e) {
if(glassOff==false){
var pickResult = scene.pick(scene.pointerX, scene.pointerY);
if (pickResult.hit) {
var w=percentage*10;
var h = (pickResult.pickedPoint.x).toFixed(4);
var v = (pickResult.pickedPoint.y).toFixed(4);
var x=0;
var y=0;
y=v*-1;
percenty=(y/10).toFixed(4);
x=Number(((w/2))+(1*h)).toFixed(4);
percentx=(x/w).toFixed(4);
if(pickResult.pickedMesh.name=="target"){
$("#glass").show();
overtarget(e,percentx,percenty);
overtarget=true;
}else{
$("#glass").hide();
overtarget=false;
}
}
}
});
});
function overtarget(e,percentx,percenty){
$('#glass').css({
height:glassH,
width: glassW,
left: e.pageX-glassW/2,
top: e.pageY-glassH/2
});
var picX = (percentx * picW) * -1;
var picY = (percenty * picH) * -1;
$('#targetImg').css({
'margin-left': picX+glassW/2,
'margin-top': picY+glassH/2
});
}
</script>
</head>
<body>
<canvas id="renderCanvas"></canvas>
<div id="glass"><img id="targetImg" src=""/></div>
<div id="legend">T=forward<BR />B=back<BR />F=left<BR />H=right</div>
</body>`
</html>

Canvas waving flag HTML5

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>

Categories