Three.js and gsap scale animation - javascript

So I'm trying to do a mousemove event in three.js where the user would hover over a geometry and then it would scale.
So for the animations I am using GSAP as tween doesn't seem to be working for me. However, I keep getting this error when I want to scale my geometry:
I don't know why because in the official gsap documentation they use scale, without a plugin I believe. Here is an example from their website
gsap.to(".box", 1, {
scale: 0.1,
y: 60,
yoyo: true,
repeat: -1,
ease: "power1.inOut",
delay:1,
stagger: {
amount: 1.5,
grid: "auto",
from: "center"
}
});
Here is my code:
function init () {
/*------Bunch of three.js code and initialsation*/
window.addEventListener('mousemove',onMouseMove);
}
function onMouseMove(event) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera(mouse,camera);
var intersects = raycaster.intersectObjects(scene.children, true);
for(var i = 0; i < intersects.length; i++) {
gsap.to(intersects[i].object.scale, {duration: 1, scale: 0.8});
}
}

So I figured the answer. It seems that in three.js, the gsap scale property doesn't work so you need to make sure you're referring to scale before adding transformations, and then use x and y (or maybe z - I haven't tried) to increase or decrease the size.
This is the code that worked for me:
gsap.to(intersects[i].object.scale, {duration: .7, x: 1.2, y:1.2});

Related

Phaser 3: Allow Particles to emit with flipped/mirrored image?

I have a particle emitter which emits multiple duplicates of the same image, as usual. However I'd like some of the particles to be flipped, either completely at a random amount, or sort of in the middle, so that particles falling to the left would be flipped and particles falling to the right won't be.
However I couldn't find anything regarding flipping particles without flipping ALL of them. I'd only like some to be flipped. Is this possible in any way?
There are serveral way's, I think the "fastest" would be just to use the scaleX property of the emiter.
this code flips about 10% of the particles ( 0.9 > Math.random() ), through multiplying it with -1, when it should be flipped.
Example Code:
this.add.particles('sparkle').createEmitter({
x: 200,
y: 100,
scaleX: {
onEmit: function () {
return ( 0.9 > Math.random() ) ? -1 : 1;
}
},
speed: { min: -100, max: 100 },
quantity: 0.1,
frequency: 1,
});
But I assume from a earlier question, that you have emitter with a "random scale" property. I that case you woud have to do something like this:
Example Code, for random scaled particles:
gameState.splash = this.add.particles('droplet').createEmitter({
x: gameState.height/2,
y: gameState.width/2,
scale: {
onEmit: function () {
// create random new scale
let newRandowmScale = Phaser.Math.FloatBetween(0.05, 0.3);
return ( 0.9 > Math.random() ) ? -1 * newRandowmScale : newRandowmScale;
}
},
speed: { min: -100, max: 100 },
...
});
UPDATE(SlowerFix): Example Code, for random scaled particles:
What the update does: save the current scale of the scaleX event and use it in the scaleY event. (it is hacky, but should work. I will see if there is a cleaner solution)
gameState.splash = this.add.particles('droplet').createEmitter({
x: gameState.height/2,
y: gameState.width/2,
scaleY:{
onEmit: function(particle){
// keep scale value positive
return Math.abs(particle.scaleX);
}
},
scaleX:{
onEmit: function(p){
let scale = Phaser.Math.FloatBetween(.2, .5);
return Math.random() > .9 ? scale * -1 : scale;
}
},
speed: { min: -100, max: 100 },
...
});

Tweenmax Scale with ThreeJS Mesh

Trying to incorporate a scale translation to my mesh[0] using TweenMax. I'm not having any problems with certain animations, such as rotation, or even scaling when I use 'mesh[0].set.scale' as the first argument. However, in this situation I'm getting 'Uncaught TypeError: Cannot assign to read only property 'scale' of object '#'' errors from the console.
I'm guessing that this is to do with the combination of using GSAP and ThreeJS, because I've tried out the same code in plain javascript and it works OK.
I've tried to include minimal code, so please let me know if more is needed!
const geometry = new THREE.IcosahedronBufferGeometry( 1, 0 );
materialRed = new THREE.MeshStandardMaterial({
color: 0xFF0000
});
mesh[0] = new THREE.Mesh( geometry, materialRed );
scene.add(mesh[0]);
TweenMax.to(mesh[0], 1,
{
scale: 2,
ease: Elastic.easeOut,
yoyo: true,
repeat: -1,
yoyoEase: Bounce.easeOut,
delay: 1,
}
);
Figured out my issue:
TweenMax.to(mesh[0].scale, 1,
{ x: 1.2,
y: 1.2,
z: 1.2,
yoyo: true,
repeat: -1,
});
Seems as if I was trying to manipulate the whole mesh, when I should have been focusing on the scale of the mesh. From here I can scale up and manipulate however.
Repeat method call has been updated:
https://greensock.com/docs/TimelineMax/repeat()
var t = Math.random() * 0.6 + 0.3;
TweenMax.to( box.scale, t, {
x: 1 + Math.random() * 3,
y: 1 + Math.random() * 20,
z: 1 + Math.random() * 3,
ease: Power2.easeInOut
} ).repeat(-1);
Demo:
https://codepen.io/MAKIO135/pen/vmBzMv?editors=0010

Threejs StreetView-like panorama effect

I'm trying to achieve a kind of effect between panoramas being rendered with ThreeJS on a sphere.
Actually, I'm moving the actual scene behind me using TweenMax for the timing and easing, but I would like to give it that fast-moving effect that you get on StreetView.
This is the piece of code I'm using for the transition:
var vector = new THREE.Vector3( 0, 0, 0);
camera.getWorldDirection(vector);
var duration = 450;
var tweenRoomOut = new TWEEN.Tween(scene.position)
.to({
x: -1 * vector.x * 300,
y: -1 * vector.y * 300,
z: -1 * vector.z * 300,
}, duration)
.easing(TWEEN.Easing.Exponential.Out)
.onComplete( () => {
//When finished, restart position so the scene returns to its origin
scene.position.x = vector.x;
scene.position.y = vector.y;
scene.position.z = vector.z;
})
.start();

many very confusing problems with kinetic.js

i got some problems with understanding kinetic.js (the documentation is horrible for newbies...) i hope i can explain it with my bad english.
Problem 1: Everytime when i #reset my canvas it is not really resetting it. its more like its pushing another background image over the actual canvas and when i click on it it jumps back to the original...
function clearCanvas() {
context.clearRect(0, 0, 1000, 1000); //whole canvas
context.drawImage(buehneObj,0,0); //redraw the main background image
}
and call it with:
reset = document.getElementById('reset');
document.getElementById('reset').onclick =function(){clearCanvas();
}
Problem 2: the slider i build for scaling the image is not working at all but i dont see the problem... ...the variables are global and if i test alert it i see that values are existing...
standard jquery slider:
$('#scaleslider').slider({
animate: "fast",
step: 0.1,
value: 1,
min: 0.1,
max: 1,
slide: function(event,ui){groesse = ui.value} //global variable
});
i made it hidden(display:none) and on click "block"
var scaleslider = document.getElementById('scaleslider').style;
document.getElementById('resize').onclick =function(){ scaleslider.display ="block";}
and here's how kinetic parts look like (dragMotiv is my first start image) "groesse" is the variable for my x and y slider value(they can us the same so it scales correct):
var dragMotiv = new Kinetic.Image({
image: imageObj,
x: 250,
y: 300,
width: 330,
height: 263,
rotationDeg: 0,
scale: { x:groesse, y:groesse },
draggable: true,
dragBoundFunc: function(pos) {
var newY = pos.y < 290 ? 290 : pos.y > 305 ? 305 : pos.y;
var newX = pos.x < 250 ? 250 : pos.x > 390 ? 390 : pos.x;
return {
x: newX,
y: newY
};
}
});
Problem 3: Saving is not possible at all.
i uploaded it to my server to let you guys take a look at it. i know that there is one little thingy that i just dont see(i hope so).
http://manufaktur13.de/playground/canvas_kinetic.html
I think you should not clear the canvas, instead you should keep record what you have drown and remove those items, and redraw the layer.

Dragging image out of frame removes it from the kineticjs stage

Could someone please provide me with the a jsfiddle of a simple and clean way to remove an image from the canvas by dragging the image out of the canvas frame.
Here is what I could come up with http://jsfiddle.net/n4w44/50/ :
I make the stage 400px and put the frame in the center at 200px by 200px dimensions by implementing the dragBoundFunc.
var image = new Kinetic.Image({
draggable : true,
x: 175,
y:175,
width: 50,
height: 50,
draggable: true,
dragBoundFunc: function(pos) {
var stage_width = stage.getWidth();
if (pos.x > 300 || pos.x < 100 || pos.y > 300 || pos.y < 100)
{
this.hide();
}
return {
x: pos.x,
y: pos.y
};
}
});
But it would be nice to see alternative solutions which:
Make it look cleaner as the image is exiting
Allow me to avoid having to do some ugly offsetting of the container (which I would need to do when I embed it in the page).
Is there any reason you're using an older version of KineticJS (4.4.3)? The reason I ask is because as of KineticJS 4.5.1 (and now currently we're on 4.6.0 which you can get on the KineticJS Website) the Tween class was added in favor of the Transition class.
KineticJS 4.5.1 Changelog
Anyways, I solved your problem by adding some code to the dragBoundFunc
var image = new Kinetic.Image({
draggable: true,
x: 175,
y: 175,
width: 50,
height: 50,
draggable: true,
dragBoundFunc: function (pos) {
var thisImg = this;
if (pos.x > (frame.getWidth() + frame.getX() - thisImg.getWidth()) || pos.x < frame.getX() || pos.y > (frame.getHeight() + frame.getY() - thisImg.getHeight()) || pos.y < frame.getY()) {
var tween = new Kinetic.Tween({
node: thisImg,
duration: 0.1,
opacity: 0,
onFinish: function () {
thisImg.hide();
thisImg.setOpacity(1);
}
});
this.stopDrag();
tween.play();
}
return {
x: pos.x,
y: pos.y
};
}
});
To make the image exit smoother, I used a Tween to tween the opacity to 0, making it look like a quick fade effect. When the tween finishes, I hide the image and set the opacity back to 1 so you can show the image later without any complications. .stopDrag() is used to the stop the image from dragging while the Tween is played.
To make the dragBoundFunc more dynamic, instead of using static numbers we use the x,y position of the frame along with the width & height to calculate the boundaries, and we also need the width and height of the image to subtract from the boundaries so that the dragBoundFunc takes into consideration the offset of the image (which is by default the top left).
JSFIDDLE Note: In the fiddle I replaced the KineticJS 4.4.3 version with KineticJS 4.6.0 (see the HTML code)
It's up to you if you can upgrade your KineticJS version to use Tweens, or stick with the version you have now and use Transitions (which you'll have to find documentation for, I'm not sure how they work).

Categories

Resources