line contracts and expands in html - javascript

i want to make a line that contracts and expands along x-axis randomly it should start from the middle of canvas . I was only able to move the line one way, not both ways! i have the code, if you could please help me i would really appreciate it !
<!DOCTYPE html>
<style>
canvas {
border: solid;
border-color: black; }
</style>
<canvas id="canvas">
</canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.strokeStyle = "black";
var posX = 0;
var lineLength = 50;
var speed = 2;
function drawLine() {
ctx.beginPath();
ctx.moveTo(posX, 50);
ctx.lineTo(posX + lineLength, 50);
ctx.stroke();
}
function moveLine() {
posX += speed;
if (posX < 0 || posX > canvas.width - 50) {
speed = speed * -1;
}
}
function loop() {
// clear old frame;
ctx.clearRect(0, 0, canvas.width, canvas.height);
moveLine();
drawLine();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
</script>

You want to be modifying the value of lineLength in your loop, not posX. Like this:
function moveLine() {
lineLength += speed;
if (lineLength < 0 || lineLength > canvas.width - 50) {
speed = speed * -1;
}
}
Then you just need to center your line:
function drawLine() {
var center = canvas.width/2;
ctx.beginPath();
ctx.moveTo(center - (lineLength/2), 50);
ctx.lineTo(center + (lineLength/2), 50);
ctx.stroke();
}
Since the X position of your line isn't variable, you don't need posX at all.

Related

Making an object move back and forth in javascript [duplicate]

So I have this rectangle that animates across to the right. How can I get the rectangle to reverse it when it hits the boundaries. I'm trying to make it go back and forth.
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript'>
window.onload=function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 50;
var width = 10;
var height = 10;
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, y, width, height);
x++;
if(x <= 490) {
setTimeout(animate, 33);
}
}
animate();
}
</script>
</head>
<body>
<canvas id="canvas" width="500" height="400"
style="border: 1px solid #000000;"></canvas>
</body>
</html>
https://codepen.io/forTheLoveOfCode/pen/wqdpeg
Is that what you need? (link to codepen above).
var canvas = document.getElementById("canvas_id");
var context = canvas.getContext('2d');
var x=5;
var y=5;
var velocity = 10;
function move(){
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
x =x + velocity
if ((x+50)>canvas.width || x<0){
velocity *=-1;
}
draw()
}
function draw(){
context.fillStyle = "#E80C7A";
context.strokeStyle = "#000000";
context.lineWidth = '3';
context.fillRect(x, y, 50, 100);
context.strokeRect(x, y, 50, 100);
}
setInterval(move, 100);
<html>
<body>
<canvas id = "canvas_id">
</canvas>
</body>
</html>
here's a solution with boundaries detection
window.onload=function(){
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var x = 0;
var y = 50;
var width = 10;
var height = 10;
var speed = 10; // speed
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(x, y, width, height);
if(
(x >= 500 - width && speed > 0) || // going to the right and bound reached
(x <= 0 && speed < 0) // going to the left and bound reached
) {
speed *= -1; // inverting the direction
}
x += speed;
setTimeout(animate, 33);
}
animate();
}
<canvas id="canvas" width="500" height="400"
style="border: 1px solid #000000;"></canvas>
consider using requestAnimationFrame instead of setTimeout to do this kind of work.

Canvas line drawing animation

