I've implemented a canvas element with a javascript particle effect. The effect is working on every browser but IOS/Safari. I've done a bit of research and IOS/Safari supports HTML5/Canvas: According to Browser Support Charts for HTML5/Canvas
$(function() {
var WIDTH = window.innerWidth * .9,
HEIGHT = window.innerHeight,
MAX_PARTICLES = 100,
DRAW_INTERVAL = 60,
canvas = document.querySelector('#pixies'),
context = canvas.getContext('2d'),
gradient = null,
pixies = new Array();
function setDimensions() {
WIDTH = window.outerWidth;
HEIGHT = window.innerHeight;
canvas.width = WIDTH;
canvas.height = HEIGHT;
}
setDimensions();
window.addEventListener('resize', setDimensions);
function Circle() {
this.settings = {ttl:8000, xmax:5, ymax:2, rmax:10, rt:1, xdef:960, ydef:540, xdrift:4, ydrift: 4, random:true, blink:true};
this.reset = function() {
this.x = (this.settings.random ? WIDTH*Math.random() : this.settings.xdef);
this.y = (this.settings.random ? HEIGHT*Math.random() : this.settings.ydef);
this.r = ((this.settings.rmax-1)*Math.random()) + 1;
this.dx = (Math.random()*this.settings.xmax) * (Math.random() < .5 ? -1 : 1);
this.dy = (Math.random()*this.settings.ymax) * (Math.random() < .5 ? -1 : 1);
this.hl = (this.settings.ttl/DRAW_INTERVAL)*(this.r/this.settings.rmax);
this.rt = Math.random()*this.hl;
this.settings.rt = Math.random()+1;
this.stop = Math.random()*.2+.4;
this.settings.xdrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
this.settings.ydrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
}
this.fade = function() {
this.rt += this.settings.rt;
}
this.draw = function() {
if(this.settings.blink && (this.rt <= 0 || this.rt >= this.hl)) {
this.settings.rt = this.settings.rt*-1;
} else if(this.rt >= this.hl) {
this.reset();
}
var newo = 1-(this.rt/this.hl);
context.beginPath();
context.arc(this.x, this.y, this.r, 0, Math.PI*2, true);
context.closePath();
var cr = this.r*newo;
gradient = context.createRadialGradient(this.x, this.y, 0, this.x, this.y, (cr <= 0 ? 1 : cr));
gradient.addColorStop(0.0, 'rgba(255,255,255,'+newo+')');
gradient.addColorStop(this.stop, 'rgba(255,255,255,'+(newo*.6)+')');
gradient.addColorStop(1.0, 'rgba(255,255,255,0)');
context.fillStyle = gradient;
context.fill();
}
this.move = function() {
this.x += (this.rt/this.hl)*this.dx;
this.y += (this.rt/this.hl)*this.dy;
if(this.x > WIDTH || this.x < 0) this.dx *= -1;
if(this.y > HEIGHT || this.y < 0) this.dy *= -1;
}
this.getX = function() { return this.x; }
this.getY = function() { return this.y; }
}
for (var i = 0; i < MAX_PARTICLES; i++) {
pixies.push(new Circle());
pixies[i].reset();
}
function draw() {
context.clearRect(0, 0, WIDTH, HEIGHT);
for(var i = 0; i < pixies.length; i++) {
pixies[i].fade();
pixies[i].move();
pixies[i].draw();
}
}
setInterval(draw, DRAW_INTERVAL);
});
#particles {
position: absolute;
background: navy;
width: 200px;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="particles">
<canvas id="pixies"></canvas>
</div>
Any ideas why this isn't working in IOS/Safari? The actual site in question is this one: www.pjmaskslive.com
The issue appears to be that the canvas elements width is set 0 on the aforementioned website. So I would assume that the issue is setting the WIDTH variable at the start. This might be due to an ongoing bug with iOS 10 as mentioned in this question.
An alternative approach might be to use document.body.getBoundingClientRect().width as an alternative to window.innerWidth and/or window.outerWidth. screen.width could also be used, however, these could also have the same issues as your previous methods.
Seems like a safari issue rather than your code either way!
Related
I have a canvas game in my webpage and it operates with arrow key controls, but whenever somebody tries to play it the page scrolls. Is there any way I can prevent it? The code for my game is here. All I need is for the page to not be bouncing up and down whenever somebody is trying to play. I know it would be easier to just use the wasd keys but to me that feels like putting duct tape on a leak on the hull of a boat instead of actually fixing it. Any suggestions? I'm using google apps script HTML service so I'm not sure if using jquery is possible or if it is whether its going going to be hours and hours of work that are eventually ditched in favor of a quicker solution. Anyways, hope somebody can help.
<h1> example html</h1>
<p>exampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTMLexampleHTML</p>
<h2>example html </h2>
<canvas id='my' width = '640' height = '480' style = 'display: none;'></canvas>
<script>
var paused = false
function PausePlay(){
if (paused === false)
{paused = true;}
else{paused = false;}
}
var canvas = document.getElementById("my");
var ctx = canvas.getContext("2d");
function paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.speedModifier = 0;
this.hasCollidedWith = function(ball) {
var paddleLeftWall = this.x;
var paddleRightWall = this.x + this.width;
var paddleTopWall = this.y;
var paddleBottomWall = this.y + this.height;
if (ball.x > paddleLeftWall &&
ball.x < paddleRightWall &&
ball.y > paddleTopWall &&
ball.y < paddleBottomWall) {
return true;
}
return false;
};
this.move = function(keyCode) {
var nextY = this.y;
if (keyCode == 40) {
nextY += 5;
this.speedModifer = 1.5;
} else if (keyCode == 38) {
nextY += -5;
this.speedModifier = 1.5;
} else {
this.speedModifier = 0;
}
nextY = nextY < 0 ? 0 : nextY;
nextY = nextY + this.height > 480 ? 480 - this.height : nextY;
this.y = nextY;
};
}
var player = new paddle(5, 200, 25, 100);
var ai = new paddle(610, 200, 25, 100);
var ball = {
x: 320,
y: 240,
radius: 7,
xSpeed: 2,
ySpeed: 0,
playerscore: 0,
aiscore: 0,
reverseX: function() {
this.xSpeed *= -1;
},
reverseY: function() {
this.ySpeed *= -1;
},
reset: function() {
alert('The score is now ' + this.playerscore + ' to ' + this.aiscore);
this.x = 20;
this.y = 24;
this.xSpeed = 2;
this.ySpeed = 0;
},
isBouncing: function() {
return ball.ySpeed != 0;
},
modifyXSpeedBy: function(modification) {
modification = this.xSpeed < 0 ? modification * -1 : modification;
var nextValue = this.xSpeed + modification;
nextValue = Math.abs(nextValue) > 9 ? 9 : nextValue;
this.xSpeed = nextValue;
},
modifyYSpeedBy: function(modification) {
modification = this.ySpeed < 0 ? modification * -1 : modification;
this.ySpeed += modification;
}
};
function tick() {
updateGame();
draw()
window.setTimeout("tick()", 1000 / 60);
}
function updateGame() {
if (paused === false){
ball.x += ball.xSpeed;
ball.y += ball.ySpeed;
if (ball.x < 0) {
ball.reset();
ball.aiscore = ball.aiscore + 1;
}
if (ball.x > 640) {
ball.reset();
ball.playerscore = ball.playerscore + 1
}
if (ball.y <= 0 || ball.y >= 480) {
ball.reverseY();
}
var collidedWithPlayer = player.hasCollidedWith(ball);
var collidedWithAi = ai.hasCollidedWith(ball);
if (collidedWithPlayer || collidedWithAi) {
ball.reverseX();
ball.modifyXSpeedBy(0.25);
var speedUpValue = collidedWithPlayer ? player.speedModifier : ai.speedModifier;
ball.modifyYSpeedBy(speedUpValue);
}
for (var keyCode in heldDown) {
player.move(keyCode);
}
var aiMiddle = ai.y + (ai.height / 2);
if (aiMiddle < ball.y) {
ai.move(40);
}
if (aiMiddle > ball.y) {
ai.move(38);
}
}
}
function draw() {
if(paused === false){
ctx.fillStyle = "black";
ctx.fillRect(0, 0, 640, 480);
renderPaddle(player);
renderPaddle(ai);
renderBall(ball);
}
}
function renderPaddle(paddle) {
ctx.fillStyle = "blue";
ctx.fillRect(paddle.x, paddle.y, paddle.width, paddle.height);
}
function renderBall(ball) {
ctx.beginPath();
ctx.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "pink";
ctx.fill();
}
var heldDown = {};
window.addEventListener("keydown", function(keyInfo) {
heldDown[event.keyCode] = true;
}, false);
window.addEventListener("keyup", function(keyInfo) {
delete heldDown[event.keyCode];
}, false);
function playPong(){
canvas.style.display = 'block';
tick()
}
function show(){
var canvas = document.getElementById('my')
canvas.style.display = 'block';
}
</script>
<div>
<button onclick = 'hide()'> Hide or show the games</button>
<br>
<button onclick = 'PausePlay()'> Pause/play games</button>
<br>
</div>
<br><br><br><br>
<button onclick = 'playPong()'> Play pong </button>
You may use overflow: hidden; CSS property in order to control the ability of scrolling. If you need to prevent vertical/horizontal scrolling only, so you may use overflow-x and overflow-y More about overflow property here.
I am trying to make a pong canvas game responsive on resize, i am nor sure what i am missing and what would be the best way to have it responsive while still not being to process heavy. i tried to delete and reinject the canvas on resize what is a bad idea i think, the responsiveness works on load so far... thanks a lot for the insights, much appreciated
http://jsfiddle.net/ut0hsvd4/1/
var animate = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) {
window.setTimeout(callback, 1000 / 60)
};
var canvas = document.createElement("canvas");
var width = document.getElementById('pong').offsetWidth;
var height = document.getElementById('pong').offsetHeight;
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
var player = new Player();
var computer = new Computer();
var ball = new Ball(width / 2, height / 2);
var keysDown = {};
var render = function() {
context.fillStyle = "red";
context.fillRect(0, 0, width, height);
player.render();
computer.render();
ball.render();
};
var update = function() {
player.update();
computer.update(ball);
ball.update(player.paddle, computer.paddle);
};
var step = function() {
update();
render();
animate(step);
};
function Paddle(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.x_speed = 0;
this.y_speed = 0;
}
Paddle.prototype.render = function() {
context.fillStyle = "#0000FF";
context.fillRect(this.x, this.y, this.width, this.height);
};
Paddle.prototype.move = function(x, y) {
this.x += x;
this.y += y;
this.x_speed = x;
this.y_speed = y;
if (this.x < 0) {
this.x = 0;
this.x_speed = 0;
} else if (this.x + this.width > width) {
this.x = width - this.width;
this.x_speed = 0;
}
};
function Computer() {
this.paddle = new Paddle(width / 2 - 25, 10, 50, 10);
}
Computer.prototype.render = function() {
this.paddle.render();
};
Computer.prototype.update = function(ball) {
var x_pos = ball.x;
var diff = -((this.paddle.x + (this.paddle.width / 2)) - x_pos);
if (diff < 0 && diff < -4) {
diff = -5;
} else if (diff > 0 && diff > 4) {
diff = 5;
}
this.paddle.move(diff, 0);
if (this.paddle.x < 0) {
this.paddle.x = 0;
} else if (this.paddle.x + this.paddle.width > width) {
this.paddle.x = width - this.paddle.width;
}
};
function Player() {
this.paddle = new Paddle(width / 2 - 25, height - 20, 50, 10);
}
Player.prototype.render = function() {
this.paddle.render();
};
Player.prototype.update = function() {
for (var key in keysDown) {
var value = Number(key);
if (value == 37) {
this.paddle.move(-4, 0);
} else if (value == 39) {
this.paddle.move(4, 0);
} else {
this.paddle.move(0, 0);
}
}
};
function Ball(x, y) {
this.x = x;
this.y = y;
this.x_speed = 0;
this.y_speed = 3;
}
Ball.prototype.render = function() {
context.beginPath();
context.arc(this.x, this.y, 5, 2 * Math.PI, false);
context.fillStyle = "#000000";
context.fill();
};
Ball.prototype.update = function(paddle1, paddle2) {
this.x += this.x_speed;
this.y += this.y_speed;
var top_x = this.x - 5;
var top_y = this.y - 5;
var bottom_x = this.x + 5;
var bottom_y = this.y + 5;
if (this.x - 5 < 0) {
this.x = 5;
this.x_speed = -this.x_speed;
} else if (this.x + 5 > width) {
this.x = width - 5;
this.x_speed = -this.x_speed;
}
if (this.y < 0 || this.y > height) {
this.x_speed = 0;
this.y_speed = 3;
this.x = width / 2;
this.y = height / 2;
}
if (top_y > height / 2) {
if (top_y < (paddle1.y + paddle1.height) && bottom_y > paddle1.y && top_x < (paddle1.x + paddle1.width) && bottom_x > paddle1.x) {
this.y_speed = -3;
this.x_speed += (paddle1.x_speed / 2);
this.y += this.y_speed;
}
} else {
if (top_y < (paddle2.y + paddle2.height) && bottom_y > paddle2.y && top_x < (paddle2.x + paddle2.width) && bottom_x > paddle2.x) {
this.y_speed = 3;
this.x_speed += (paddle2.x_speed / 2);
this.y += this.y_speed;
}
}
};
document.getElementsByClassName('js-pong')[0].appendChild(canvas);
animate(step);
window.addEventListener("keydown", function(event) {
keysDown[event.keyCode] = true;
});
window.addEventListener("keyup", function(event) {
delete keysDown[event.keyCode];
});
var resizer = function() {
document.getElementsByTagName('canvas').remove();
document.getElementsByClassName('js-pong')[0].appendChild(canvas);
animate(step);
}
window.addEventListener('resize', resizer);
Dont use the Resize event for animations.
(if you use requestAnimationFrame)
Do not add a resize to the resize event. The resize event does not fire in sync with the display, and it can also fire many time quicker than the display rate. This can make the resize and game feel sluggish while dragging at the window size controls.
Smooth and efficient resizing
For the smoothest resize simply check the canvas size inside the main loop. If the canvas does not match the containing element size then resize it. This ensures you only resize when needed and always resize in sync with the display (if you use requestAnimationFrame)
Eg
// get a reference to the element so you don't query the DOM each time
const pongEl = document.getElementById("pong");
// then in the main loop
function mainLoop() {
// do first thing inside the render loop
if(canvas.width !== pongEl.offsetWidth || canvas.height !== pongEl.offsetHeight ){
canvas.width = pongEl.offsetWidth;
canvas.height = pongEl.offsetHeight;
// note the above clears the canvas.
}
// game code as normal
requestAnimationFrame(mainLoop);
}
You have to detect when the resize happens with JavaScript:
window.onresize = function(event) {
...
};
and add a css class or properties to make the canvas width 100%. Also you have to give it a min-width to make sure no body can resize it to a really uncomfortable width.
This piece of code needs to run again after a resize:
var canvas = document.createElement("canvas");
var width = document.getElementById('pong').offsetWidth;
var height = document.getElementById('pong').offsetHeight;
canvas.width = width;
canvas.height = height;
var context = canvas.getContext('2d');
I work with this code for show HTML5 canvas animated in over my div:
HTML:
<div class="ls-slide" id="asb">
<div id="smile" style="width:100%;height:359px;">
<canvas style="position: absolute; width: 100%; z-index: 3; display: block;" height="359" width="2111">
</canvas>
</div>
</div>
JS:
window.onload = function() {
travers();
var lastHeight = $("#asb").height();
var canvas = document.querySelector('canvas');
ctx = canvas.getContext('2d');
color = '#aaa';
var check = respondCanvas();
canvas.width = check[1];
canvas.height = lastHeight;
canvas.style.display = 'block';
ctx.fillStyle = color;
ctx.lineWidth = .1;
ctx.strokeStyle = color;
function respondCanvas() {
var width = [];
width[0] = $('#smile').width(); //max width
width[1] = $('canvas').width(); //max width
return width;
//Call a function to redraw other content (texts, images etc)
}
function checkheight() {
var height = $('#asb').height(); //max width
//console.log(height);
// return height;
}
var mousePosition = {
x: 30 * canvas.width / 100,
y: 30 * canvas.height / 100
};
if (canvas.width <= 1000) {
var numdot = 100;
} else if (canvas.width <= 800) {
var numdot = 80;
} else if (canvas.width <= 500) {
var numdot = 35;
} else {
var numdot = 300;
}
var dots = {
nb: numdot,
distance: 70,
d_radius: 50,
array: []
};
function Dot() {
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.vx = -.5 + Math.random();
this.vy = -.5 + Math.random();
this.radius = Math.random();
}
Dot.prototype = {
create: function() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fill();
},
animate: function() {
for (i = 0; i < dots.nb; i++) {
var dot = dots.array[i];
if (dot.y < 0 || dot.y > canvas.height) {
dot.vx = dot.vx;
dot.vy = -dot.vy;
} else if (dot.x < 0 || dot.x > canvas.width) {
dot.vx = -dot.vx;
dot.vy = dot.vy;
}
dot.x += dot.vx;
dot.y += dot.vy;
}
},
line: function() {
for (i = 0; i < dots.nb; i++) {
for (j = 0; j < dots.nb; j++) {
i_dot = dots.array[i];
j_dot = dots.array[j];
if ((i_dot.x - j_dot.x) < dots.distance && (i_dot.y - j_dot.y) < dots.distance && (i_dot.x - j_dot.x) > -dots.distance && (i_dot.y - j_dot.y) > -dots.distance) {
if ((i_dot.x - mousePosition.x) < dots.d_radius && (i_dot.y - mousePosition.y) < dots.d_radius && (i_dot.x - mousePosition.x) > -dots.d_radius && (i_dot.y - mousePosition.y) > -dots.d_radius) {
ctx.beginPath();
ctx.moveTo(i_dot.x, i_dot.y);
ctx.lineTo(j_dot.x, j_dot.y);
ctx.stroke();
ctx.closePath();
}
}
}
}
}
};
function createDots() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (i = 0; i < dots.nb; i++) {
dots.array.push(new Dot());
dot = dots.array[i];
dot.create();
}
dot.line();
dot.animate();
}
$("canvas").mousemove(function(parameter) {
mousePosition.x = parameter.pageX - 0;
mousePosition.y = parameter.pageY - 300;
});
setInterval(createDots, 1000 / 30);
};
But, In action not work and I can't see dotted animation(I checked in chrome,ff). How do fix this?!
demo : https://jsfiddle.net/5pzvh8ko/
You can try it better by giving an ID to you canvas tag, and then use "document.getElementById()", to access your canvas tag, i think it is a better method and even simpler.here is an example:
canvas tag with id:
<canvas ID="canvas_id" style="position: absolute; width: 100%; z-index:3; display: block;" height="359" width="2111">
then use JavaScript to access it this way:
var canvas = document.getElementById("canvas_id");
This might not be all you need but you can at least try it that way.
I am following this tutorial and trying to implement it on my website. I am struggling to remove the 'Black' background to show the full background image with the stars.
Here's jsFiddle: jFiddle
Here's the screen shot below.
Here's the jQuery for your inspection:
width = window.innerWidth,
height = 300;
// Add 2 shooting stars that just cycle.
entities.push(new ShootingStar());
entities.push(new ShootingStar());
//animate background
function animate() {
bgCtx.fillStyle = "black";
bgCtx.fillRect(0, 0, width, height);
bgCtx.fillStyle = '#fff';
bgCtx.strokeStyle = "#fff";
var entLen = entities.length;
while (entLen--) {
entities[entLen].update();
}
requestAnimationFrame(animate);
}
animate();
Any help would be great! thanks :)
In the animate()function, replace
bgCtx.fillStyle = "black";
bgCtx.fillRect(0, 0, width, height);
with
bgCtx.fillStyle = "rgba(0,0,0,0)";
bgCtx.clearRect(0, 0, width, height);
and remove this line bgCtx.fillRect(0, 0, width, height);(l80)
http://jsfiddle.net/aernk8kk/13/
(function () {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
window.requestAnimationFrame = requestAnimationFrame;
})();
// Terrain stuff.
var background = document.getElementById("bgCanvas"),
bgCtx = background.getContext("2d"),
width = window.innerWidth,
height = 300;
(height < 400) ? height = 400 : height;
background.width = width;
background.height = height;
function Terrain(options) {
options = options || {};
this.terrain = document.createElement("canvas");
this.terCtx = this.terrain.getContext("2d");
this.scrollDelay = options.scrollDelay || 90;
this.lastScroll = new Date().getTime();
this.terrain.width = width;
this.terrain.height = height;
this.fillStyle = options.fillStyle || "#f30";
this.mHeight = options.mHeight || height;
// generate
this.points = [];
var displacement = options.displacement || 140,
power = Math.pow(2, Math.ceil(Math.log(width) / (Math.log(2))));
// set the start height and end height for the terrain
this.points[0] = this.mHeight;//(this.mHeight - (Math.random() * this.mHeight / 2)) - displacement;
this.points[power] = this.points[0];
// create the rest of the points
for (var i = 1; i < power; i *= 2) {
for (var j = (power / i) / 2; j < power; j += power / i) {
this.points[j] = ((this.points[j - (power / i) / 2] + this.points[j + (power / i) / 2]) / 2) + Math.floor(Math.random() * -displacement + displacement);
}
displacement *= 0.6;
}
document.body.appendChild(this.terrain);
}
Terrain.prototype.update = function () {
// draw the terrain
this.terCtx.clearRect(0, 0, width, height);
this.terCtx.fillStyle = this.fillStyle;
if (new Date().getTime() > this.lastScroll + this.scrollDelay) {
this.lastScroll = new Date().getTime();
this.points.push(this.points.shift());
}
this.terCtx.beginPath();
for (var i = 0; i <= width; i++) {
if (i === 0) {
this.terCtx.moveTo(0, this.points[0]);
} else if (this.points[i] !== undefined) {
this.terCtx.lineTo(i, this.points[i]);
}
}
this.terCtx.lineTo(width, this.terrain.height);
this.terCtx.lineTo(0, this.terrain.height);
this.terCtx.lineTo(0, this.points[0]);
this.terCtx.fill();
}
// Second canvas used for the stars
bgCtx.fillStyle = "rgb(255,255,255)";
// stars
function Star(options) {
this.size = Math.random() * 2;
this.speed = Math.random() * .05;
this.x = options.x;
this.y = options.y;
}
Star.prototype.reset = function () {
this.size = Math.random() * 2;
this.speed = Math.random() * .05;
this.x = width;
this.y = Math.random() * height;
}
Star.prototype.update = function () {
this.x -= this.speed;
if (this.x < 0) {
this.reset();
} else {
bgCtx.fillRect(this.x, this.y, this.size, this.size);
}
}
function ShootingStar() {
this.reset();
}
ShootingStar.prototype.reset = function () {
this.x = Math.random() * width;
this.y = 0;
this.len = (Math.random() * 80) + 10;
this.speed = (Math.random() * 10) + 6;
this.size = (Math.random() * 1) + 0.1;
// this is used so the shooting stars arent constant
this.waitTime = new Date().getTime() + (Math.random() * 3000) + 500;
this.active = false;
}
ShootingStar.prototype.update = function () {
if (this.active) {
this.x -= this.speed;
this.y += this.speed;
if (this.x < 0 || this.y >= height) {
this.reset();
} else {
bgCtx.lineWidth = this.size;
bgCtx.beginPath();
bgCtx.moveTo(this.x, this.y);
bgCtx.lineTo(this.x + this.len, this.y - this.len);
bgCtx.stroke();
}
} else {
if (this.waitTime < new Date().getTime()) {
this.active = true;
}
}
}
var entities = [];
// init the stars
for (var i = 0; i < height; i++) {
entities.push(new Star({
x: Math.random() * width,
y: Math.random() * height
}));
}
// Add 2 shooting stars that just cycle.
entities.push(new ShootingStar());
entities.push(new ShootingStar());
//animate background
function animate() {
bgCtx.fillStyle = "rgba(0,0,0,0)";
bgCtx.clearRect(0, 0, width, height);
bgCtx.fillStyle = '#fff';
bgCtx.strokeStyle = "#fff";
var entLen = entities.length;
while (entLen--) {
entities[entLen].update();
}
requestAnimationFrame(animate);
}
animate();
body, html {
color: #fff;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background: url(
http://cdn1.dottech.org/wp-content/uploads/2013/08/moon_clear_sky_wallpaper_2560x1440.jpg
) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
canvas {
position:absolute;
top:0;
left:0
}
<canvas id="bgCanvas"></canvas>
check clearRect
I would like to know how the "moving effect" it's made in this site:
http://www.perturbator.com/
I mean the pink lines, not the logo ()wichi is a simple parallax).
EDIT (I can't answer myself in 8 hours):
The code it's in the base.js file. It drawns the dots and then the lines.
$(function(){
var header = $('.site-header'),
canvas = $('<canvas></canvas>').appendTo(header)[0],
ctx = canvas.getContext('2d'),
color = '#fc335c',
idle = null, mousePosition;
canvas.width = window.innerWidth;
canvas.height = header.outerHeight();
canvas.style.display = 'block';
ctx.fillStyle = color;
ctx.lineWidth = .1;
ctx.strokeStyle = color;
var mousePosition = {
x: 30 * canvas.width,
y: 30 * canvas.height
},
dots = {
nb: 150,
distance: 90,
d_radius: 900,
array: []
};
function Dot(){
this.x = Math.random() * canvas.width;
this.y = Math.random() * canvas.height;
this.vx = -.5 + Math.random();
this.vy = -.5 + Math.random();
this.radius = Math.random();
}
Dot.prototype = {
create: function(){
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false);
ctx.fill();
},
animate: function(){
for(var i = 0, dot=false; i < dots.nb; i++){
dot = dots.array[i];
if(dot.y < 0 || dot.y > canvas.height){
dot.vx = dot.vx;
dot.vy = - dot.vy;
}else if(dot.x < 0 || dot.x > canvas.width){
dot.vx = - dot.vx;
dot.vy = dot.vy;
}
dot.x += dot.vx;
dot.y += dot.vy;
}
},
line: function(){
for(var i = 0; i < dots.nb; i++){
for(var j = 0; j < dots.nb; j++){
i_dot = dots.array[i];
j_dot = dots.array[j];
if((i_dot.x - j_dot.x) < dots.distance && (i_dot.y - j_dot.y) < dots.distance && (i_dot.x - j_dot.x) > - dots.distance && (i_dot.y - j_dot.y) > - dots.distance){
if((i_dot.x - mousePosition.x) < dots.d_radius && (i_dot.y - mousePosition.y) < dots.d_radius && (i_dot.x - mousePosition.x) > - dots.d_radius && (i_dot.y - mousePosition.y) > - dots.d_radius){
ctx.beginPath();
ctx.moveTo(i_dot.x, i_dot.y);
ctx.lineTo(j_dot.x, j_dot.y);
ctx.stroke();
ctx.closePath();
}
}
}
}
}
};
function createDots(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(var i = 0; i < dots.nb; i++){
dots.array.push(new Dot());
dot = dots.array[i];
dot.create();
}
dot.line();
dot.animate();
}
idle = setInterval(createDots, 1000/30);
$(canvas).on('mousemove mouseleave', function(e){
if(e.type == 'mousemove'){
mousePosition.x = canvas.width / 2;
mousePosition.y = canvas.height / 2;
}
if(e.type == 'mouseleave'){
mousePosition.x = canvas.width / 2;
mousePosition.y = canvas.height / 2;
}
});
});
If you're talking about the pinkish background getting bigger and smaller, I believe it is done with a CSS3 animation http://www.w3schools.com/css/css3_animations.asp
You can see the details following the DOM chain:
<div id="home">
<div>...
<div>...
<div class="bg-layer">
If you were talking about the 3D "Perturbator", then I'd guess something related to 3Dtransforms in a JS script, but I can't tell much more...