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...
Related
I am fairly new to using html canvas. I'm creating a breakout game. I want to implement a fall text when a brick is hit that the paddle at the bottom can catch to increase points.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 4;
var brickColumnCount = 4;
var brickWidth = 50;
var brickHeight = 10;
var brickPadding = 15;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
var reward = { value: 1, x: canvas.width / 2 - 5, y: 20 };
var bricks = [];
for (var c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
for (var r = 0; r < brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1 };
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 37) {
leftPressed = false;
}
}
function mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth / 2;
}
}
function collisionDetection() {
for (var c = 0; c < brickColumnCount; c++) {
for (var r = 0; r < brickRowCount; r++) {
var b = bricks[c][r];
if (b.status == 1) {
if (
x + 5 > b.x &&
x - 5 < b.x + brickWidth &&
y > b.y &&
y < b.y + brickHeight
) {
reward.value++;
reward.x = b.x;
reward.y = b.y;
// drawReward();
// drawReward(x, y);
ctx.font = "16px Arial";
ctx.fillStyle = "#50b848";
ctx.fillText("1GB", 8, 10);
dy = -dy;
b.status = 0;
score++;
if (score == brickRowCount * brickColumnCount) {
alert("YOU WIN, CONGRATS!");
document.location.reload();
}
}
}
}
}
}
function drawBall() {
// var img = document.getElementById("icon");
// var img = new Image();
// img.src = "/images/glo_icon.png";
// ctx.drawImage(img, x, y, 25, 25);
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#50b848";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#50b848";
ctx.fill();
ctx.closePath();
}
function drawBricks() {
for (var c = 0; c < brickColumnCount; c++) {
for (var r = 0; r < brickRowCount; r++) {
if (bricks[c][r].status == 1) {
var brickX = r * (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = c * (brickHeight + brickPadding) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = `#50b848`;
ctx.fill();
ctx.closePath();
}
}
}
}
// function drawReward() {
// // ctx.clearRect(reward.x, reward.y, 30, 30);
// ctx.font = "25px Arial";
// ctx.fillStyle = "#ffffff";
// ctx.fillText(reward.value + "GB", canvas.width / 2 - 5, 20);
// if (y >= 300) {
// y = 290; // Set the ball's Y position to the bottom of the canvas
// dy = 0; //And finally this set the falling is zero
// }
// }
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "purple";
ctx.fillText("Score: " + score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.fillText("Lives: " + lives, canvas.width - 65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawLives();
// drawReward();
collisionDetection();
if (x + dx > canvas.width - ballRadius || x + dx < -5) {
dx = -dx;
}
if (y + dy < -5) {
dy = -dy;
}
if (y + dy > canvas.height - ballRadius) {
if (x > paddleX - 10 && x < paddleX + paddleWidth + 10) {
dy = -dy;
} else {
dy = -dy;
lives--;
if (!lives) {
// alert("GAME OVER");
// document.location.reload();
} else {
x = canvas.width / 2;
y = canvas.height - 30;
dx = 3;
dy = -3;
paddleX = (canvas.width - paddleWidth) / 2;
}
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
draw();
<canvas id="myCanvas"></canvas>
when a brick is hit, at text like "2X" should be drawn from that point and drop down to the bottom so the paddle can pick it up.
thanks for the assistance in advance
You need to be able to render multiple rewards; this is because several blocks may be hit within a short period of time, leading to several falling text items at once.
The only real trick here is to create an array of rewards, create another top-level rendering function named drawRewards (in the plural), and within that function, loop through all rewards in our rewards array, and render them. (Oh, and don't forget to actually add new rewards into the array whenever a block is hit!) I've modified your code to do all these things; let me know if this is what you were looking for:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width / 2;
var y = canvas.height - 30;
var dx = 2;
var dy = -2;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width - paddleWidth) / 2;
var rightPressed = false;
var leftPressed = false;
var brickRowCount = 4;
var brickColumnCount = 4;
var brickWidth = 50;
var brickHeight = 10;
var brickPadding = 15;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;
var reward = { value: 1, x: canvas.width / 2 - 5, y: 20 };
let rewards = [];
var bricks = [];
for (var c = 0; c < brickColumnCount; c++) {
bricks[c] = [];
for (var r = 0; r < brickRowCount; r++) {
bricks[c][r] = { x: 0, y: 0, status: 1 };
}
}
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
document.addEventListener("mousemove", mouseMoveHandler, false);
function keyDownHandler(e) {
if (e.keyCode == 39) {
rightPressed = true;
} else if (e.keyCode == 37) {
leftPressed = true;
}
}
function keyUpHandler(e) {
if (e.keyCode == 39) {
rightPressed = false;
} else if (e.keyCode == 37) {
leftPressed = false;
}
}
function mouseMoveHandler(e) {
var relativeX = e.clientX - canvas.offsetLeft;
if (relativeX > 0 && relativeX < canvas.width) {
paddleX = relativeX - paddleWidth / 2;
}
}
function collisionDetection() {
for (var c = 0; c < brickColumnCount; c++) {
for (var r = 0; r < brickRowCount; r++) {
var b = bricks[c][r];
if (b.status == 1) {
if (
x + 5 > b.x &&
x - 5 < b.x + brickWidth &&
y > b.y &&
y < b.y + brickHeight
) {
reward.value++;
reward.x = b.x;
reward.y = b.y;
rewards.push({ x: b.x, y: b.y, text: '1GB' });
dy = -dy;
b.status = 0;
score++;
if (score == brickRowCount * brickColumnCount) {
document.location.reload();
}
}
}
}
}
}
function drawBall() {
// var img = document.getElementById("icon");
// var img = new Image();
// img.src = "/images/glo_icon.png";
// ctx.drawImage(img, x, y, 25, 25);
ctx.beginPath();
ctx.arc(x, y, ballRadius, 0, Math.PI * 2);
ctx.fillStyle = "#50b848";
ctx.fill();
ctx.closePath();
}
function drawPaddle() {
ctx.beginPath();
ctx.rect(paddleX, canvas.height - paddleHeight, paddleWidth, paddleHeight);
ctx.fillStyle = "#50b848";
ctx.fill();
ctx.closePath();
}
function drawBricks() {
for (var c = 0; c < brickColumnCount; c++) {
for (var r = 0; r < brickRowCount; r++) {
if (bricks[c][r].status == 1) {
var brickX = r * (brickWidth + brickPadding) + brickOffsetLeft;
var brickY = c * (brickHeight + brickPadding) + brickOffsetTop;
bricks[c][r].x = brickX;
bricks[c][r].y = brickY;
ctx.beginPath();
ctx.rect(brickX, brickY, brickWidth, brickHeight);
ctx.fillStyle = `#50b848`;
ctx.fill();
ctx.closePath();
}
}
}
}
function drawRewards() {
for (let reward of rewards) {
reward.y = reward.y + 1;
ctx.font = "12px Arial";
ctx.fillStyle = "#000";
ctx.fillText(reward.text, reward.x, reward.y);
}
// Remove any rewards which fall out of view
rewards = rewards.filter(reward => reward.y < canvas.height);
}
function drawScore() {
ctx.font = "16px Arial";
ctx.fillStyle = "purple";
ctx.fillText("Score: " + score, 8, 20);
}
function drawLives() {
ctx.font = "16px Arial";
ctx.fillStyle = "red";
ctx.fillText("Lives: " + lives, canvas.width - 65, 20);
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBricks();
drawBall();
drawPaddle();
drawScore();
drawRewards();
drawLives();
// drawReward();
collisionDetection();
if (x + dx > canvas.width - ballRadius || x + dx < -5) {
dx = -dx;
}
if (y + dy < -5) {
dy = -dy;
}
if (y + dy > canvas.height - ballRadius) {
if (x > paddleX - 10 && x < paddleX + paddleWidth + 10) {
dy = -dy;
} else {
dy = -dy;
lives--;
if (!lives) {
// alert("GAME OVER");
// document.location.reload();
} else {
x = canvas.width / 2;
y = canvas.height - 30;
dx = 3;
dy = -3;
paddleX = (canvas.width - paddleWidth) / 2;
}
}
}
if (rightPressed && paddleX < canvas.width - paddleWidth) {
paddleX += 7;
} else if (leftPressed && paddleX > 0) {
paddleX -= 7;
}
x += dx;
y += dy;
requestAnimationFrame(draw);
}
draw();
<canvas id="myCanvas"></canvas>
I have grid on a canvas that is running Conway's game of life. But there is a problem when the cells from the game reach the edges in that they cant spread any longer and you can see them just stop. So i was wondering if it is possible to offset the whole grid på 10 cells so that the red lines are not showing. So as to hide the cells hitting the edge.
Here is the code for the grid
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
var cellSize = 16;
var gridColor = "#4a4a4a";
//set canvas resolution to screen resolution
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var cellsInRow = parseInt(ctx.canvas.height/cellSize)+20;
var cellsInCollum = parseInt(ctx.canvas.width/cellSize)+20;
//create array
let arry = [];
for(var i = 0; i < cellsInRow; i++){
arry[i] = [];
for(var j = 0; j < cellsInCollum; j++){
arry[i][j] = 0;
}
}
let arryOld = arry.map(row => [...row]);
//draw on canvas
setInterval(drawCells, 1);
canvasBackground();
canvasGrid();
function getCursonPointer(canvas, event){
const rect = canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
console.log("x: " + x + " y: " + y);
setCell(x, y);
}
canvas.addEventListener('mousedown', function(e){
getCursonPointer(canvas, e);
});
//set cell in array
function setCell(x, y){
for(var i = 0; i < cellsInRow; i++){
for(var j = 0; j < cellsInCollum; j++){
if((y >= (i*cellSize) && y <= ((i*cellSize)+cellSize-1)) &&(x >= (j*cellSize) && x <= ((j*cellSize)+cellSize-1))){
if(arry[i][j] == 0){
arry[i][j] = 1;
}else{
arry[i][j] = 0;
}
}
}
}
}
function drawCells(){
for(var i = 0; i < cellsInRow; i++){
for(var j = 0; j < cellsInCollum; j++){
if(arry[i][j] == 1){
ctx.clearRect(j * cellSize+1, i * cellSize+1, cellSize-2, cellSize-2);
ctx.fillStyle = "white";
ctx.font = "8px Arial";
ctx.fillText(i, j*cellSize + 4, i*cellSize + (cellSize/2));
}else{
ctx.fillStyle ="black";
ctx.fillRect(j * cellSize+1, i * cellSize+1, cellSize-2, cellSize-2);
}
}
}
}
//draw background
function canvasBackground(){
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
//draw the grid
function canvasGrid(){
for(var i = 0; i < cellsInRow; i++){
if(i == 10 || i == cellsInRow-10){
ctx.strokeStyle = "red";
}
else if(i%10 == 0){
ctx.strokeStyle = "white";
}else{
ctx.strokeStyle = gridColor;
}
ctx.beginPath();
ctx.moveTo(0, i*cellSize);
ctx.lineTo(canvas.width, i*cellSize);
ctx.lineWidth = 1;
ctx.stroke();
for(var j = 0; j < cellsInCollum; j++){
if(j == 10 || j == cellsInCollum-10){
ctx.strokeStyle = "red";
}
else if(j%10 == 0){
ctx.strokeStyle = "white";
}else{
ctx.strokeStyle = gridColor;
}
ctx.beginPath();
ctx.moveTo(j*cellSize, 0);
ctx.lineTo(j*cellSize, canvas.height);
ctx.lineWidth = 1;
ctx.stroke();
}
}
}
keep in mind that I want the array to also be offset by the same amount so the upper right corner(under and left of the red lines) would still be arry[10][10].
In the image the black is the canvas and the green is the screen. I basicly want to shift the canvas and grid so that grid position [10][10] is in the corner of the screen. the red lines intersecting is the [10][10] position
Not sure what exactly you're looking for, but if you want a perfect grid that doesn't overflow you can try this.
ctx.canvas.width = window.innerWidth - (window.innerWidth % cellSize * 10 );
ctx.canvas.height = window.innerHeight - (window.innerHeight % cellSize * 10);
var cellsInRow = ctx.canvas.height / cellSize;
var cellsInCollum = ctx.canvas.width / cellSize;
You are ignoring that extra width and height of window that can have a partial grid that is not perfect 10 * 10
I'm making a simple memory game and I have put a short delay after 2 cards have been flipped face up and before they are checked for a match. If they are unmatched they will then flip back face down. The problem I'm having is that the delay comes before the second card is flipped face up even though it comes afterwards in the code, resulting in the second card not showing face up. I'm using the drawImage function with pre-loaded images so the call shouldn't have to wait for an image to load. I've added my code below and commented after the draw face up and delay functions.
An online version: http://dtc-wsuv.org/mscoggins/hiragana/seindex.html
var ROWS = 2;
var COLS = 3;
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.width = COLS * 80 + (COLS - 1) * 10 + 40;
canvas.height = ROWS * 100 + (ROWS - 1) * 10 + 40;
var Card = function(x, y, img) {
this.x = x;
this.y = y;
this.w = 80;
this.h = 100;
this.r = 10;
this.img = img;
this.match = false;
};
Card.prototype.drawFaceDown = function() {
this.drawCardBG();
ctx.beginPath();
ctx.fillStyle = "red";
ctx.arc(this.w / 2 + this.x, this.h / 2 + this.y, 15, 0, 2 * Math.PI);
ctx.fill();
ctx.closePath();
this.isFaceUp = false;
};
Card.prototype.drawFaceUp = function() {
this.drawCardBG();
var imgW = 57;
var imgH = 70;
var imgX = this.x + (this.w - imgW) / 2;
var imgY = this.y + (this.h - imgH) / 2;
ctx.drawImage(this.img, imgX, imgY, imgW, imgH);
this.isFaceUp = true;
};
Card.prototype.drawCardBG = function() {
ctx.beginPath();
ctx.fillStyle = "white";
ctx.fillRect(this.x, this.y, this.w, this.h);
ctx.closePath();
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
ctx.moveTo(this.x + this.r, this.y);
ctx.lineTo(this.w + this.x - this.r * 2, this.y);
ctx.arcTo(this.w + this.x, this.y, this.w + this.x, this.y + this.r, this.r);
ctx.lineTo(this.w + this.x, this.h + this.y - this.r * 2);
ctx.arcTo(this.w + this.x, this.h + this.y, this.w + this.x - this.r, this.h + this.y, this.r);
ctx.lineTo(this.x + this.r, this.h + this.y);
ctx.arcTo(this.x, this.h + this.y, this.x, this.h + this.y - this.r, this.r);
ctx.lineTo(this.x, this.y + this.r);
ctx.arcTo(this.x, this.y, this.x + this.r, this.y, this.r);
ctx.stroke();
ctx.closePath();
};
Card.prototype.mouseOverCard = function(x, y) {
return x >= this.x && x <= this.x + this.w && y >= this.y && y <= this.y + this.h;
};
var imgLib = [
'img/a.png', 'img/ka.png', 'img/sa.png', 'img/ta.png', 'img/na.png', 'img/ha.png',
'img/ma.png', 'img/ya.png', 'img/ra.png', 'img/wa.png', 'img/i.png', 'img/ki.png',
'img/shi.png', 'img/chi.png', 'img/ni.png', 'img/hi.png', 'img/mi.png', 'img/ri.png',
'img/u.png', 'img/ku.png', 'img/su.png', 'img/tsu.png', 'img/nu.png', 'img/hu.png',
'img/mu.png', 'img/yu.png', 'img/ru.png', 'img/n.png', 'img/e.png', 'img/ke.png',
'img/se.png', 'img/te.png', 'img/ne.png', 'img/he.png', 'img/me.png', 'img/re.png',
'img/o.png', 'img/ko.png', 'img/so.png', 'img/to.png', 'img/no.png', 'img/ho.png',
'img/mo.png', 'img/yo.png', 'img/ro.png', 'img/wo.png'
];
var imgArray = [];
imgArray = imgLib.slice();
var flippedCards = [];
var numTries = 0;
var doneLoading = function() {};
canvas.addEventListener("click", function(e) {
for(var i = 0;i < cards.length;i++) {
var mouseX = e.clientX - e.currentTarget.offsetLeft;
var mouseY = e.clientY - e.currentTarget.offsetTop;
if(cards[i].mouseOverCard(mouseX, mouseY)) {
if(flippedCards.length < 2 && !this.isFaceUp) {
cards[i].drawFaceUp(); //draw card face up
flippedCards.push(cards[i]);
if(flippedCards.length === 2) {
numTries++;
if(flippedCards[0].img.src === flippedCards[1].img.src) {
flippedCards[0].match = true;
flippedCards[1].match = true;
}
delay(600); //delay after image has been drawn
checkMatches();
}
}
}
}
var foundAllMatches = true;
for(var i = 0;i < cards.length;i++) {
foundAllMatches = foundAllMatches && cards[i].match;
}
if(foundAllMatches) {
var winText = "You Win!";
var textWidth = ctx.measureText(winText).width;
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "red";
ctx.font = "40px Arial";
ctx.fillText(winText, canvas.width / 2 - textWidth, canvas.height / 2);
}
}, false);
var gameImages = [];
for(var i = 0;i < ROWS * COLS / 2;i++) {
var imgId = Math.floor(Math.random() * imgArray.length);
var match = imgArray[imgId];
gameImages.push(match);
gameImages.push(match);
imgArray.splice(imgId, 1);
}
gameImages.sort(function() {
return 0.5 - Math.random();
});
var cards = [];
var loadedImages = [];
var index = 0;
var imgLoader = function(imgsToLoad, callback) {
for(var i = 0;i < imgsToLoad.length;i++) {
var img = new Image();
img.src = imgsToLoad[i];
loadedImages.push(img);
cards.push(new Card(0, 0, img));
img.onload = function() {
if(loadedImages.length >= imgsToLoad.length) {
callback();
}
};
}
for(var i = 0;i < COLS;i++) {
for(var j = 0;j < ROWS;j++) {
cards[index].x = i * 80 + i * 10 + 20;
cards[index].y = j * 100 + j * 10 + 20;
index++;
}
}
for(var i = 0;i < cards.length;i++) {
cards[i].drawFaceDown();
}
};
imgLoader(gameImages, doneLoading);
var checkMatches = function() {
for(var i = 0;i < cards.length;i++) {
if(!cards[i].match) {
cards[i].drawFaceDown();
}
}
flippedCards = [];
};
var delay = function(ms) {
var start = new Date().getTime();
var timer = false;
while(!timer) {
var now = new Date().getTime();
if(now - start > ms) {
timer = true;
}
}
};
The screen won't be refreshed until your function exits. The usual way to handle this is using setTimeout. Put the code that you want to run after the delay in a separate function and use setTimeout to call that function after the desired delay. Note that setTimeout will return immediately; the callback will be executed later.
I have implemented this below, just replace your click event listener code with the following:
canvas.addEventListener("click", function(e) {
for(var i = 0;i < cards.length;i++) {
var mouseX = e.clientX - e.currentTarget.offsetLeft;
var mouseY = e.clientY - e.currentTarget.offsetTop;
if(cards[i].mouseOverCard(mouseX, mouseY)) {
if(flippedCards.length < 2 && !this.isFaceUp) {
cards[i].drawFaceUp(); //draw card face up
flippedCards.push(cards[i]);
if(flippedCards.length === 2) {
numTries++;
if(flippedCards[0].img.src === flippedCards[1].img.src) {
flippedCards[0].match = true;
flippedCards[1].match = true;
}
//delay(600); //delay after image has been drawn
//checkMatches();
window.setTimeout(checkMatchesAndCompletion, 600);
}
}
}
}
function checkMatchesAndCompletion() {
checkMatches();
var foundAllMatches = true;
for(var i = 0;i < cards.length;i++) {
foundAllMatches = foundAllMatches && cards[i].match;
}
if(foundAllMatches) {
var winText = "You Win!";
var textWidth = ctx.measureText(winText).width;
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "red";
ctx.font = "40px Arial";
ctx.fillText(winText, canvas.width / 2 - textWidth, canvas.height / 2);
}
}
}, false);
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 was wondering if it was possible to have mouseover events with multiple squares on a canvas
this is my code right now: http://jsfiddle.net/2j3u9f7m/
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var Enemy = function (x, y, velx, vely) {
this.x = x;
this.y = y;
this.velx = 0;
this.vely = 0;
}
Enemy.prototype.update = function () {
var tx = 650 - this.x;
var ty = 250 - this.y;
var dist = Math.sqrt(tx * tx + ty * ty);
this.velx = (tx / dist);
this.vely = (ty / dist);
if (dist > 0) {
this.x += this.velx;
this.y += this.vely;
}
};
Enemy.prototype.render = function () {
context.fillStyle = '#000000';
context.beginPath();
context.rect(this.x, this.y, 25, 25);
context.fill();
context.closePath();
};
var enemies = [];
for (var i = 0; i < 10; i++) {
// random numbers from 0 (inclusive) to 100 (exclusive) for example:
var randomX = Math.random() * 896;
var randomY = Math.random() * 1303;
console.log(randomX);
console.log(randomY);
if (randomX > 100 && randomX < 1200) {
if (randomX % 2 == 0) {
randomX = 140;
} else {
randomX = 1281;
}
}
if (randomY > 100 && randomY < 75) {
if (randomY % 2 == 0) {
randomY = 15;
} else {
randomY = 560;
}
}
var enemy = new Enemy(randomX, randomY, 0, 0);
enemies.push(enemy);
}
for (var i = 0; i < 15; i++) {
// random numbers from 0 (inclusive) to 100 (exclusive) for example:
var randomX = Math.random() * 200;
var randomY = Math.random() * 403;
console.log(randomX);
console.log(randomY);
if (randomX > 100 && randomX < 1200) {
if (randomX % 2 == 0) {
randomX = 140;
} else {
randomX = 1281;
}
}
if (randomY > 100 && randomY < 75) {
if (randomY % 2 == 0) {
randomY = 15;
} else {
randomY = 560;
}
}
var enemy = new Enemy(randomX, randomY, 0, 0);
enemies.push(enemy);
}
function render() {
context.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < enemies.length; i++) {
var one = enemies[i];
one.update();
one.render();
}
requestAnimationFrame(render);
}
render();
What I want to do is to have a mouseover event for each square; is there a way to do this without using a library?
You can extend your Enemy object doing a region check like this:
Enemy.prototype.isOnEnemy = function(x, y) {
return (x >= this.x && x < this.x + 25 && // 25 = width
y >= this.y && y < this.y + 25); // 25 = height
};
If the provided (x,y) position is inside the rectangle (here assuming width and height of 25) it will return true.
Then add a mousemove event listener to the canvas. Inside adjust the mouse position, then feed the muse position to each enemy object to check:
context.canvas.onmousemove = function(e) {
var rect = this.getBoundingClientRect(), // correct mouse position
x = e.clientX - rect.left,
y = e.clientY - rect.top,
i = 0;
for(; i < enemies.length; i++) { // check each enemy
if (enemies[i].isOnEnemy(x, y)) { // is inside?
console.log("AAAARG...", i); // some action...
}
}
};
Modified fiddle (see console for hits).