I am new learner of animation using HTML5 Canvas. I am struggling to create line drawing animation in a canvas with desired length of a line.
Here is the code
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
width = canvas.width = window.innerWidth,
height = canvas.height = window.innerHeight;
var x = 200;
var y = 200;
draw();
update();
function draw() {
context.beginPath();
context.moveTo(100, 100);
context.lineTo(x, y);
context.stroke();
}
function update() {
context.clearRect(0, 0, width, height);
x = x + 1;
y = y + 1;
draw();
requestAnimationFrame(update);
}
html,
body {
margin: 0px;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
The line is growing on Canvas in the above code. But how to achieve that the 200px wide line and animate the movement in x and y direction. And the same animation with multiple lines using for loop and move them in different direction.
Check the reference image ....
Need to move each line in a different direction
Thanks in advance
Find a new reference image which i want to achieve
You need to either use transforms or a bit of trigonometry.
Transforms
For each frame:
Reset transforms and translate to center
Clear canvas
Draw line from center to the right
Rotate x angle
Repeat from step 2 until all lines are drawn
var ctx = c.getContext("2d");
var centerX = c.width>>1;
var centerY = c.height>>1;
var maxLength = Math.min(centerX, centerY); // use the shortest direction for demo
var currentLength = 0; // current length, for animation
var lenStep = 1; // "speed" of animation
function render() {
ctx.setTransform(1,0,0,1, centerX, centerY);
ctx.clearRect(-centerX, -centerY, c.width, c.height);
ctx.beginPath();
for(var angle = 0, step = 0.1; angle < Math.PI * 2; angle += step) {
ctx.moveTo(0, 0);
ctx.lineTo(currentLength, 0);
ctx.rotate(step);
}
ctx.stroke(); // stroke all at once
}
(function loop() {
render();
currentLength += lenStep;
if (currentLength < maxLength) requestAnimationFrame(loop);
})();
<canvas id=c></canvas>
You can use transformation different ways, but since you're learning I kept it simple in the above code.
Trigonometry
You can also calculate the line angles manually using trigonometry. Also here you can use different approaches, ie. if you want to use delta values, vectors or brute force using the math implicit.
For each frame:
Reset transforms and translate to center
Clear canvas
Calculate angle and direction for each line
Draw line
var ctx = c.getContext("2d");
var centerX = c.width>>1;
var centerY = c.height>>1;
var maxLength = Math.min(centerX, centerY); // use the shortest direction for demo
var currentLength = 0; // current length, for animation
var lenStep = 1; // "speed" of animation
ctx.setTransform(1,0,0,1, centerX, centerY);
function render() {
ctx.clearRect(-centerX, -centerY, c.width, c.height);
ctx.beginPath();
for(var angle = 0, step = 0.1; angle < Math.PI * 2; angle += step) {
ctx.moveTo(0, 0);
ctx.lineTo(currentLength * Math.cos(angle), currentLength * Math.sin(angle));
}
ctx.stroke(); // stroke all at once
}
(function loop() {
render();
currentLength += lenStep;
if (currentLength < maxLength) requestAnimationFrame(loop);
})();
<canvas id=c></canvas>
Bonus animation to play around with (using the same basis as above):
var ctx = c.getContext("2d", {alpha: false});
var centerX = c.width>>1;
var centerY = c.height>>1;
ctx.setTransform(1,0,0,1, centerX, centerY);
ctx.lineWidth = 2;
ctx.strokeStyle = "rgba(0,0,0,0.8)";
ctx.shadowBlur = 16;
function render(time) {
ctx.globalAlpha=0.77;
ctx.fillRect(-500, -500, 1000, 1000);
ctx.globalAlpha=1;
ctx.beginPath();
ctx.rotate(0.025);
ctx.shadowColor = "hsl(" + time*0.1 + ",100%,75%)";
ctx.shadowBlur = 16;
for(var angle = 0, step = Math.PI / ((time % 200) + 50); angle < Math.PI * 2; angle += step) {
ctx.moveTo(0, 0);
var len = 150 + 150 * Math.cos(time*0.0001618*angle*Math.tan(time*0.00025)) * Math.sin(time*0.01);
ctx.lineTo(len * Math.cos(angle), len * Math.sin(angle));
}
ctx.stroke();
ctx.globalCompositeOperation = "lighter";
ctx.shadowBlur = 0;
ctx.drawImage(ctx.canvas, -centerX, -centerY);
ctx.drawImage(ctx.canvas, -centerX, -centerY);
ctx.globalCompositeOperation = "source-over";
}
function loop(time) {
render(time);
requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
body {margin:0;background:#222}
<canvas id=c width=640 height=640></canvas>
Here is what I think you are describing...
window.onload = function() {
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
width = canvas.width = 400,
height = canvas.height = 220,
xcenter = 200,
ycenter = 110,
radius = 0,
radiusmax = 100,
start_angle1 = 0,
start_angle2 = 0;
function toRadians(angle) {
return angle * (Math.PI / 180);
}
function draw(x1, y1, x2, y2) {
context.beginPath();
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
}
function drawWheel(xc, yc, start_angle, count, rad) {
var inc = 360 / count;
for (var angle = start_angle; angle < start_angle + 180; angle += inc) {
var x = Math.cos(toRadians(angle)) * rad;
var y = Math.sin(toRadians(angle)) * rad;
draw(xc - x, yc - y, xc + x, yc + y);
}
}
function update() {
start_angle1 += 0.1;
start_angle2 -= 0.1;
if(radius<radiusmax) radius++;
context.clearRect(0, 0, width, height);
drawWheel(xcenter, ycenter, start_angle1, 40, radius);
drawWheel(xcenter, ycenter, start_angle2, 40, radius);
requestAnimationFrame(update);
}
update();
};
html,
body {
margin: 0px;
}
canvas {
display: block;
}
<canvas id="canvas"></canvas>
This is one that is a variable length emerging pattern. It has a length array element for each spoke in the wheel that grows at a different rate. You can play with the settings to vary the results:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var width = canvas.width = window.innerWidth;
var height = canvas.height = window.innerHeight;
var xcenter = width/4;
var ycenter = height/2;
var radius;
var time;
if(width>height) {
radius = height*0.4;
}
else {
radius = width*0.4;
}
var start_angle1 = 0;
var start_angle2 = 0;
function toRadians (angle) {
return angle * (Math.PI / 180);
}
function draw(x1,y1,x2,y2) {
context.beginPath();
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.stroke();
}
var radmax=width;
var rads = [];
var radsinc = [];
function drawWheel(xc,yc,start_angle,count,rad) {
var inc = 360/count;
var i=0;
for(var angle=start_angle; angle < start_angle+180; angle +=inc) {
var x = Math.cos(toRadians(angle)) * rads[rad+i];
var y = Math.sin(toRadians(angle)) * rads[rad+i];
draw(xc-x,yc-y,xc+x,yc+y);
rads[rad+i] += radsinc[i];
if(rads[rad+i] > radmax) rads[rad+i] = 1;
i++;
}
}
function update() {
var now = new Date().getTime();
var dt = now - (time || now);
time = now;
start_angle1 += (dt/1000) * 10;
start_angle2 -= (dt/1000) * 10;
context.clearRect(0,0,width,height);
drawWheel(xcenter,ycenter,start_angle1,50,0);
drawWheel(xcenter,ycenter,start_angle2,50,50);
requestAnimationFrame(update);
}
function init() {
for(var i=0;i<100;i++) {
rads[i] = 0;
radsinc[i] = Math.random() * 10;
}
}
window.onload = function() {
init();
update();
};
html, body {
margin: 0px;
}
canvas {
width:100%;
height:200px;
display: block;
}
<canvas id="canvas"></canvas>

DrawImage() doesn't draw on canvas

I am trying to make a screen following the player so that the player is in the middle of the screen. I have already made it in another game, but here it doesn't work. Here is my code :
var c = document.getElementById("main");
var ctx = c.getContext("2d");
var screen = document.getElementById("screen").getContext("2d");
var WhatUSeeWidth = document.getElementById("screen").width;
var WhatUSeeHeight = document.getElementById("screen").height;
ctx.beginPath();
for (i = 0; i < 100; i ++) {
if (i % 2) {
ctx.fillStyle = "red";
}
else {
ctx.fillStyle = "blue";
}
ctx.fillRect(0, i * 100, 500, 100);
}
var player = {
x : 700,
y : 800
}
setInterval(tick, 100);
function tick() {
screen.beginPath();
screen.drawImage(c, player.x - WhatUSeeWidth / 2, player.y - WhatUSeeHeight / 2, WhatUSeeWidth, WhatUSeeHeight, 0, 0, WhatUSeeWidth, WhatUSeeHeight);
}
canvas {
border: 2px solid black;
}
<canvas id="main" width="500" height="500"h></canvas>
<canvas id="screen" width="500" height="500"></canvas>
I want to draw The Blue and red canvas in The "screen" canvas Using drawImage
Ok , from your comment I understood what you are looking for. But the problem is that you probably start by an example without having understood. I try to give you my interpretation of what you do , but you should look for a good guide that starts with the basics and deepen animations (for example this: http://www.html5canvastutorials.com/).
HTML
<canvas id="canvasLayer" width="500" height="500"></canvas>
Javascript
var canvas = document.getElementById("canvasLayer");
var context = canvas.getContext("2d");
var WhatUSeeWidth = document.getElementById("canvasLayer").width;
var WhatUSeeHeight = document.getElementById("canvasLayer").height;
var player = {
x : 0,
y : 0
}
function drawBackground() {
for (i = 0; i < 100; i ++) {
if (i % 2) {
context.fillStyle = "red";
}
else {
context.fillStyle = "blue";
}
context.fillRect(0, i * 100, 500, 100);
}
}
function playerMove() {
context.beginPath();
var radius = 5;
context.arc(player.x, player.y, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 1;
context.strokeStyle = '#003300';
context.stroke();
}
setInterval(tick, 100);
function tick() {
context.clearRect(0, 0, canvas.width, canvas.height);
drawBackground();
player.x++;
player.y++;
playerMove();
}
This is the JSFiddle.
EDIT WITH THE CORRECT ANSWER
The error is in the position of the object "player". It is located outside of the canvas, width:500 height:500 and the "player" is in position x:700 y:800.
Changing the position of the player your copy will appear.
var player = {
x : 50,
y : 50
}
Here the jsfiddle example.

Javascript confetti blast effect

I was able to find this code to create a javascript confetti blast.
However, I need three main colours for the confetti, and for the confetti, to be squares. Any help would be much appreciated.
Below is the code
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
W = window.innerWidth,
H = window.innerHeight,
circles = [];
canvas.width = W;
canvas.height = H;
//Random Circles creator
function create() {
//Place the circles at the center
this.x = W/2;
this.y = H/2;
//Random radius between 2 and 6
this.radius = 2 + Math.random()*3;
//Random velocities
this.vx = -5 + Math.random()*10;
this.vy = -5 + Math.random()*10;
//Random colors
this.r = Math.round(Math.random())*255;
this.g = Math.round(Math.random())*255;
this.b = Math.round(Math.random())*255;
}
for (var i = 0; i < 500; i++) {
circles.push(new create());
}
function draw() {
//Fill canvas with black color
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(0,0,0,0.15)";
ctx.fillRect(0, 0, W, H);
//Fill the canvas with circles
for(var j = 0; j < circles.length; j++){
var c = circles[j];
//Create the circles
ctx.beginPath();
ctx.arc(c.x, c.y, c.radius, 0, Math.PI*2, true);
ctx.fillStyle = "rgba("+c.r+", "+c.g+", "+c.b+", 1)";
ctx.fill();
c.x += c.vx;
c.y += c.vy;
c.radius -= .02;
if(c.radius > 3)
circles[j] = new create();
}
}
function animate() {
requestAnimFrame(animate);
draw();
}
animate();
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
<style type="text/css">
body{
padding: 0; margin: 0;
min-height: 400px; height: 100%;
width: 100%;
overflow: hidden;
background-color: #000000;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="explosion.js"></script>
</body>
</html>
I wrote up an alternative solution. I noticed your current solutions had some runtime error, also a lot of unnecessary code (IMO - might be cleaner or easier to read?) and painted the whole rectangle canvas, you could apply this as a background colour via CSS, or leave as transparent as you probably want the confetti to show over something?
https://codepen.io/BenMoses/pen/MWyEePJ
ctx.globalCompositeOperation = "source-over"; //not needed as is default.
// shim layer with setTimeout fallback ? This is globally support so probably unnecessary?
//this.radius = 2 + Math.random()*3; //this is only for circles so can be removed
// all circle references should be updated to rect or square or confetti and confetto (a single confetti :o )
Pass in the index and use modulus operator to determine what color to set. Basic idea:
function create(ind) {
/* other code */
if(ind%3===0) { /* set color one */ }
else if (ind%2===0) { /* set color two */ }
else { /* set color three */ }
}
for (var i = 0; i < 500; i++) {
circles.push(new create(i));
}
Hopefully you figure out you need to change the this.r, this.g, and this.b values to match the color you need.
There are just a couple of places to modify (commented below).
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body{
padding: 0; margin: 0;
min-height: 400px; height: 100%;
width: 100%;
overflow: hidden;
background-color: #000000;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script>
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
W = window.innerWidth,
H = window.innerHeight,
circles = [];
canvas.width = W;
canvas.height = H;
//Random Circles creator
function create() {
//Place the circles at the center
this.x = W/2;
this.y = H/2;
//Random radius between 2 and 6
this.radius = 2 + Math.random()*3;
//Random velocities
this.vx = -5 + Math.random()*10;
this.vy = -5 + Math.random()*10;
}
for (var i = 0; i < 500; i++) {
circles.push(new create());
}
function draw() {
//Fill canvas with black color
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(0,0,0,0.15)";
ctx.fillRect(0, 0, W, H);
var myColors = ["e8e8e8", "a98547", "ccac7b"];
var which = 0;
//Fill the canvas with circles
for(var j = 0; j < circles.length; j++){
var c = circles[j];
//Create the circles
ctx.beginPath();
//ctx.arc(c.x, c.y, c.radius, 0, Math.PI*2, true);
ctx.fillRect(c.x , c.y, 20, 20); //change to box
//ctx.fillStyle = "rgba("+c.r+", "+c.g+", "+c.b+", 1)";
ctx.fillStyle = "#" + myColors[which].toString();
ctx.fill();
c.x += c.vx;
c.y += c.vy;
c.radius -= .02;
if(c.radius > 3)
circles[j] = new create();
if(which < myColors.length - 1) {
which++;
}
else {
which = 0;
}
}
}
function animate() {
requestAnimFrame(animate);
draw();
}
animate();
</script>
</body>
</html>
Here is the final code, thank you Stephen Brickner for all the help. I've learned a hell of alot
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
W = window.innerWidth,
H = window.innerHeight,
circles = [];
canvas.width = W;
canvas.height = H;
//Random Circles creator
function create() {
//Place the circles at the center
this.x = W/2;
this.y = H/2;
//Random radius between 2 and 6
this.radius = 2 + Math.random()*3;
//Random velocities
this.vx = -10 + Math.random()*30;
this.vy = -10 + Math.random()*30;
}
for (var i = 0; i < 100; i++) {
circles.push(new create());
}
function draw() {
//Fill canvas with black color
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "rgba(175,38,28,255)";
ctx.fillRect(0, 0, W, H);
var myColors = ["e8e8e8", "a98547", "ccac7b"];
var which = 0;
//Fill the canvas with circles
for(var j = 0; j < circles.length; j++){
var c = circles[j];
//Create the circles
ctx.beginPath();
//ctx.arc(c.x, c.y, c.radius, 0, Math.PI*2, true);
ctx.fillRect(c.x , c.y, 8, 8); //change to box
//ctx.fillStyle = "rgba("+c.r+", "+c.g+", "+c.b+", 1)";
ctx.fillStyle = "#" + myColors[which].toString();
ctx.fill();
c.x += c.vx;
c.y += c.vy;
c.radius -= .02;
if(c.radius > 3)
circles[j] = new create();
if(which < myColors.length - 1) {
which++;
}
else {
which = 0;
}
}
}
function animate() {
requestAnimFrame(animate);
draw();
}
animate();

CSS3: change the color of the ball every time it bounces off the canvas wall

I have to create a ball game in HTML5/CSS3. JSFiddle for the same could be seen.
Now what I want is to change the ball color every time it bounces off the wall.
var context;
var dx = 4;
var dy = 4;
var y = 150;
var x = 10;
function draw() {
context = myCanvas.getContext('2d');
context.clearRect(0, 0, 300, 300);
context.beginPath();
context.arc(x, y, 20, 0, Math.PI * 2, true);
context.closePath();
context.fill();
if (x < 0 || x > 300)
dx = -dx;
if (y < 0 || y > 300)
dy = -dy;
x += dx;
y += dy;
}
setInterval(draw, 10);
#container {
text-align: center;
}
#myCanvas {
background: #fff;
border: 1px solid #cbcbcb;
text-align: center;
}
<div id="container">
<div>
<canvas id="myCanvas" width="300" height="300"></canvas>
</div>
</div>
I don't know how to do it. Can css3 be used to do this?
The random color function comes from here: https://stackoverflow.com/a/1484514/2042240
This will make it change at every bounce.
https://jsfiddle.net/e0b1gkc4/4/
var context;
var dx= 4;
var dy=4;
var y=150;
var x=10;
function draw(){
context= myCanvas.getContext('2d');
context.clearRect(0,0,300,300);
context.beginPath();
context.arc(x,y,20,0,Math.PI*2,true);
context.closePath();
context.fill();
if( x<0 || x>300){
dx=-dx;
context.fillStyle = getRandomColor();
}
if( y<0 || y>300){
dy=-dy;
context.fillStyle = getRandomColor();
}
x+=dx;
y+=dy;
}
setInterval(draw,10);
function getRandomColor() {
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ ) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}

Categories

Resources