Three.js How to check when animation is end? - javascript

If I write something like this:
function renderuj(){
scene.renderer.setClearColor(0xeeeeee, 1);
ob1.animation.update(0.5);
ob2.animation.update(0.5);
scene.renderer.render(scene.scene, scene.camera);
animationFram = requestAnimationFrame(renderuj);
}
the animation working in loop.
But I want to play only once and no more.
How to do that
inside the .js file where is 3D animation/object we can see this
animation" : [{"name":"test1","fps":24,"length":10
and I try add to my code something like this
if(temp < 10)
temp++;
else
cancelRequestAnimFrame(animationFram );
but I have only half of animation

Not sure what type for animation object you are using but you probably want to do something like this.
if ( obj.animation.time + delta < obj.animation.duration ) {
// running
obj.animation.update( delta );
} else {
// finished
obj.animation.update( obj.animation.duration - obj.animation.time );
}

Related

Phaser3 framework javascript: current anims index

In phaser 3 framework, what syntax do I use to check the current frame index?
I want to make a hit area appear only when the player's sprite sheet reaches a certain index(the index displaying the motion of 'attack'). I want to accomplish this through detecting its current frame index.
How can I do this?
You could use the sprite events like: Phaser.Animations.Events.ANIMATION_UPDATE, details in official phaser documenation
player.on(Phaser.Animations.Events.ANIMATION_UPDATE, function (anim, frame, gameObject, frameKey) {
// Here you can check for the specific-frame
if(frameKey == "show_hit_area_frame"){
// ... show hitarea
}
// alternatively: with the index of the frame
if(frame.index == 7){
// ... show hitarea
}
});
In this selected Event, you can also check the current frame, for other properties of the frame object (details in official documenation), if you don't know/have the specific framekey/index.
The solution is found.
//hitbox solution: https://newdocs.phaser.io/docs/3.52.0/Phaser.Animations.Events.ANIMATION_COMPLETE_KEY
//hitboxB listener
gameState.playerB.on('animationstart-kill', function () {
console.log("finish kill <3")
gameState.hitBoxB.x = gameState.playerB.flipX ? gameState.playerB.x + 120 : gameState.playerB.x - 120;
gameState.hitBoxB.y = gameState.playerB.y;
// gameState.hitBoxB.visible = true;
})
gameState.playerB.on('animationcomplete-kill', function () {
console.log("kill <3")
gameState.hitBoxB.x =0 ;
gameState.hitBoxB.y = 0;
// gameState.hitBoxB.visible = false;
})

How to set collider with world bounds (Phaser)?

I'm using Phaser.io
I just learned how to set a collider function:
this.physics.add.collider(enemies, platforms, function (enemy) {
enemy.destroy();
gameState.score += 10;
});
But I would like to do the same thing without the platform. Instead of the platform, I would like to use the world bounds.
I know you can set world bounds like this:
player.setCollideWorldBounds(true);
I've tried:
this.physics.add.collider(enemies, this.worldBounds, function (enemy) {
enemy.destroy();
gameState.score += 10;
});
But this doesn't work.
Any ideas?
I have found a solution for you:
First, set your enemy's sprite to collide with the setCollideWorldBounds(true) like so:
enemy.setCollideWorldBounds(true);
Second, turn the option for your enemy's sprite to listen for WorldBound events like so:
enemy.body.onWorldBounds = true;
Third & lastly, set the "wordbounds" event listener & make the enemy disappear like so:
enemy.body.world.on('worldbounds', function(body) {
// Checks if it's the sprite that you'listening for
if (body.gameObject === this) {
// Make the enemy sprite unactived & make it disappear
this.setActive(false);
this.setVisible(false);
}
}, enemy);

FabricJS - performance threading

