Random letters wrapped with rectangles - javascript

How the random letters wrapped with rectangles can be generated using canvas??? I used j-query for it but dont know how to do it with canvas. here is the code which generates random letter using j-query.
<script>
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
function randomNumber(max) {
var randomNum = Math.random();
var numExpanded = randomNum * max;
var numFloored = Math.floor(numExpanded);
return numFloored;
}
//create a function returning a random letter
function randomLetter() {
var random0to25 = randomNumber(letters.length);
var randomLetter = letters.charAt(random0to25);
return randomLetter;
}
//create a function creating a span containing a random letter and attaching it to body
function createLetter() {
var span = $("<span/>");
span.css("position", "absolute");
span.css("top", 0);
randomCol=randomNumber(760);
randomCol=randomCol+20;
//concatenation
span.css("left", randomCol+"px");
span.text(randomLetter());
span.appendTo("body");
return span;
}
//explain how to animate an element
function makeLetterFall() {
var letterElement = createLetter();
letterElement.animate({"top":"95%"}, 5000); //any ideas how not to use {} here?
}
//handle keyup, find a letter and remove it
/*function removeTypedLetter(pressedKey) {
var typedLetter = String.fromCharCode(pressedKey.keyCode);
var letterElement = $("span:contains("+typedLetter+")").first();
letterElement.remove();
}*/
//$(document).on("keyup", removeTypedLetter);
//make a new letter every second
setInterval(makeLetterFall, 1000);
</script
>

