Draw moving line in phaser 3 - javascript

I want to draw line, where it's first pair of coordinates situated in the center of drew circle and it's second pair will be unsettled until I direct it to the cirlce with the same color, which have first one. Do you have any ideas?
My code:
let config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: '#f0ebeb',
physics: {
default: 'arcade',
arcade: {
gravity: { y: 300 },
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
},
scale: {
autoCenter: Phaser.Scale.CENTER_BOTH
}
};
let game = new Phaser.Game(config);
let items = [];
let dots = new Map([
[1, '#4293f5'],
[2, '#42f554'],
[3, '#f5e942'],
[4, '#f55a42'],
[5, '#f542c8'],
])
function preload() {
}
function create() {
let x = 100;
let y = 0;
for (i = 0; i < 36; i++) {
if (i % 6 === 0) {
y += 85;
x = 100;
}
this.add.circle(x, y, 35, parseInt(dots.get(getRandomInt(5)).replace(/^#/, ''), 16));
x += 125;
}
}
function update() { }
function getRandomInt(max) {
return Math.floor(Math.random() * max) + 1;
}
What I am trying to do: https://play.google.com/store/apps/details?id=com.nerdyoctopus.gamedots

A quick possible solution could be to use the pointer Events (pointerdown, pointermove and pointerup) of the scene. Here is a demo code, with the basic functionality
let config = {
type: Phaser.AUTO,
parent: 'phaser-example',
width: 400,
height: 200,
scene: { create }
};
let game = new Phaser.Game(config);
let isDragging = false;
let lineStartPosition = {x:0 , y:0};
let line;
function create ()
{
let cicles = []
for(let rowIdx = 0; rowIdx < 4; rowIdx++ ){
for(let colIdx = 0; colIdx < 2; colIdx++ ){
let circle = this.add.circle(50 + 100 * rowIdx, 50 + 100 * colIdx, 25, 0x6666ff).setOrigin(.5);
circle.setInteractive();
cicles.push(circle);
}
}
line = this.add.line(0,0, 0,0, 100, 100, 0xffffff).setOrigin(0);
line.setLineWidth(5);
line.visible = false;
// adding the events to the scene
this.input.on('pointerdown', dragStart);
this.input.on('pointerup', dragEnd);
this.input.on('pointermove', drag);
}
function dragStart(pointer, gameObjects){
if(gameObjects.length == 0)
return
lineStartPosition.x = gameObjects[0].x;
lineStartPosition.y = gameObjects[0].y;
isDragging = true;
line.x = gameObjects[0].x;
line.y = gameObjects[0].y;
line.setTo(0, 0, 0, 0);
line.visible = true;
}
function drag(pointer, gameObject){
if(isDragging == true){
line.setTo(0, 0, pointer.x - lineStartPosition.x, pointer.y - lineStartPosition.y);
}
}
function dragEnd(pointer, gameObject){
isDragging = false;
}
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

Related

phaser 3 Trying to make bullet travel towards a location

i am trying to make my bullet travel towards the cursor location. I have tried lots of things and I just can't get it to work. I have the player arm set up to always move to the player shoulder level. The player's arm and the gun has the same rotation value. The rotation value is calculated using Phaser.Math.Angle.BetweenPoints(playerArm, player1Aim);. I found a couple examples but i couldn't get them to work. Please teach me how to use it. I am a newbie. Please help. Here is my code:
var config = {
type: Phaser.AUTO,
width: 512,
height: 512,
physics: {
default: 'arcade',
arcade: {
gravity: {
y: 1500
},
debug: false
}
},
scene: {
preload: preload,
create: create,
update: update
}
// plugins: {
// global: [{
// key: 'PhaserPauseRenderPlugin',
// plugin: PhaserPauseRenderPlugin,
// mapping: 'render'
// }]
// }
};
// class SceneMain extends Phaser.Scene {
// constructor() {
// super('SceneMain');
// }
// preload() {}
// create() {
// //make 3 bars
// let healthBar = this.makeBar(140, 100, 0x2ecc71);
// this.setValue(healthBar, 100);
// // let powerBar = this.makeBar(140, 200, 0xe74c3c);
// // this.setValue(powerBar, 50);
// // let magicBar = this.makeBar(140, 300, 0x2980b9);
// // this.setValue(magicBar, 33);
// }
// makeBar(x, y, color) {
// //draw the bar
// let bar = this.add.graphics();
// //color the bar
// bar.fillStyle(color, 1);
// //fill the bar with a rectangle
// bar.fillRect(0, 0, 200, 50);
// //position the bar
// bar.x = x;
// bar.y = y;
// //return the bar
// return bar;
// }
// setValue(bar, percentage) {
// //scale the bar
// bar.scaleX = percentage / 100;
// }
// update() {}
// }
var player;
var platforms;
var cursors;
var gameOver = false;
var score = 0;
var time;
var waves;
var enemies;
var enemy;
var health;
var hacking = false;
var timer;
var enemyCount = 0;
var startGame = false;
var timeSpeed = 1;
var keys;
var damageStrike = 0;
var toMouse = 0;
var toPlayer = 0;
var bullets;
var ship;
var speed;
var stats;
var cursors;
var lastFired = 0;
var fire = false;
var pointerDown = false;
// var healthBar = new SceneMain();
// spaceBar input
// var spaceBar = Phaser.Input.Keyboard.KeyCodes.SPACE;
var game = new Phaser.Game(config);
function preload() {
//this.load.image('platform', 'images/platform.png');
// this.load.image('background', 'images/background.png');z
this.load.image('background', 'images/background.png');
this.load.image('platform', 'images/platform.png');
this.load.image('longPlatform', 'images/platform long.png');
this.load.image('itembg', 'images/item bg.png');
this.load.image('playerArm', 'images/player arm.png');
this.load.image('enemyArm', 'images/enemy arm.png');
this.load.image('playerGun', 'images/player gun.png');
this.load.image('enemyGun', 'images/enemy gun.png');
this.load.image('medkit', 'images/medkit.png');
this.load.image('aim', 'images/aim.png');
this.load.image('bullet', 'images/laser.png');
this.load.spritesheet('player', 'images/player idle-1.png', {
frameWidth: 49,
frameHeight: 128
});
this.load.spritesheet('enemy', 'images/enemy.png', {
frameWidth: 49,
frameHeight: 128
});
}
function create() {
// var Bullet = new Phaser.Class({
// Extends: Phaser.GameObjects.Image,
// initialize:
// // Bullet Constructor
// function Bullet(scene) {
// Phaser.GameObjects.Image.call(this, scene, 0, 0, 'bullet');
// this.speed = 1;
// this.born = 0;
// this.direction = 0;
// this.xSpeed = 0;
// this.ySpeed = 0;
// this.setSize(12, 12, true);
// },
// // Fires a bullet from the player to the reticle
// fire: function(player, target) {
// this.setPosition(player.x, player.y); // Initial position
// this.direction = Math.atan((target.x - this.x) / (target.y - this.y));
// // Calculate X and y velocity of bullet to moves it from shooter to target
// if (target.y >= this.y) {
// this.xSpeed = this.speed * Math.sin(this.direction);
// this.ySpeed = this.speed * Math.cos(this.direction);
// } else {
// this.xSpeed = -this.speed * Math.sin(this.direction);
// this.ySpeed = -this.speed * Math.cos(this.direction);
// }
// this.rotation = player.rotation; // angle bullet with shooters rotation
// this.born = 0; // Time since new bullet spawned
// },
// // Updates the position of the bullet each cycle
// update: function(time, delta) {
// this.x += this.xSpeed * delta;
// this.y += this.ySpeed * delta;
// this.born += delta;
// if (this.born > 500) {
// this.setActive(false);
// this.setVisible(false);
// }
// }
// });
// playerBullets = this.physics.add.group({
// classType: Bullet,
// runChildUpdate: true
// });
speed = Phaser.Math.GetSpeed(300, 1);
// healthBar.makeBar(32, 32, 0xffffff);
// console.log(timer);
// add background
// this.add.image(256, 256, 'background');
background = this.add.image(256, 256, 'background');
background.alpha = 0.8;
itemBg = this.add.image(256, 520, 'itembg')
platforms = this.physics.add.staticGroup();
// Here we create the ground.
platforms.create(256, 450, 'longPlatform').refreshBody();;
// platforms.create(256, 450, 'platform');
platforms.create(50, 175, 'platform');
platforms.create(460, 175, 'platform');
platforms.create(50, 350, 'platform');
platforms.create(460, 350, 'platform');
platforms.create(265, 250, 'platform');
player = this.physics.add.sprite(256, 10, 'player');
player.setScale(0.5);
player.setBounce(0.1);
player.setCollideWorldBounds(true);
playerArm = this.add.image(256, 256, 'playerArm');
playerArm.setScale(0.5);
playerArm.angle = 0;
playerGun = this.add.image(256, 256, 'playerGun');
playerGun.setScale(0.5);
playerGun.angle = 0;
enemyArm = this.add.image(256, 256, 'enemyArm');
enemyArm.setScale(0.5);
enemyArm.angle = 0;
enemyGun = this.add.image(256, 256, 'enemyGun');
enemyGun.setScale(0.5);
enemyGun.angle = 0;
player1Aim = this.add.image(256, 256, 'aim');
player1Aim.setScale(2);
player1Aim.angle = 0;
bullet = this.add.image(256, 10, 'bullet');
bullet.setScale(0.25);
bullet.angle = 0;
var playerX = player.x;
var playerY = player.y;
enemies = this.physics.add.group();
medkits = this.physics.add.group();
spawn = (x, enemyName) => {
enemyPlayer = this.physics.add.sprite(x, 20, enemyName);
// enemyPlayer = this.physics.add.sprite.destroy(true);
console.log(enemyPlayer);
enemyPlayer.setScale(0.5);
enemyPlayer.setBounce(0.1);
enemyPlayer.setCollideWorldBounds(true);
enemyPlayer.allowGravity = true;
return enemyPlayer;
}
spawnMedkit = (x, enemyName) => {
enemyPlayer = this.physics.add.sprite(x, 20, enemyName);
// enemyPlayer = this.physics.add.sprite.destroy(true);
console.log(enemyPlayer);
enemyPlayer.setScale(1);
enemyPlayer.setBounce(0.1);
enemyPlayer.setCollideWorldBounds(true);
enemyPlayer.allowGravity = true;
return enemyPlayer;
}
enemy = spawn(450, 'enemy');
medkit = spawnMedkit(100, 'medkit');
enemyCount += 1;
console.log(enemyCount);
// enemy = enemies.create(450, 20, 'enemy')
// // enemies.create(250, 20, 'enemy')
// enemy.setScale(0.5)
// enemy.setBounce(0.1);
// enemy.setCollideWorldBounds(true);
// enemy.allowGravity = true;
cursors = this.input.keyboard.createCursorKeys();
this.physics.add.collider(player, platforms);
this.physics.add.collider(enemy, platforms);
this.physics.add.collider(medkit, platforms);
// this.physics.add.collider(bombs, platforms);
health = 100;
waves = 0;
// timer = this.time.create(false);
// The score
scoreText = this.add.text(16, 16, 'score: 0', {
fontSize: '25px',
fill: '#00FFFF'
});
// FPS
fps = this.add.text(16, 50, game.loop.actualFps, {
fontSize: '15px',
fill: '#00FFFF'
});
timeScale = this.add.text(16, 70, this.physics.world.timeScale, {
fontSize: '15px',
fill: '#00FFFF'
});
gunRotation = this.add.text(16, 100, 'gun rotation: 0', {
fontSize: '15px',
fill: '#00FFFF'
});
// gameStatus = this.add.text(16, 60, 'Game Status: Alive', {
// fontSize: '25px',
// fill: '#00FFFF'
// });
// hp = this.add.text(16, 100, 'Health: ' + health, {
// fontSize: '25px',
// fill: '#00FFFF'
// });
// add collisions
this.physics.add.collider(player, enemy, damage, null, this);
this.physics.add.collider(player, medkit, healByMedkit, null, this);
// this.physics.add.collider(laser, enemy, hit, null, this);
keys = this.input.keyboard.addKeys('W,A,S,D,F,J,K,L,SPACE');
var r1 = this.add.rectangle(playerX, playerY - 15, 200, 69, 10, 0x6666ff);
this.input.on('pointermove', function(pointer) {
toMouse = Phaser.Math.Angle.BetweenPoints(playerArm, player1Aim);
});
this.input.on('pointerdown', function(pointer) {
// shoot the bullet towards the cursor (player1Aim)
});
startGame = true;
}
function update(time, delta) {
var playerX = player.x;
var playerY = player.y;
var enemyX = enemy.x;
var enemyY = enemy.y;
var playerArmX = playerArm.x;
var playerArmY = playerArm.y;
var playerArmRotation = playerArm.angle;
var mouseX = game.input.mousePointer.x;
var mouseY = game.input.mousePointer.y;
// var theta =
// console.log(playerArmRotation);
// position the arm to the shoulder level of the player
playerArm.x = playerX;
playerArm.y = playerY - 5;
playerGun.x = playerX;
playerGun.y = playerY - 3;
enemyArm.x = enemyX;
enemyArm.y = enemyY - 5;
enemyGun.x = enemyX;
enemyGun.y = enemyY - 5;
player1Aim.x = mouseX;
player1Aim.y = mouseY;
toPlayer = Phaser.Math.Angle.BetweenPoints(enemy, player);
playerArm.rotation = Phaser.Math.Angle.BetweenPoints(playerArm, player1Aim);
playerGun.rotation = Phaser.Math.Angle.BetweenPoints(playerArm, player1Aim);
enemyArm.rotation = toPlayer;
enemyGun.rotation = toPlayer;
// rotate gun for player
if (playerGun.angle >= 90 || playerGun.angle <= -90) {
playerGun.flipY = true;
// console.log('flipped')
} else {
playerGun.flipY = false;
}
// rotate gun for player
if (enemyGun.angle >= 90 || enemyGun.angle <= -90) {
enemyGun.flipY = true;
// console.log('flipped')
} else {
enemyGun.flipY = false;
}
// this.input.on('pointerdown', function(pointer) {
// if (pointerDown == false) {
// pointerDown = true;
// fire();
// console.log('FIRE');
// } else {
// pointerDown = false;
// }
// });
// this.input.on('pointerdown', function(pointer, time, lastFired) {
// if (player.active === false)
// return;
// // Get bullet from bullets group
// var bullet = playerBullets.get().setActive(true).setVisible(true);
// if (bullet) {
// bullet.fire(playerGun, player1Aim);
// // this.physics.add.collider(enemy, bullet, enemyHitCallback);
// }
// }, this);
// this.input.on('pointerdown', function(pointer) {
// if (time > lastFired) {
// var bullet = bullets.get();
// console.log('test2');
// if (bullet) {
// // bullet.rotation = playerGun.rotation;
// bullet.fire(playerGun.x, playerGun.y);
// lastFired = time + 50;
// }
// }
// });
if (startGame == true) {
if (keys.J.isDown) {
this.physics.world.timeScale = 1.75;
// console.log(this.physics.world.timeScale);
// timeSpeed = 0.5;
// console.log(timeSpeed);
} else
if (keys.K.isDown) {
this.physics.world.timeScale = 0.75;
// timeSpeed = 1;
}
if (keys.L.isDown) {
}
if (gameOver) {
return;
gameStatus.setText('Game Status: Dead')
}
if (cursors.left.isDown || keys.A.isDown) {
player.setVelocityX(-160 * timeSpeed);
} else if (cursors.right.isDown || keys.D.isDown) {
player.setVelocityX(160 * timeSpeed);
} else {
player.setVelocityX(0 * timeSpeed);
}
if (cursors.up.isDown && player.body.touching.down) {
player.setVelocityY(-650 * timeSpeed);
}
if (keys.W.isDown && player.body.touching.down) {
player.setVelocityY(-650 * timeSpeed);
}
if (keys.SPACE.isDown && player.body.touching.down) {
player.setVelocityY(-650 * timeSpeed);
}
if (waves == 0) {
waves += 1;
console.log(waves)
}
fps.setText('fps: ' + game.loop.actualFps);
scoreText.setText('Score: ' + score);
timeScale.setText('timeScale: ' + this.physics.world.timeScale);
gunRotation.setText('gun rotation: ' + playerGun.angle);
}
}
function damage(player, enemy) {
enemy.disableBody(true, true);
// enemy.body.enable = false;
// enemy.body.gameObject.active = false;
enemyCount -= 1;
console.log(enemyCount);
health -= 10;
score -= 10;
damageStrike += 1;
if (enemyCount === 0) {
var randomX = Phaser.Math.FloatBetween(0, 500);
enemy.enableBody(true, randomX, 15, true, true);
enemyCount += 1;
console.log(enemyCount);
}
if (damageStrike === 3 && medkits.countActive(false) == 0) {
var randomX = Phaser.Math.FloatBetween(0, 500);
medkit.enableBody(true, randomX, 15, true, true);
damageStrike = 0;
}
console.log('Health: ' + health);
if (health <= 0) {
gameOver = true;
}
}
function hit(laser, enemy) {
score += 10;
enemy.disableBody(true, true);
}
function healByMedkit(player, medkit) {
score += 5;
health += 15;
console.log(health);
medkit.disableBody(true, true);
}
Well if you want to rotate a gameObjects and shoot something in a specific angle, in Phaser you should have to keep somethings in mind:
Origin of the gameObject (since the rotation occurs around this point)
The direction / angle offset of the gameObject you want to rotate
Apart from that, everything is more or less straightforward, calculate the vector for "shooting" a bullet and set the velocity of that bullet.
Here a short demo:
In this Demo, the both main factors are shown, origin and "angle-offset".
(It should cover the basic from your code)
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 50 },
}
},
scene: {
create,
update
},
banner: false
};
function create () {
this.add.text(10, 10, 'Click to shoot bullets')
.setOrigin(0);
// head
this.add.circle ( 42, 60, 8, 0xffffff)
.setOrigin(0);
// body
let player = this.add.rectangle( 40, 80, 20, 50, 0xffffff)
.setOrigin(0);
// sholder
this.add.circle ( 50, 90, 5, 0xff0000)
.setOrigin(0.5);
// arm
let playerArm = this.add.rectangle( 50, 90, 10, 30, 0xff0000)
// Point #1: the Point of rotation is more or less the shoulder
.setOrigin(.5, 0)
.setDepth(10);
// create bullet Group
this.bullets = this.add.group();
this.input.on('pointermove', pointer => {
let rotation = Phaser.Math.Angle.BetweenPoints(playerArm, pointer);
// Point #2: Angle-Offset since the 0 Degrees is on the right,
// and the arm is pointing down I need to subtract 90° 0 PI/2
playerArm.rotation = rotation - Math.PI / 2;
});
this.input.on('pointerdown', pointer => {
let speed = 300;
// create bullet
let bullet = this.add.circle( playerArm.x, playerArm.y, 4, 0xffff00)
.setDepth(9);
this.physics.add.existing(bullet);
// get Vector where to shoot bullet
let vector = new Phaser.Math.Vector2( pointer.x - playerArm.x, pointer.y - playerArm.y );
// set Speed of bullet
vector.setLength(speed);
// DEMO: to shoot in a straightline, just comment the following line in
// bullet.body.setAllowGravity(false);
// DEMO: QuickFix to destroy the bullet after 1 Second automatically
// setTimeout( () => bullet.destroy(), 1000);
// add bullet to group
this.bullets.add(bullet);
bullet.body.setVelocity(vector.x, vector.y);
});
}
function update(){
this.bullets.getChildren().forEach(bullet => {
if(bullet.x > config.width){
bullet.destroy();
}
})
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
If you want the bullet to fly without gravity / in a straight line, just add this line bullet.body.setAllowGravity(false); after the creation of the bullet, to turn off the physics effect for the bullet.

How do I add a rectangle to the zoomed canvas area?

I'm using Fabric JS. Every time I press the Add Door button it creates on the upper left. I gave the values ​​in the rectangle (left: 40, top: 40,).
However, when I press the button while I am on the area I zoomed, I want it to add it to the area I zoomed. I looked at a few examples but could not find what I wanted. How can I do that?
Video
var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage('https://i.hizliresim.com/0pIPiv.jpg', canvas.renderAll.bind(canvas));
var uniqids = 0;
$("#door").on("click", function(e) {
rect = new fabric.Rect({
id:uniqid,
left: 40,
top: 40,
width: 35,
height: 50,
fill: 'blue',
stroke: 'blue',
strokeWidth: 5,
strokeUniform: false,
hasControls : true,
});
var uniqid = uniqids.toString();
var text = new fabric.Text(uniqid, {
fontSize: 30,
originX: 'center',
originY: 'right'
});
var group = new fabric.Group([ rect, text ], {
left: 0,
top: 100,
});
canvas.add(group);
uniqids++;
canvas.on('selection:cleared', c => {
console.log("empty");
});
canvas.selection = false;
});
//*****************************
// canvas.on('mouse:wheel', function(opt) {
// var delta = opt.e.deltaY;
// var zoom = canvas.getZoom();
// zoom *= 0.999 ** delta;
// if (zoom > 20) zoom = 20;
// if (zoom < 0.01) zoom = 0.01;
// canvas.setZoom(zoom);
// opt.e.preventDefault();
// opt.e.stopPropagation();
// })
$('#getid').click(function() {
var activeObject = canvas.getActiveObjects();
alert(canvas.getActiveObject().id);
});
//***************************************
$("#save").on("click", function(e) {
$(".save").html(canvas.toSVG());
});
$('#delete').click(function() {
var activeObject = canvas.getActiveObjects();
canvas.discardActiveObject();
canvas.remove(...activeObject);
});
$("#btnResetZoom").on("click", function(e) {
canvas.setViewportTransform([1,0,0,1,0,0]);
});
canvas.on('mouse:wheel', function(opt) {
var delta = opt.e.deltaY;
var zoom = canvas.getZoom();
zoom *= 0.999 ** delta;
if (zoom > 20) zoom = 20;
if (zoom < 1) zoom = 1;
canvas.zoomToPoint({x: opt.e.offsetX, y: opt.e.offsetY}, zoom);
opt.e.preventDefault();
opt.e.stopPropagation();
});
var shiftKeyDown = true;
var mouseDownPoint = null;
canvas.on('mouse:move', function(options) {
if (shiftKeyDown && mouseDownPoint) {
var pointer = canvas.getPointer(options.e, true);
var mouseMovePoint = new fabric.Point(pointer.x, pointer.y);
canvas.relativePan(mouseMovePoint.subtract(mouseDownPoint));
mouseDownPoint = mouseMovePoint;
keepPositionInBounds(canvas);
}
});
var Direction = {
LEFT: 0,
UP: 1,
RIGHT: 2,
DOWN: 3
};
var zoomLevel = 0;
var zoomLevelMin = 0;
var zoomLevelMax = 3;
var shiftKeyDown = false;
var mouseDownPoint = null;
canvas.on('mouse:down', function(options) {
var pointer = canvas.getPointer(options.e, true);
mouseDownPoint = new fabric.Point(pointer.x, pointer.y);
});
canvas.on('mouse:up', function(options) {
mouseDownPoint = null;
});
canvas.on('mouse:move', function(options) {
if (shiftKeyDown && mouseDownPoint) {
var pointer = canvas.getPointer(options.e, true);
var mouseMovePoint = new fabric.Point(pointer.x, pointer.y);
canvas.relativePan(mouseMovePoint.subtract(mouseDownPoint));
mouseDownPoint = mouseMovePoint;
keepPositionInBounds(canvas);
}
});
fabric.util.addListener(document.body, 'keydown', function(options) {
if (options.repeat) {
return;
}
var key = options.which || options.keyCode; // key detection
if (key == 16) { // handle Shift key
canvas.defaultCursor = 'move';
canvas.selection = false;
shiftKeyDown = true;
} else if (key === 37) { // handle Left key
move(Direction.LEFT);
} else if (key === 38) { // handle Up key
move(Direction.UP);
} else if (key === 39) { // handle Right key
move(Direction.RIGHT);
} else if (key === 40) { // handle Down key
move(Direction.DOWN);
}
});
fabric.util.addListener(document.body, 'keyup', function(options) {
var key = options.which || options.keyCode; // key detection
if (key == 16) { // handle Shift key
canvas.defaultCursor = 'default';
canvas.selection = true;
shiftKeyDown = false;
}
});
// jQuery('.canvas-container').on('mousewheel', function(options) {
// var delta = options.originalEvent.wheelDelta;
// if (delta != 0) {
// var pointer = canvas.getPointer(options.e, true);
// var point = new fabric.Point(pointer.x, pointer.y);
// if (delta > 0) {
// zoomIn(point);
// } else if (delta < 0) {
// zoomOut(point);
// }
// }
// });
function move(direction) {
switch (direction) {
case Direction.LEFT:
canvas.relativePan(new fabric.Point(-10 * canvas.getZoom(), 0));
break;
case Direction.UP:
canvas.relativePan(new fabric.Point(0, -10 * canvas.getZoom()));
break;
case Direction.RIGHT:
canvas.relativePan(new fabric.Point(10 * canvas.getZoom(), 0));
break;
case Direction.DOWN:
canvas.relativePan(new fabric.Point(0, 10 * canvas.getZoom()));
break;
}
keepPositionInBounds(canvas);
}
// function zoomIn(point) {
// if (zoomLevel < zoomLevelMax) {
// zoomLevel++;
// canvas.zoomToPoint(point, Math.pow(2, zoomLevel));
// keepPositionInBounds(canvas);
// }
// }
// function zoomOut(point) {
// console.log(zoomLevel, zoomLevelMin);
// if (zoomLevel > zoomLevelMin) {
// zoomLevel--;
// canvas.zoomToPoint(point, Math.pow(2, zoomLevel));
// keepPositionInBounds(canvas);
// }
// }
function keepPositionInBounds() {
var zoom = canvas.getZoom();
var xMin = (2 - zoom) * canvas.getWidth() / 2;
var xMax = zoom * canvas.getWidth() / 2;
var yMin = (2 - zoom) * canvas.getHeight() / 2;
var yMax = zoom * canvas.getHeight() / 2;
var point = new fabric.Point(canvas.getWidth() / 2, canvas.getHeight() / 2);
var center = fabric.util.transformPoint(point, canvas.viewportTransform);
var clampedCenterX = clamp(center.x, xMin, xMax);
var clampedCenterY = clamp(center.y, yMin, yMax);
var diffX = clampedCenterX - center.x;
var diffY = clampedCenterY - center.y;
if (diffX != 0 || diffY != 0) {
canvas.relativePan(new fabric.Point(diffX, diffY));
}
}
function clamp(value, min, max) {
return Math.max(min, Math.min(value, max));
}
#c {
background-color: grey;
margin-top: 10px;
}
button {
padding: 10px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.1.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<button id="door">Door</button>
<button id="delete">Delete Door</button>
<button id="save">Save</button>
<button id="getid">GET ID</button>
<button id="btnResetZoom">Reset Zoom</button>
<canvas id="c" width="800" height="800"></canvas>
<br>
<p class="save">
</p>
I think you should use the transformPoint method to translate position
$("#door").on("click", function (e) {
const points = {};
const iVpt = fabric.util.invertTransform(canvas.viewportTransform);
points.tl = fabric.util.transformPoint({x: 40, y: 40}, iVpt);
rect = new fabric.Rect({
id: uniqid,
left: points.tl.x,
top: points.tl.y,
width: 35,
height: 50,
fill: "blue",
stroke: "blue",
strokeWidth: 5,
strokeUniform: false,
hasControls: true,
});

Bouncing ball code causes jitter in HTML5 canvas

I have a HTML Canvas on my website that I use to contain balls that drop into the canvas, they bounce around and have a real good time settling down at the bottom in a range of ways.
I was under the impression this was working perfectly. However, it has now been brought to my attention these balls jitter and freak out on other people's computers. I checked the browser they are using and it is the same as mine (Chrome V79). So just to clarify - I have never had it bug on my computer but it consistently has this jitter on other peoples computers, some with more powerful computers as well as lower spec computers.
This is it (this CodePen doesn't have the jitter on their computers, so you may not see it also): https://codepen.io/jason-is-my-name/pen/gObKGRg
This is a video of the bug: https://streamable.com/vtg0g
$(document).ready(function () {
$.ajaxSetup({
cache: true
});
$.when(
$.getScript("https://code.createjs.com/easeljs-0.6.0.min.js"),
$.getScript("https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.10.0/matter.min.js"),
$.Deferred(function (deferred) {
$(deferred.resolve);
})
).done(function () {
new App();
});
});
function App() {
var self = this;
self.running = false;
self.initialized = false;
var stageClicked = false;
var stage, canvas;
var canvasWidth = 410;
var canvasHeight = 550;
var ballBounce = 0.8;
var balls = [];
var matterJsBalls = [];
var _gravityY = 1;
var _gravityX = 0;
var FPS = 60;
var infoText, detailsText;
var ballsInitalized = false;
var iOS = navigator.userAgent.match(/(iPod|iPhone|iPad)/);
var startTime = (new Date()).getTime();
var engine = Matter.Engine.create();
var world = engine.world;
var floor = Matter.Bodies.rectangle(canvasWidth / 2, canvasHeight + 50, canvasWidth, 100, {
isStatic: true,
render: {
visible: false
}
});
var leftWall = Matter.Bodies.rectangle(-50, canvasHeight / 2, 100, canvasHeight, {
isStatic: true,
render: {
visible: false
}
});
var rightWall = Matter.Bodies.rectangle(canvasWidth + 50, canvasHeight / 2, 100, canvasHeight, {
isStatic: true,
render: {
visible: false
}
});
Matter.World.add(world, [floor, leftWall, rightWall]);
self.initialize = function () {
toggleListeners(true);
self.initCanvas();
self.initGame();
};
var toggleListeners = function (enable) {
if (!enable) return;
};
self.refresh = function () {};
self.initCanvas = function () {
canvas = $("#ball-stage").get(0);
stage = new createjs.Stage(canvas);
window.addEventListener("resize", onStageResize, false);
onStageResize();
createjs.Touch.enable(stage);
createjs.Ticker.addListener(tick);
createjs.Ticker.setFPS(FPS);
self.initialized = true;
};
self.initGame = function () {
initBalls(canvasWidth, canvasHeight);
};
var onStageResize = function () {
stage.canvas.width = canvasWidth;
stage.canvas.height = canvasHeight;
};
var initBalls = function (stageX, stageY) {
var imagesArray = [
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg",
"https://cdn.mos.cms.futurecdn.net/vChK6pTy3vN3KbYZ7UU7k3-320-80.jpg"
];
for (var i = 0; i < imagesArray.length; i++) {
(function (imageArray) {
setTimeout(function () {
var arrayImage = new Image();
arrayImage.onload = function () {
addBall(arrayImage, stageX / 2, 52);
};
arrayImage.src = imageArray;
}, (i * 1000) + 1000);
})(imagesArray[i]);
}
};
var addBall = function (img, x, y) {
var shape = new createjs.Shape();
shape.id = balls.length;
shape.radius = 51.25;
shape.mass = shape.radius;
shape.x = x;
shape.y = y;
shape.vx = rand(-3, 3);
shape.vy = rand(-3, 3);
shape.stuck = false;
var transform = new createjs.Matrix2D();
transform.appendTransform(-shape.radius, -shape.radius, 1, 1, 0);
shape.graphics.beginBitmapFill(img, "repeat", transform).drawCircle(0, 0, shape.radius);
stage.addChild(shape);
balls.push(shape);
var circle = Matter.Bodies.circle(x, y, shape.radius, {
isStatic: false,
restitution: ballBounce
});
Matter.World.add(world, circle);
Matter.Body.applyForce(circle, {
x: circle.position.x,
y: circle.position.y
}, {
x: shape.vx * 0.05,
y: shape.vy * 0.05
});
matterJsBalls.push(circle);
};
var tick = function () {
Matter.Engine.update(engine, 16);
for (var i = 0; i < matterJsBalls.length; i++) {
var curBall = balls[i];
var curMatterJsBall = matterJsBalls[i];
curBall.x = curMatterJsBall.position.x;
curBall.y = curMatterJsBall.position.y;
}
stage.update();
};
var rand = function (min, max) {
return Math.random() * (max - min) + min;
return Math.random() * max + min;
};
self.initialize();
return self;
}
window.log = function f() {
log.history = log.history || [];
log.history.push(arguments);
if (this.console) {
var args = arguments,
newarr;
args.callee = args.callee.caller;
newarr = [].slice.call(args);
if (typeof console.log === "object")
log.apply.call(console.log, console, newarr);
else console.log.apply(console, newarr);
}
};
(function (a) {
function b() {}
for (
var c = "assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,markTimeline,profile,profileEnd,time,timeEnd,trace,warn".split(
","
),
d; !!(d = c.pop());
) {
a[d] = a[d] || b;
}
})(
(function () {
try {
console.log();
return window.console;
} catch (a) {
return (window.console = {});
}
})()
);
.tech-stack-icons-container{width:410px;height:100%}#ball-stage{width:100%;height:100%;background-color:pink;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tech-stack-icons-container">
<canvas id="ball-stage"></canvas>
</div>
How can I find a fix to this invisible issue?

Famous Engine Bruteforce collisions

I have a famous engine setup and working with physics / drag etc.
But it appears there are other physics options, BruteForce, SweepAndPrune etc.
I suspect these may be what i need to improve the collision detection between the elements.
I've tried to add the BruteForce collision detection like so:
this.collision = new collision([rightWall, leftWall, topWall, bottomWall]);
But I get an error about an incorrect constraint.
this.simulation.addConstraint(this.collision);
Does anyone have experience with solving this issue?
You can see a demo here:
var famous = famous;
var FamousEngine = famous.core.FamousEngine;
var Camera = famous.components.Camera;
var DOMElement = famous.domRenderables.DOMElement;
var Gravity3D = famous.physics.Gravity3D;
var MountPoint = famous.components.MountPoint;
var PhysicsEngine = famous.physics.PhysicsEngine;
var Position = famous.components.Position;
var Size = famous.components.Size;
var Wall = famous.physics.Wall;
var Sphere = famous.physics.Sphere;
var Vec3 = famous.math.Vec3;
var math = famous.math;
var physics = famous.physics;
var collision = famous.physics.Collision;
var gestures = famous.components.GestureHandler;
var Spring = famous.physics.Spring;
console.log(famous)
var anchor = new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0);
//Create Walls
var rightWall = new Wall({
direction: Wall.LEFT
}).setPosition(window.innerWidth - 20, 0, 0);
var leftWall = new Wall({
direction: Wall.RIGHT
}).setPosition(window.innerWidth + 20, 0, 0);
var topWall = new Wall({
direction: Wall.DOWN
}).setPosition(0, 20, 0);
var bottomWall = new Wall({
direction: Wall.UP
}).setPosition(0, window.innerHeight - 20, 0);
var centerPoint;
function Demo() {
this.scene = FamousEngine.createScene('body');
this.collision = new collision([rightWall, leftWall, topWall, bottomWall]);
console.log(this.collision)
this.simulation = new PhysicsEngine();
this.simulation.setOrigin(0.5, 0.5);
this.simulation.addConstraint(this.collision);
this.items = [];
this.walls = [];
//Create Items
for (var i = 0; i < 10; i++) {
var node = this.scene.addChild();
node.setMountPoint(0.5, 0.5);
var size = new Size(node).setMode(1, 1);
var position = new Position(node);
if (i === 0) {
createLogo.call(this, node, size, position);
}
if (i !== 0 && i !== 9) {
node.id = i;
createSatellites.call(this, node, size, position);
}
if (i === 9) {
node.id = i;
createAlternateShape.call(this, node, size, position);
}
}
//Create Walls
var node = this.scene.addChild();
createWalls(node);
var once = true;
Demo.prototype.onUpdate = function(time) {
this.simulation.update(time);
this.collision.resolve(time, 360)
//Postition walls
var wallPosition = topWall.getPosition();
node.setPosition(wallPosition.x, wallPosition.y);
//Position elements
if (this.items.length > 0) {
for (var i = 0; i < this.items.length; i++) {
if (once) {
console.log(this.items[i][1]._node.moving)
once = false;
}
if (this.items[i][1]._node.moving) {
console.log('moving!')
} else {
var itemPosition = this.simulation.getTransform(this.items[i][0]).position;
this.items[i][1].set(itemPosition[0], itemPosition[1], 0);
}
}
}
FamousEngine.requestUpdateOnNextTick(this);
};
FamousEngine.requestUpdateOnNextTick(this);
}
function createWalls(wallNode) {
wallNode.setSizeMode('absolute', 'absolute', 'absolute').setAbsoluteSize(window.innerWidth, 10, 0);
var wallDOMElement = new DOMElement(wallNode, {
tagName: 'div'
}).setProperty('background-color', 'lightblue');
}
function createLogo(node, size, position) {
node.moving = false;
size.setAbsolute(100, 100);
var mp = new MountPoint(node).set(0.5, 0.5);
var el = new DOMElement(node, {
tagName: 'img',
attributes: {
src: 'http://www.denisboudreau.org/presentations/2014/CSUN/Browser%20Zoom%20and%20Low%20Vision/Comps/ToM_EnsoCircle.png'
}
});
centerPoint = new Sphere({
radius: 50,
mass: 10000,
restrictions: ['xy'],
position: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
});
var spring = new Spring(null, centerPoint, {
stiffness: 95,
period: 0.6,
dampingRatio: 1.0,
anchor: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
});
centerPoint.setVelocity(0, 0, 0);
this.simulation.add(centerPoint, spring);
this.items.push([centerPoint, position]);
this.collision.addTarget(centerPoint);
}
function createAlternateShape(node, size, position) {
node.moving = false;
size.setAbsolute(100, 100);
var el = new DOMElement(node, {
properties: {
'background-color': 'red',
}
});
var box = new physics.Box({
size: [100, 100, 100],
mass: 10,
position: new Vec3(100, 100, 0)
});
// Attach the box to the anchor with a `Spring` force
var spring = new Spring(null, box, {
stiffness: 95,
period: 0.6,
dampingRatio: 1.0,
anchor: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
});
box.setVelocity(0.5, 0.5, 0);
this.simulation.add(box, spring);
this.items.push([box, position]);
this.collision.addTarget(box);
}
function createSatellites(node, size, position, i) {
node.moving = false;
var rand = Math.round(Math.random() * 100 + 30);
size.setAbsolute(rand, rand);
var radius = 100;
var x = Math.floor(Math.random() * radius * 2) - radius;
var y = (Math.round(Math.random()) * 2 - 1) * Math.sqrt(radius * radius - x * x);
var color = 'rgb(' + Math.abs(x) + ',' + Math.abs(Math.round(y)) + ',' + (255 - node.id) + ')';
var el = new DOMElement(node, {
properties: {
'background-color': color,
'border-radius': '50%'
}
});
var satellite = new Sphere({
radius: rand / 2,
mass: 10,
position: new Vec3(x + window.innerWidth / 2, y + window.innerHeight / 2, 0)
});
// Attach the box to the anchor with a `Spring` force
var spring = new Spring(null, satellite, {
stiffness: 95,
period: 0.6,
dampingRatio: 1.0,
anchor: anchor
});
//console.log(color);
// satellite.setVelocity(-y / Math.PI, -x / Math.PI / 2, y / 2);
satellite.setVelocity(0.5, 0.5, 0);
// this.gravity.addTarget(satellite);
this.simulation.add(satellite, spring);
this.items.push([satellite, position]);
this.collision.addTarget(satellite);
//Drag
var nodeGesture = new gestures(node);
nodeGesture.on('drag', function(e, p) {
if (e.status == "move") {
node.moving = true;
}
var currentPos = node.getPosition()
var newPosX = currentPos[0] + e.centerDelta.x
var newPosY = currentPos[1] + e.centerDelta.y
satellite.setPosition(newPosX, newPosY)
node.setPosition(newPosX, newPosY)
if (e.status == "end") {
node.moving = false;
}
});
//event
node.addUIEvent('click');
// node.addComponent({
// onReceive:function(event, payload){
// if(event==='click'){
// // el.setContent('I\'ve been clicked')
//
// }
// }
// })
}
setTimeout(function() {
// Boilerplate
FamousEngine.init();
}, 500);
// App Code
var demo = new Demo();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Famous :: Seed Project</title>
<link rel="icon" href="favicon.ico?v=1" type="image/x-icon">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
body {
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
-webkit-perspective: 0;
perspective: none;
overflow: hidden;
}
</style>
</head>
<body>
<script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script>
</body>
</html>
This is the solution using BruteForceAABB.
var famous = famous;
var FamousEngine = famous.core.FamousEngine;
var Camera = famous.components.Camera;
var DOMElement = famous.domRenderables.DOMElement;
var Gravity3D = famous.physics.Gravity3D;
var MountPoint = famous.components.MountPoint;
var PhysicsEngine = famous.physics.PhysicsEngine;
var Position = famous.components.Position;
var Size = famous.components.Size;
var Wall = famous.physics.Wall;
var Sphere = famous.physics.Sphere;
var Vec3 = famous.math.Vec3;
var math = famous.math;
var physics = famous.physics;
var collision = famous.physics.Collision;
var gestures = famous.components.GestureHandler;
var Spring = famous.physics.Spring;
console.log(famous)
var anchor = new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0);
//Create Walls
var rightWall = new Wall({
direction: Wall.LEFT
}).setPosition(window.innerWidth - 20, 0, 0);
var leftWall = new Wall({
direction: Wall.RIGHT
}).setPosition(window.innerWidth + 20, 0, 0);
var topWall = new Wall({
direction: Wall.DOWN
}).setPosition(0, 20, 0);
var bottomWall = new Wall({
direction: Wall.UP
}).setPosition(0, window.innerHeight - 20, 0);
var centerPoint;
function Demo() {
this.scene = FamousEngine.createScene('body');
// this.collision = new collision.({broadphase: 'BruteForce'});
var broadPhase = new physics.Collision.BruteForceAABB([rightWall, leftWall, topWall, bottomWall]);
this.collision = new collision([topWall], {
'broadPhase': broadPhase
});
this.simulation = new PhysicsEngine();
this.simulation.setOrigin(0.5, 0.5);
this.simulation.addConstraint(this.collision);
this.items = [];
this.walls = [];
//Create Items
for (var i = 0; i < 10; i++) {
var node = this.scene.addChild();
node.setMountPoint(0.5, 0.5);
var size = new Size(node).setMode(1, 1);
var position = new Position(node);
if (i === 0) {
createLogo.call(this, node, size, position);
}
if (i !== 0 && i !== 9) {
node.id = i;
createSatellites.call(this, node, size, position);
}
if (i === 9) {
node.id = i;
createAlternateShape.call(this, node, size, position);
}
}
//Create Walls
var node = this.scene.addChild();
createWalls(node);
var once = true;
Demo.prototype.onUpdate = function(time) {
this.simulation.update(time);
// this.collision.resolve(time, 360)
//Postition walls
var wallPosition = topWall.getPosition();
node.setPosition(wallPosition.x, wallPosition.y);
//Position elements
if (this.items.length > 0) {
for (var i = 0; i < this.items.length; i++) {
if (once) {
console.log(this.items[i][1]._node.moving)
once = false;
}
if (this.items[i][1]._node.moving) {
console.log('moving!')
} else {
var itemPosition = this.simulation.getTransform(this.items[i][0]).position;
this.items[i][1].set(itemPosition[0], itemPosition[1], 0);
}
}
}
FamousEngine.requestUpdateOnNextTick(this);
};
FamousEngine.requestUpdateOnNextTick(this);
}
function createWalls(wallNode) {
wallNode.setSizeMode('absolute', 'absolute', 'absolute').setAbsoluteSize(window.innerWidth, 10, 0);
var wallDOMElement = new DOMElement(wallNode, {
tagName: 'div'
}).setProperty('background-color', 'lightblue');
}
function createLogo(node, size, position) {
node.moving = false;
size.setAbsolute(100, 100);
var mp = new MountPoint(node).set(0.5, 0.5);
var el = new DOMElement(node, {
tagName: 'img',
attributes: {
src: './images/famous_logo.png'
}
});
centerPoint = new Sphere({
radius: 50,
mass: 100000,
restrictions: ['xy'],
position: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
});
var spring = new Spring(null, centerPoint, {
stiffness: 95,
period: 0.6,
dampingRatio: 1.0,
anchor: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
});
centerPoint.setVelocity(0, 0, 0);
this.simulation.add(centerPoint, spring);
this.items.push([centerPoint, position]);
this.collision.addTarget(centerPoint);
}
function createAlternateShape(node, size, position) {
node.moving = false;
size.setAbsolute(100, 100);
var el = new DOMElement(node, {
properties: {
'background-color': 'red',
}
});
var box = new physics.Box({
size: [101, 101, 101],
mass: 100,
position: new Vec3(100, 100, 0)
});
// Attach the box to the anchor with a `Spring` force
var spring = new Spring(null, box, {
period: 1.5,
dampingRatio: 0.8,
anchor: new Vec3(window.innerWidth / 2, window.innerHeight / 2, 0)
});
box.setVelocity(0.1, 0.1, 0);
this.simulation.add(box, spring);
this.items.push([box, position]);
this.collision.addTarget(box);
}
function createSatellites(node, size, position, i) {
node.moving = false;
var rand = Math.round(Math.random() * 100 + 30);
size.setAbsolute(rand, rand);
var radius = rand;
var x = Math.floor(Math.random() * radius * 2) - radius;
var y = (Math.round(Math.random()) * 2 - 1) * Math.sqrt(radius * radius - x * x);
var color = 'rgb(' + Math.abs(x) + ',' + Math.abs(Math.round(y)) + ',' + (255 - node.id) + ')';
var el = new DOMElement(node, {
properties: {
'background-color': color,
'border-radius': '50%'
}
});
var satellite = new Sphere({
radius: rand / 2,
mass: 100,
position: new Vec3(x + window.innerWidth / 2, y + window.innerHeight / 2, 0)
});
// Attach the box to the anchor with a `Spring` force
var spring = new Spring(null, satellite, {
// stiffness: 10,
period: 1.5,
dampingRatio: 0.8,
anchor: anchor
});
//console.log(color);
// satellite.setVelocity(-y / Math.PI, -x / Math.PI / 2, y / 2);
satellite.setVelocity(0.1, 0.1, 0);
// this.gravity.add(satellite);
this.simulation.add(satellite, spring);
this.items.push([satellite, position]);
this.collision.addTarget(satellite);
//Drag
var nodeGesture = new gestures(node);
nodeGesture.on('drag', function(e, p) {
if (e.status == "move") {
node.moving = true;
}
var currentPos = node.getPosition()
var newPosX = currentPos[0] + e.centerDelta.x
var newPosY = currentPos[1] + e.centerDelta.y
satellite.setPosition(newPosX, newPosY)
node.setPosition(newPosX, newPosY)
if (e.status == "end") {
node.moving = false;
}
});
//event
node.addUIEvent('click');
// node.addComponent({
// onReceive:function(event, payload){
// if(event==='click'){
// // el.setContent('I\'ve been clicked')
//
// }
// }
// })
}
setTimeout(function() {
// Boilerplate
FamousEngine.init();
}, 500);
// App Code
var demo = new Demo();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Famous :: Seed Project</title>
<link rel="icon" href="favicon.ico?v=1" type="image/x-icon">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html,
body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
body {
position: absolute;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
-webkit-perspective: 0;
perspective: none;
overflow: hidden;
}
</style>
</head>
<body>
<script src="http://code.famo.us/famous/0.6.2/famous.min.js"></script>
</body>
</html>

Multiple animation in canvas

I want to animate 2 figures on my page. Therefore I use Javascript. The problem is that I can't define which "sprite" he has to take. Because I can't add some Parameters like the object "animation" to the gameLoop()-method, because of the requestAnimationFrame. Any idea how I can solve this?
var animation,
image,
canvas,
stopAtLastFrame = false,
amountAnimation = 0,
amountAnimated = 1;
image = new Image();
function sprite (options) {
var that = {},
frameIndex = 0,
currentRow = 0,
currentColumn = 0,
tickCount = 0,
rowOfLastFrame = 0,
columnOfLastFrame = 0,
ticksPerFrame = options.ticksPerFrame,
numberOfFrames = options.numberOfFrames,
numberOfColumns = options.totalColumns,
numberOfRows = options.totalRows,
widthOfOneFrame = options.width/numberOfColumns,
heightOfOneFrame = options.height/numberOfRows;
that.context = options.context;
that.width = options.width;
that.height = options.height;
that.image = options.image;
rowOfLastFrame = numberOfRows-1;
columnOfLastFrame = numberOfColumns - 1 - ((numberOfRows *numberOfColumns) - numberOfFrames);
that.render = function () {
that.context.save();
that.context.scale(0.5,0.5);
// Clear the canvas
that.context.clearRect(0, 0, that.width, that.height);
// Draw the animation
that.context.drawImage(
that.image,
currentColumn * widthOfOneFrame,
currentRow * heightOfOneFrame,
widthOfOneFrame,
heightOfOneFrame,
0,
0,
widthOfOneFrame,
heightOfOneFrame);
that.context.restore();
if(rowOfLastFrame==currentRow && columnOfLastFrame==currentColumn && amountAnimated==amountAnimation)
{
stopAtLastFrame=true;
}
};
that.update = function () {
tickCount += 1;
if (tickCount > ticksPerFrame) {
tickCount = 0;
if (frameIndex < numberOfFrames-1) {
frameIndex++;
currentColumn++;
if (currentColumn == numberOfColumns) {
currentRow++;
currentColumn = 0;
}
}else{
amountAnimated++;
frameIndex=0;
currentColumn=0;
currentRow=0;
}
}
};
return that;
}
function gameLoop () {
if(stopAtLastFrame==true)
{
stopAtLastFrame=false;
}
else
{
window.requestAnimationFrame(gameLoop);
animation.update();
animation.render();
}
}
function startAnimation(canvas, imageUrl, amount){
canvas = document.getElementById(canvas);
canvas.width = 7680/4;
canvas.height = 2880/4;
image.src = imageUrl;
amountAnimation=amount;
animation = sprite({
context: canvas.getContext("2d"),
width: 7684,
height: 2880,
image: image,
numberOfFrames:16,
totalRows : 4,
totalColumns: 4,
ticksPerFrame: 5
});
gameLoop();
}
startAnimation("imageAnimation", "img/16.png", 3);
startAnimation("imageAnimation2", "img/32.png", 5);
In this example I pretend that my spritesheets are the same size and columns, just to test the code.
This doesn't work of course, but this is what I need:
function gameLoop (animation) {
if(stopAtLastFrame==true)
{
stopAtLastFrame=false;
}
else
{
window.requestAnimationFrame(gameLoop(animation));
animation.update();
animation.render();
}
}
requestAnimationFrame function is not allowed to pass your own parameter, one solution/trick is bound that gameLoop function to sprite object, so that we can access this as sprite object.
as example: http://jsfiddle.net/XQpzU/6110/
Your code can be modified as:
var animation,
image,
canvas,
stopAtLastFrame = false,
amountAnimation = 0,
amountAnimated = 1;
image = new Image();
function sprite (options) {
var that = {},
frameIndex = 0,
currentRow = 0,
currentColumn = 0,
tickCount = 0,
rowOfLastFrame = 0,
columnOfLastFrame = 0,
ticksPerFrame = options.ticksPerFrame,
numberOfFrames = options.numberOfFrames,
numberOfColumns = options.totalColumns,
numberOfRows = options.totalRows,
widthOfOneFrame = options.width/numberOfColumns,
heightOfOneFrame = options.height/numberOfRows;
that.context = options.context;
that.width = options.width;
that.height = options.height;
that.image = options.image;
rowOfLastFrame = numberOfRows-1;
columnOfLastFrame = numberOfColumns - 1 - ((numberOfRows *numberOfColumns) - numberOfFrames);
that.render = function () {
that.context.save();
that.context.scale(0.5,0.5);
// Clear the canvas
that.context.clearRect(0, 0, that.width, that.height);
// Draw the animation
that.context.drawImage(
that.image,
currentColumn * widthOfOneFrame,
currentRow * heightOfOneFrame,
widthOfOneFrame,
heightOfOneFrame,
0,
0,
widthOfOneFrame,
heightOfOneFrame);
that.context.restore();
if(rowOfLastFrame==currentRow && columnOfLastFrame==currentColumn && amountAnimated==amountAnimation)
{
stopAtLastFrame=true;
}
};
that.update = function () {
tickCount += 1;
if (tickCount > ticksPerFrame) {
tickCount = 0;
if (frameIndex < numberOfFrames-1) {
frameIndex++;
currentColumn++;
if (currentColumn == numberOfColumns) {
currentRow++;
currentColumn = 0;
}
}else{
amountAnimated++;
frameIndex=0;
currentColumn=0;
currentRow=0;
}
}
};
that.gameLoop = gameLoop.bind(that);
return that;
}
function gameLoop () {
if(stopAtLastFrame==true)
{
stopAtLastFrame=false;
}
else
{
// this will be your sprite
window.requestAnimationFrame(this.gameLoop);
animation.update();
animation.render();
}
}
function startAnimation(canvas, imageUrl, amount){
canvas = document.getElementById(canvas);
canvas.width = 7680/4;
canvas.height = 2880/4;
image.src = imageUrl;
amountAnimation=amount;
animation = sprite({
context: canvas.getContext("2d"),
width: 7684,
height: 2880,
image: image,
numberOfFrames:16,
totalRows : 4,
totalColumns: 4,
ticksPerFrame: 5
});
animation.gameLoop();
}
startAnimation("imageAnimation", "img/16.png", 3);
startAnimation("imageAnimation2", "img/32.png", 5);

Categories