Sorry if the title was misleading, it's the closest approximation I could come up with, haha.
Okay so I'm using FabricJS for a proof-of-concept for a fabric-printing client, and they require 300PPI images (i.e, freaking huge). Now, if you check the JsFiddle I've popped in below you'll see the tiling is done with some while loops which seem to work fine, except for the fact that the whole browser freezes while loading, meaning I can't even stick up a loader icon.
Have I done something horribly wrong, or is that just sorta how it works? The long loading times are fine as long as I can a) put up a loader and b) it doesn't, uh, "He's dead, Jim!" my Chrome. I'm getting the images with base64, if that helps at all.
Cheers everyone!
EDIT For context, here's one of the functions that creates a pattern from an uploaded file:
function renderMirror(){
showLoader();
var isFullRows = false;
var rowIndex = 0;
var totalHeight = 0;
while(isFullRows == false){
// let's start with filling up the row's columns. start the width at zero.
var totalWidth = 0;
var isFullCols = false;
var colIndex = 0;
if(rowIndex % 2){
var isRowMirrored = false;
}else{
var isRowMirrored = true;
}
while(isFullCols == false){
colIndex++
if(rowIndex == 1){
console.log('row');
}
if(totalWidth >= canvas.width){
isFullCols = true;
}
if(colIndex % 2){
var isColMirrored = false;
}else{
var isColMirrored = true;
}
canvas.add(new fabric.Rect({
left: totalWidth,
top: totalHeight,
fill: pattern,
flipX: isColMirrored,
flipY: isRowMirrored,
height: newImgHeight,
width: newImgWidth,
selectable: false
}));
totalWidth+= newImgWidth;
// safeguard
if(colIndex > 100){
isFullCols = true;
}
}
// now instantiate the row.
rowIndex++;
if(totalHeight >= canvas.height){
isFullRows = true;
}
totalHeight+= newImgHeight;
// safeguard
if(rowIndex > 100){
isFullRows = true;
}
}
hideLoader();
}
The whole thing is here, if you'd like to have a proper look?
I've experienced something similar to generate PDF at 300. I tried two different solutions:
Using webWorkers which will do the heavy work on the background and is not going to freeze the browser, however this approach was a little bit slower in my use case.
The second approach I took was create an endpoint where I get just the base 64 image and then with that data of the image I generate a PDF using imagemagick to create the PDF at 300 DPI also I create a virtual canvas with JS to generate the real size of the image from a scaled canvas in order to make it a little bit faster as well.

Easeljs sprite animation stuck on frame

I'm learning javascript by using the easeljs library to make a simple game, for school lessons.
I want to make a crosshair give some feedback to the player by showing a small animation while you are pointing at your target, using a hittest I made.
However, when the crosshair touches the target, the animation (should be two little triangles pointing to the middle of the crosshair) seems to be stuck on it's first frame.
Here is a bit of my code, I put both of these functions inside a ticker function. The functions do what they're supposed to do (I checked by sending a message to the console.log), but I think the animation is reset as soon as the variable "hitTestControle" is set to true, at every tick.
If you want to check out all of the code, here is a link to the "game":
http://athena.fhict.nl/users/i279907/achtergrond/achtergrond.html
function hitTest() {
if(distance(crossHair, block) < 60) {
hitTestControle = true;
} else {
hitTestControle = false;
console.log(hitTestControle);
}
}
function hitTestControl() {
if(hitTestControle == true) {
crossHair.gotoAndPlay("move");
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
}
}
PS: There also seems to be something wrong with this hittest I used.
function distance() {
var difx = blok.x - crossHair.x;
var dify = blok.y - crossHair.y;
return Math.sqrt( (difx * difx) + (dify * dify) );
}
It looks like you're starting the animation... setting it to the first frame and starting it... every time hitTestControle is true. Since hitTestControle will be true as long as you're hovering over the target, the animation will never reach the second frame.
What you need to do is start the animation when you transition from hitTestControle = false to hitTestControle = true, but once that happens you just let it play automatically.
Try changing your hitTestControl() function to something like this:
function hitTestControl() {
if(hitTestControle == true && alreadyOverHit == false) {
crossHair.gotoAndPlay("move");
alreadyOverHit = true;
console.log("hit");
} else {
crossHair.gotoAndPlay("stop");
alreadyOverHit = false;
}
}
In other words, only start the animation once, during the first frame you're detecting a hit, and then don't touch it unless you move off the target and back on.

Mouse position on a canvas

I am a bit confused here about how to interact with an image in a canvas.
My images load but I want to be able to click a given image and work out which image the mouse has clicked.
But the images can be offset aswell which makes matters more confusing, so I was wondering if there was a some kind of mathematical way to calculate which image your mouse is over when you click the canvas?
Not tried in on a canvas, but maybe it can help (part is jQuery), base rely on DOM function elementFromPoint():
getElemFromPos = function(x,y,def)
{
var f = 'elementFromPoint',
x=parseInt(x),y=parseInt(y),d=$j(document);
if(!d[0][f] || isNaN(x) || isNaN(y)) return def;
var w=$(window),bRel=0;
if( !d[0].__ajqefpc )
{
var sl=d.scrollTop();
if( sl >0)
{ bRel = (d[0][f](0, sl + w.height() -1) == null); }
else if((sl = d.scrollLeft())>0 )
{ bIsRel = (d[0][f](sl + w.width() -1, 0) == null); }
d[0].__ajqefpc=(sl>0);
}
if(!bRel)
{
x += d.scrollLeft();
y += d.scrollTop();
}
var r = d[0][f](x,y);
return (r && r!=null)?r:false;
};
Are you using any javascript libraries? I would suggest wrappping all your images in a div with the same class then doing something like this:
jQuery('.imageWrapper').click(function(elm){
console.log(this , elm);
//some code to run here
}
In this instance this should refer to the event, and elm should be the element, that you clicked on. You can then do whatever you need to to that element.

Categories

Resources