I'm having an issue with scrollmagic.
I'd like to be able to trigger all 3 animations in sequence on desktop, but on smaller viewports trigger them one by one as the user scrolls.
Having both of these sets of triggers active at the same time presents an unappealing experience where all elements animate twice
I have shown how this issue presents itself in the following codepen :
https://codepen.io/TomBismuth/pen/jYaybe
in short, I only want this to happen on desktop views
var sceneEntire = new ScrollMagic.Scene({
triggerElement: "#triggerall",
reverse: false
})
.setTween(entire) // trigger a TweenMax.to tween
.addIndicators({ name: "1 (duration: 0)" })
.addTo(mainController);
and this to only happen on mobile views
var scene1only = new ScrollMagic.Scene({
triggerElement: "#trigger1",
reverse: false
})
.setTween(row1) // trigger a TweenMax.to tween
.addIndicators({ name: "1 (duration: 0)" })
.addTo(mainController);
var scene2only = new ScrollMagic.Scene({
triggerElement: "#trigger2",
reverse: false
})
.setTween(row2) // trigger a TweenMax.to tween
.addIndicators({ name: "1 (duration: 0)" })
.addTo(mainController);
var scene3only = new ScrollMagic.Scene({
triggerElement: "#trigger3",
reverse: false
})
.setTween(row3) // trigger a TweenMax.to tween
.addIndicators({ name: "1 (duration: 0)" })
.addTo(mainController);
The end goal is to present the following animations (more complex version of the earlier example): https://codepen.io/TomBismuth/pen/ppWqwN in an appealing way for both desktop and mobile users on a website. Having them all trigger at once is unappealing on desktop, and having them trigger in sequence is unappealing on mobile.
Any help would be massively appreciated
For the mobile version you need to set a triggerHook property for when the element is in the viewport. The values are between 0 and 1 where 0 represents the top of the viewport and 1 the very bottom. You can only use increments of .1, so a value of .9 is 90% from the top (or 10% from the bottom) of the viewport depending on how you wish to phrase it.
So using the .9 value on your first scene, it would be:
if (window.innerWidth < 737) {
var scene1only = new ScrollMagic.Scene({
triggerElement: "#trigger1",
triggerHook: .9,
reverse: false
})
.setTween(row1) // trigger a TweenMax.to tween
.addIndicators({ name: "1 (duration: 0)" })
.addTo(mainController);
}
Related
In this specific every time I tap on the screen the entity would appear multiple times (many #treeModel 's). My intention is just to make one model to pop out, no matter how many times I tap on the screen.
A-Frame Version: 1.1.0
Platform / Device: 8th Wall/Mac
init() {
this.raycaster = new THREE.Raycaster()
this.camera = document.getElementById('camera')
this.threeCamera = this.camera.getObject3D('camera')
this.ground = document.getElementById('ground')
// 2D coordinates of the raycast origin, in normalized device coordinates (NDC)---X and Y
// components should be between -1 and 1. Here we want the cursor in the center of the screen.
this.rayOrigin = new THREE.Vector2(0, 0)
this.cursorLocation = new THREE.Vector3(0, 0, 0)
this.el.sceneEl.addEventListener('click', (event) => {
// Create new entity for the new object
const newElement = document.createElement('a-entity')
// Spawn model at location of the cursor
newElement.setAttribute('position', this.el.object3D.position)
const randomYRotation = Math.random() * 360
newElement.setAttribute('rotation', `0 ${randomYRotation} 0`)
newElement.setAttribute('visible', 'false')
newElement.setAttribute('scale', '0.0001 0.0001 0.0001')
newElement.setAttribute('gltf-model', '#treeModel')
newElement.setAttribute('shadow', {receive: false})
this.el.sceneEl.appendChild(newElement)
newElement.addEventListener('model-loaded', () => {
// Once the model is loaded, we are ready to show it popping in using an animation
newElement.setAttribute('visible', 'true')
newElement.setAttribute('animation', {
property: 'scale',
to: '10 10 10',
easing: 'easeOutElastic',
dur: 800,
})
})
})
}
Create the model once, and move it on click, ie:
create the element before the click, but keep it hidden (via the visible attribute)
on click, change its position and make it visible.
I have a small problem with scrollMagic plugin.
I'm trying to make simple js and it works fine,
but when I follow to another page here comes an error, I can't understand:
18:27:48:554 (ScrollMagic.Scene) -> ERROR: Element defined in option "triggerElement" was not found: .my-element
I understand that on this page plugin won't find this element, but it shouldn't work so.
My code (I'm also using TweenMax):
var titleParallaxScene = new ScrollMagic.Scene({
triggerElement: '.my-element',
triggerHook: 0,
duration: '100%'
})
.setTween(TweenMax.to('.my-title', 0.5, {autoAlpha: 0, y: '250px', ease:Linear.easeNone}))
.addTo(controller);
I'm a newbie, so if it is silly question, sorry!
Thanks.
is a good practice check if the element is defined in page before initialize animations
so you have to wrap your code in a if statement
if(document.getElementByClassName('my-element').length > 0){
var titleParallaxScene = new ScrollMagic.Scene({
triggerElement: '.my-element',
triggerHook: 0,
duration: '100%'
})
.setTween(TweenMax.to('.my-title', 0.5, {autoAlpha: 0, y: '250px', ease:Linear.easeNone}))
.addTo(controller);
}
this made your ScrollMagic fires only if the target element is defined
I need to be able to jump to the middle of a tween that is lower down on the page and hasn't begun, and then begin the tween at the point where I jumped in.
When I click on the nav menu (seen as an unloaded image in the header), I need to be taken to the correct sliding panel, then have the scrolling continue from there. For example, if I click on "Degrees" in the menu, I want to be taken to the "Degrees" panel, then be able to scroll on to the next panel, "People".
The problem is when I get to the panel, the scrolling jumps back to the beginning, the first panel "About", instead of continuing on seamlessly. How do I fix this?
Link to jsfiddle to view full code (in "Employment" menu button event listener, you can see my attempts with play() and seek() and controller.ScrollTo(), perhaps using them in an incorrect combination).
// Initialize ScrollMagic controller
var controller = new ScrollMagic.Controller();
// Define movement of panels
var wipeAnimation = new TimelineMax()
.to("#slideContainer", 1, {x: "-11.11%"}) // to Degrees
.to("#slideContainer", 1, {x: "-22.22%"}) // to People
.to("#slideContainer", 1, {x: "-33.33%"}) // to Research
.to("#slideContainer", 1, {x: "-44.44%"}) // to Employment
.to("#slideContainer", 1, {x: "-55.56%"}) // to Employment2
.to("#slideContainer", 1, {x: "-66.67%"}) // to Employment3
.to("#slideContainer", 1, {x: "-77.78%"}); // to Resources
// Create scene to pin and link animation
var scene = new ScrollMagic.Scene({
triggerElement: "#pinContainer",
triggerHook: "onLeave",
duration: "600%" // slows down scrolling
})
.setPin("#pinContainer")
.setTween(wipeAnimation)
//.addIndicators()
.addTo(controller);
/**************************** MENU ****************************/
$('.menu-btn').each(function(index, element) {
$(this).on('click', function() {
var name = $(this).text();
if (name == "Degrees") {
wipeAnimation.seek(1);
wipeAnimation.play(1);
} else if (name == "People") {
wipeAnimation.seek(2);
} else if (name == "Research") {
wipeAnimation.seek(3);
} else if (name == "Employment") {
//wipeAnimation.seek(4);
//controller.scrollTo('#start');
// controller.scrollTo('#employmentAnchor')
//scene.progress(0.56);
//wipeAnimation.play(4);
//alert(scene.progress());
//scene.progress(0.5);
//controller.scrollTo('#start');
//alert('current pos: ' + controller.scrollPosMethod());
//wipeAnimation.play(4);
//wipeAnimation.start();
//wipeAnimation.play(4);
} else if (name == "Resources") {
wipeAnimation.seek(5);
}
});
})
$('.menu').on('click', function() {
$('nav').show();
})
I'm trying to figure out how to use TimelineMax with Scrollmagic.
The problem is easy to explain.
I have similar DOM elements, like particles that have to move slowly than scrolling speed.
This first implementation is WORKING (no Timeline)
var controller = new ScrollMagic.Controller();
var $particles = $("#particles li");
$particles.each(function() {
var tween = TweenMax.to($(this), 1, { y: -100, ease: Linear.easeNone });
var scene = new ScrollMagic.Scene({
triggerElement: ".wrapper",
duration: 1000
});
scene.setTween(tween);
scene.addTo(controller);
});
The second implementation is NOT WORKING (uses Timeline)
var controller = new ScrollMagic.Controller();
var $particles = $("#particles li");
var timeline = new TimelineMax();
$particles.each(function() {
timeline.to($(this), 1, { y: -200, ease: Linear.easeNone });
});
var scene = new ScrollMagic.Scene({
triggerElement: ".wrapper",
duration: 1000
});
scene.setTween(timeline)
scene.addTo(controller);
I'd like to make timeline working but elements are not animating. They move but with null timing.
Thank you for help
--- CODEPENS ---
https://codepen.io/anon/pen/wJOveM (multiple scenes)
https://codepen.io/anon/pen/dvryog?editors=1111 (w/ timeline NOT WORKING)
Can you try to use the TimelineMax .add() method instead of the .to() method in you second implementation? So your code should look like this:
var controller = new ScrollMagic.Controller();
var $particles = $("#particles li");
var timeline = new TimelineMax();
$particles.each(function() {
timeline.add(TweenMax.to($(this), 1, { y: -200, ease: Linear.easeNone }),0);
});
var scene = new ScrollMagic.Scene({
triggerElement: ".wrapper",
duration: 1000
});
scene.setTween(timeline)
scene.addTo(controller);
Also, for better debugging, please add the .addIndicators() method to the scene to see indicators on the screen, which can really help in debugging while scrolling. You can try to play with the duration property as well to see if things work properly.
UPDATE: Since all the particles needed to be moving at the same time, I added a ,0 property at the end of every .add method call. This ensures that all the tweens are triggered at the same positions. You can read more about the position property here:
https://greensock.com/asdocs/com/greensock/TimelineLite.html#add()
Here's hopefully a working example this time :)
https://codepen.io/anon/pen/ryROrv
Hope this helps. Cheers.
I'm using PhysicsJS to make a 2D roulette ball spinning animation.
So far, I've implemented the following:
used a constraint so that the ball wouldn't "fly away":
rigidConstraints.distanceConstraint( wheel, ball, 1 );
used drag to slow down the ball:
world.add(Physics.integrator('verlet', { drag: 0.9 }));
made the wheel attract the ball, so that it would fall towards it when the drag has slowed down the ball enough
My questions:
how do I gradually slow down the ball spinning?
I have already a very high drag value, but it doesn't look like it's doing anything
how do I make attraction towards the wheel work?
The distance constraint should keep the ball from escaping, not from getting closer to the wheel.
why does angularVelocity: -0.005 not work at all on the wheel?
My code, also on JSfiddle
Physics(function (world) {
var viewWidth = window.innerWidth
,viewHeight = window.innerHeight
,renderer
;
world.add(Physics.integrator('verlet', {
drag: 0.9
}));
var rigidConstraints = Physics.behavior('verlet-constraints', {
iterations: 10
});
// create a renderer
renderer = Physics.renderer('canvas', {
el: 'viewport'
,width: viewWidth
,height: viewHeight
});
// add the renderer
world.add(renderer);
// render on each step
world.on('step', function () {
world.render();
});
// create some bodies
var ball = Physics.body('circle', {
x: viewWidth / 2
,y: viewHeight / 2 - 300
,vx: -0.05
,mass: 0.1
,radius: 10
,cof: 0.99
,styles: {
fillStyle: '#cb4b16'
,angleIndicator: '#72240d'
}
})
var wheel = Physics.body('circle', {
x: viewWidth / 2
,y: viewHeight / 2
,angularVelocity: -0.005
,radius: 100
,mass: 100
,restitution: 0.35
// ,cof: 0.99
,styles: {
fillStyle: '#6c71c4'
,angleIndicator: '#3b3e6b'
}
,treatment: "static"
});
world.add(ball);
world.add(wheel);
rigidConstraints.distanceConstraint( wheel, ball, 1 );
world.add( rigidConstraints );
// add things to the world
world.add([
Physics.behavior('interactive', { el: renderer.el })
,Physics.behavior('newtonian', { strength: 5 })
,Physics.behavior('body-impulse-response')
,Physics.behavior('body-collision-detection')
,Physics.behavior('sweep-prune')
]);
// subscribe to ticker to advance the simulation
Physics.util.ticker.on(function( time ) {
world.step( time );
});
// start the ticker
Physics.util.ticker.start();
});
Drag has a bug in that version of PhysicsJS, try using the most updated version from github. https://github.com/wellcaffeinated/PhysicsJS/issues/94
Unfortunately the distance constraint imposes a fixed distance. So to prevent the ball's escape in that way, you'd need to implement your own behavior. (more below)
You'll have to change behavior: "static" to be behavior: "kinematic". Static bodies don't ever move on their own.
To create a custom behavior check out the documentation here: https://github.com/wellcaffeinated/PhysicsJS/wiki/Behaviors#creating-a-custom-behavior
In order to get the functionality you're describing, you'll need to do something like this:
// in the behave method
// calculate the displacement of the ball from the wheel... something like....
disp.clone( wheel.state.pos ).vsub( ball.state.pos );
// if it's greater than max distance, then move it back inside the max radius
if ( disp.norm() > maxDist ){
var moveBy = disp.norm() - maxDist;
disp.normalize(); // unit vector towards the wheel
disp.mult( moveBy );
ball.state.pos.vadd( disp ); // move it back inside the max radius
}
Of course, this is a "just get it done" way of doing this but it should work.