Here's a learning example showing a falling rectangle letter.
Points of interest:
letter width can be measured with context.measureText
letter height can be approximated as the fontsize plus 2-3
text can be aligned vertically & horizontally with .textAlign & .textBaseline
text can be drawn on the canvas with context.fillText('A',x,y)
unfilled rectangles can be drawn on the canvas with context.strokeRect(x,y,width,height)
Example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var x=150;
var y=10;
var fontsize=20;
var fontface='verdana';
ctx.font=fontsize+' '+fontface;
ctx.textAlign='center';
ctx.textBaseline='middle';
animate();
function drawLetter(letter,x,y){
var width=ctx.measureText(letter).width;
ctx.strokeRect(x,y,width,fontsize);
ctx.fillText(letter,x+width/2,y+fontsize/2,width,fontsize);
}
function animate(){
ctx.clearRect(0,0,cw,ch);
drawLetter('A',x,y);
x+=Math.random()*4-2;
y+=1;
if(y<ch){
requestAnimationFrame(animate);
}
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<h4>Letter in Rect falling with random horizontal drifting</h4>
<canvas id="canvas" width=300 height=300></canvas>

Related

can you animate an image on a canvas

since I'm learning new to html and javascript, I was wondering if you can place an moving image side to side on a canvas? If so how can this be done please???
Here's what I've to do so far.
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="ann.css" />
<script>
window.onload = animate;
var canvas=document.getElementById('mycanvas');
var ctx=canvas.getContext('2d');
function animate()
{
window.setInterval(slide,1000);
}
function slide()
{
var obj = document.getElementById("ball");
var left = obj.style.left;
if(left === ''){
left = 0;
}
var wartosc = parseInt(left, 10);
obj.style.left = (wartosc + 10) + "px";
}
function Loop() {
if (left>canvas.width){
var right = obj.style.right;
if(right === ''){
right = 0;
}
var wartosc = parseInt(right, 10);
obj.style.right = (wartosc + 10) + "px";
}
</script>
<style>
#ball
{
position: relative;
left: 1px;
}
#mycanvas {border:1px solid #000000}
</style>
</head>
<body>
<img src="ball.gif" id="ball" alt="Usmiech" width="30" height="30" />
<canvas id=mycanvas width=600 height=50>Canvas Not Supported
</canvas>
<body>
</html>
What I want it do to is for the image to be contained inside the canvas and to move left to right and when reached the right side of canvas to go back left and so on continuously.
However my problems are if can be done, I don't know how I can put the image on the canvas and then I can't make the image move to the right once it has reached the end off the canvas. I think the issue is my loop function, which is there to try to make it go to the right.
As you can see from the fiddle link, when I remove the loop function code it works. However it will only goes to the left.
http://jsfiddle.net/eCSb4/18/
Please can someone help me fix it? :)
You can animate a spritesheet instead of a .gif.
The sequence is simple:
Clear the canvas,
Draw the next sprite in sequence and position it to advance across the canvas.
Wait a while (perhaps in a requestAnimationFrame loop).
Repeat #1.
Here's annotated code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
// timing related vars
var nextTime=0;
var spriteCount=7;
var interval=700/spriteCount;
// sprite related vars
var sIndex=0;
var sw=60;
var sh=95;
var animationOn=true;
// current x,y position of sprite
var x=100;
var y=100;
// load the spritesheet
var ss=new Image();
ss.onload=start;
ss.src="http://i59.tinypic.com/jpkk6f.jpg";
function start(){
// draw the first sprite
ctx.drawImage(ss,sIndex*sw,0,sw,sh,x,y,sw,sh);
// start the animation loop
requestAnimationFrame(animate);
}
function animate(time){
// wait for the specified interval before drawing anything
if(time<nextTime || !animationOn){requestAnimationFrame(animate); return;}
nextTime=time+interval;
// draw the new sprite
ctx.clearRect(0,0,cw,ch);
ctx.drawImage(ss,sIndex*sw,0,sw,sh,x,y,sw,sh);
// get the next sprite in sequence
if(++sIndex>=spriteCount){sIndex=0;}
// advance the sprite rightward
x+=5;
if(x>cw){x=-sw-10;}
// request another animation loop
requestAnimationFrame(animate);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=300 height=300></canvas>

HTML5 Canvas Flip Card Animation

I am trying to create flip card effect using html canvas by drawing it in the canvas.
no ccs3 tricks needed. It should be done in a native manner;
this is my initial test using phaser.js by changing the scale
<html>
<head>
</head>
<body>
<div id="game_canvas">
</div>
<script src = "jquery.min.js"></script>
<script src = "phaser.min.js"></script>
<script>
var game;
var sprite;
$(document).ready(function(){
game = new Phaser.Game(640, 480, Phaser.AUTO, 'game_canvas', {
preload : preload,
create : create,
update : update
});
function preload () {
game.load.image('card','download.png');
}
function create() {
this.delay = 1000;
this.spawn = 0;
sprite = game.add.sprite(game.width/4, game.height/4, 'card');
}
function update() {
console.log(this.spawn > game.time.now);
if (this.spawn > game.time.now) {
return;
}
this.spawn = game.time.now + this.delay;
sprite.scale.x *= -1;
}
});
</script>
</body>
</html>
and what i want to attain is like this using the canvas
http://www.turnjs.com/#samples/steve-jobs/10
anyone has any idea on how to do it would be a great help
thanks in advance
here is the current demo
http://sopronioli713.github.io/test/
Here's a canvas based card flip (with rotation) that I did a while back for fun.
It works by scaling in just the X direction so that the card appears to be flipping.
Notes about the effect:
You can omit the rotations if they are not required.
This effect translates to the horizontal center of the card before scaling (flipping) which makes the card "spin". If you instead want a "dealers flip" then you would instead translate to the edge of the card.
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var x=150;
var y=150;
var scaleX=100;
var angle=0;
var scaleDirection=-1;
var scaleDelta=1;
var PI2=Math.PI*2;
var backCanvas=document.createElement('canvas');
var backCtx=backCanvas.getContext('2d');
var imgCount=2;
var front=new Image();front.onload=start;front.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcard.png";
var back=new Image();back.onload=start;back.src="https://dl.dropboxusercontent.com/u/139992952/multple/kingcardback.png";
function start(){
if(--imgCount>0){return;}
animate();
}
function draw(x,y,scaleX,angle){
ctx.clearRect(0,0,cw,ch);
ctx.translate(x,y);
ctx.rotate(angle);
ctx.scale(scaleX,1);
if(scaleX>=0){
ctx.drawImage(front,-front.width/2,-front.height/2);
}else{
ctx.drawImage(back,-back.width/2,-back.height/2);
}
ctx.setTransform(1,0,0,1,0,0);
}
function animate(time){
draw(x,y,scaleX/100,angle);
angle+=PI2/720;
scaleX+=scaleDirection*scaleDelta;
if(scaleX<-100 || scaleX>100){
scaleDirection*=-1;
scaleX+=scaleDirection*scaleDelta;
}
requestAnimationFrame(animate);
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
On the other hand...
You link to a page-turning demo--which is a totally different animal. If that's what your after Rick Barraza has done a nice writeup on how to do that here: http://rbarraza.com/html5-canvas-pageflip/

Collision between falling letters and blocks

I am making a game in which the collision between letters and boxes must be detected.
I came across width height comparison algorithm but how would I go about finding the letters's height and width properties?
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<title>Game</title>
</head>
<style>
#canvas{
outline: 1px solid #000;
background-color: #0099FF;
}
</style>
<body>
<canvas id="canvas" width="800" height="600">
</canvas>
<script>
var canvas = document.querySelector('#canvas');
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#FF5050";
var xPos=0;
var yPos=500;
ctx.fillRect(xPos,yPos,70,70);
ctx.stroke();
function move(e){
if(xPos+70<=canvas.width)
{
if(e.keyCode==39){
xPos+=5;
}
}
if(xPos>0)
{
if(e.keyCode==37){
xPos-=5;
} }
canvas.width=canvas.width;
ctx.fillStyle = "#FF5050";
ctx.fillRect(xPos,yPos,70,70);
ctx.stroke();
}
document.onkeydown =move;
</script>
<script>
var letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
function randomNumber(max) {
var randomNum = Math.random();
var numExpanded = randomNum * max;
var numFloored = Math.floor(numExpanded);
return numFloored;
}
//create a function returning a random letter
function randomLetter() {
var random0to25 = randomNumber(letters.length);
var randomLetter = letters.charAt(random0to25);
return randomLetter;
}
//create a function creating a span containing a random letter and attaching it to body
function createLetter() {
var span = $("<span/>");
span.css("position", "absolute");
span.css("top", 0);
randomCol=randomNumber(760);
randomCol=randomCol+20;
//concatenation
span.css("left", randomCol+"px");
span.text(randomLetter());
span.appendTo("body");
return span;
}
//explain how to animate an element
function makeLetterFall() {
var letterElement = createLetter();
letterElement.animate({"top":"95%"}, 5000); //any ideas how not to use {} here?
}
//handle keyup, find a letter and remove it
/*function removeTypedLetter(pressedKey) {
var typedLetter = String.fromCharCode(pressedKey.keyCode);
var letterElement = $("span:contains("+typedLetter+")").first();
letterElement.remove();
}*/
//$(document).on("keyup", removeTypedLetter);
//make a new letter every second
setInterval(makeLetterFall, 1000);
</script>
</body>
</html>
It's probably easier to use canvas to draw both the falling letter and the blocks.
That way you can get the text's bounding box like this:
set the text font with context.font='36px verdana'
The approximate text height is the px font size + 2 (in this example var textHeight=36+2;)
You can measure the text width using var textWidth=context.measureText('A').width
Bounding box: x,y,textWidth,textHeight
To detect collisions you would check the text's bounding box against each rectangle's bounding box:
var textLeft=textX;
var textRight=textX+textWidth;
var textTop=textY;
var textBottom=textY+textHeight;
var rectLeft=rectX;
var rectRight=rectX+textWidth;
var rectTop=rectY;
var rectBottom=rectY+rectHeight;
// test if text & rect are colliding
return(!(
textLeft>rectRight ||
textRight<rectLeft ||
textTop>rectBottom ||
textBottom<rectTop
));
You can draw text on the canvas like this:
// context.fillText(text,x,y);
context.fillText('A',100,200);
To animate the text falling, in each new frame you would clear the canvas with context.clearRect(0,0,canvas.width,canvas.height) and then redraw the blocks & text in their new positions.

Stop a moving image in HTML5 Canvas

Im pretty new to the canvas element in HTML5.
What i want to do is move an image from the right hand side of the screen to the left, once it reaches the left i want it to begin again from the right hand side. I only want it to do this maybe 2/3 times and then stop.
I tried to add in a for loop so that it would limit the iterations but this was unsuccessful.
Any help at all would be appreciated.
Heres my code:
<canvas id="myCanvas" width="600" height="400"></canvas>
<script>
window.addEventListener('load', function () {
var
img = new Image,
ctx = document.getElementById('myCanvas').getContext('2d');
img.src = 'pies.png';
img.addEventListener('load', function () {
var interval = setInterval(function() {
var x = 650, y = 194;
return function () {
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.drawImage(img, x, y);
x -= 1;
if (x < -500) {
x = 650;
}
};
}(), 1000/40);
}, false);
}, false);
</script>
One way is to specify a maximum number of leftward moves:
// allow leftward moves = 2 1/2 time the canvas width
// (plus an allowance for the image width)
var maxMoves = (canvas.width+image.width) *2.5;
Then just countdown maxMoves until zero. At zero, stop your animation:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
ctx.fillStyle='skyblue';
var currentX=cw;
var delay=16; // 16ms between moves
var continueAnimating=true;
var nextMoveTime,maxMoves;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sun.png";
function start(){
maxMoves=(cw+img.width)*2.5;
nextMoveTime=performance.now();
requestAnimationFrame(animate);
}
function animate(currentTime){
if(continueAnimating){ requestAnimationFrame(animate); }
if(currentTime<nextMoveTime){return;}
nextMoveTime=currentTime+delay;
ctx.fillRect(0,0,cw,ch);
ctx.drawImage(img,currentX,50);
if(--currentX<-img.width){ currentX=cw; }
if(--maxMoves<0){continueAnimating=false;}
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<p>Stop animating after 2 1/2 "sunrises"</p>
<canvas id="canvas" width=300 height=300></canvas>

Text and animation together on HTML5 canvas

I have an animation based canvas that on mouseover animates rain droplets and the animation stops on mouseout. I have textbox which on submit should show text on canvas. However this text disappears when i moveout and mouseover again. I know that the canvas is redrawn on mouseover but i am unable to figure how to make the text remain where it is. Thanks!
I have adapted the code from the solution provided here =>
Random images falling like rain in canvas (Javascript)
Javascript
var ctx;
var imgBg;
var imgDrops;
var x = 0;
var y = 0;
var noOfDrops = 7;
var fallingDrops = [];
var intV;
imgBg = new Image();
imgBg.src = "image.jpg";
var canvas = document.getElementById('canvasRegn');
ctx = canvas.getContext('2d');
ctx.drawImage(imgBg,0,0,600,450); //Background
function draw() {
ctx.drawImage(imgBg, 0, 0,600,450); //Background
for (var i=0; i< noOfDrops; i++)
{
ctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y); //The rain drop
fallingDrops[i].y += fallingDrops[i].speed;
fallingDrops[i+4].x += fallingDrops[i].speed-1;//Set the falling speed
if (fallingDrops[i].y > 450) { //Repeat the raindrop when it falls out of view
fallingDrops[i].y = -120; //Account for the image size
fallingDrops[i].x = Math.random() * 600; //Make it appear randomly along the width
}
}
}
function setup() {
intV = setInterval(function(){draw()}, 36);
for (var i = 0; i < noOfDrops; i++) {
var fallingDr = new Object();
fallingDr["image"] = new Image();
fallingDr.image.src = "Rain.svg";
fallingDr["x"] = Math.random() * 600;
fallingDr["y"] = Math.random() * 5;
fallingDr["speed"] = 3 + Math.random() * 5;
fallingDrops.push(fallingDr);
}
}
function start(){
setup();
}
function stop(){
clearInterval(intV);
}
function clicked(){
var x=document.getElementById("form_val");
ctx.clearRect(0,0,600,400);
ctx.font="36px Verdana";
ctx.fillStyle="yellow";
ctx.strokeStyle="green";
ctx.lineWidth=2;
ctx.strokeText(x.value,200,200);
ctx.fillText(x.value,200,200);
}
HTML
<canvas id="canvasRegn" width="600" height="450"style="margin:10px;" onmouseover="start()" onmouseout="stop()">
</canvas>
<br>
<input type="text" name="fname" size="50" id="form_val">
<button id="submit" onclick="clicked()">Submit</button>
Each time you redraw the canvas you need to redraw the textbox, I would personally rename "clicked()" and call it from inside "draw()" (either before or after the drops depending on whether you want it to appear above or below)
You'd also have to remove the ctx.clearRect() from "clicked()" or it will overwrite the rain (if you're placing it on top)
Then you'd need to edit how it was called, the clicked() function could set a boolean variable which is checked inside the draw function (and if true, draws the textbox)
Pseudo code example:
var text = false
draw(){
drawRain()
if(text == true){drawText()}
}
clicked(){
text = true
}
Then if you wanted the textbox to be editable, you can use variables instead of fixed values in the drawText() e.g.
Outside the drawText()
fontVar = "36px Verdana";
fillColour = "yellow";
strokeColour = "green";
Inside the drawText()
ctx.font=fontVar;
ctx.fillStyle=fillColour;
ctx.strokeStyle=strokeColour;
The answer to this question lies in the laying of two canvas layers. First Canvas layer will have the background image and the animation effect. Second layer on top of it will draw the Text.
Note : Credit to #DBS for finding the solution.
JavaScript:
script type="text/javascript">
var ctx;
var ctx2
var imgBg;
var imgDrops;
var x = 0;
var y = 0;
var noOfDrops = 20;
var fallingDrops = [];
var intV;
fontVar ="36px Verdana";
fillColour="yellow";
strokeColour="green";
imgBg = new Image();
imgBg.src = "image.jpg";
var canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
ctx.drawImage(imgBg,0,0,600,400); //Background
var canvas2 = document.getElementById('drawText');
ctx2 = canvas2.getContext('2d');
function drawing(){
ctx.drawImage(imgBg,0,0,600,400); //Background
}
function draw() {
ctx.drawImage(imgBg, 0, 0,600,400); //Background
for (var i=0; i< noOfDrops; i++)
{
ctx.drawImage (fallingDrops[i].image, fallingDrops[i].x, fallingDrops[i].y,35,35); //The rain drop
fallingDrops[i].y += fallingDrops[i].speed;
fallingDrops[i+7].x += fallingDrops[i].speed-1;//Set the falling speed
if (fallingDrops[i].y > 400) { //Repeat the raindrop when it falls out of view
fallingDrops[i].y = -120; //Account for the image size
fallingDrops[i].x = Math.random() * 600; //Make it appear randomly along the width
}
}
}
function setup() {
intV = setInterval(function(){draw()}, 36);
for (var i = 0; i < noOfDrops; i++) {
var fallingDr = new Object();
fallingDr["image"] = new Image();
fallingDr.image.src = "Rain.svg";
fallingDr["x"] = Math.random() * 600;
fallingDr["y"] = Math.random() * 5;
fallingDr["speed"] = 3 + Math.random() * 5;
fallingDrops.push(fallingDr);
}
}
function start(){
setup();
}
function stop(){
clearInterval(intV);
}
function clicked(){
z=document.getElementById("form_val");
ctx2.clearRect(0,0,600,400);
ctx2.font=fontVar;
ctx2.fillStyle=fillColour;
ctx2.strokeStyle=strokeColour;
ctx2.lineWidth=2;
ctx2.strokeText(z.value,200,200);
ctx2.fillText(z.value,200,200);
}
</script>
HTML
<div class="wrapper">
<canvas id="myCanvas" width="600" height="400" style="margin:1px;"></canvas>
<canvas id="drawText" width="600" height="400" onmouseover="start()" onmouseout="stop()</canvas>
</div>
<br>
Greeting Message: <input type="text" name="fname" size="50" id="form_val">
<button id="submit" onclick="clicked()">Add this message</button>
</div>
CSS
How can I stack two same-sized canvas on top of each other?

Categories

Resources