Is it possible to use scrollmagic.js for sticky animation?

Hello,

Please check the scrollmagic.js at https://scrollmagic.io/examples/

Here are some interesting animations:

https://scrollmagic.io/examples/basic/scene_manipulation.html
https://scrollmagic.io/examples/advanced/section_slides_manual.html
https://scrollmagic.io/examples/expert/mobile_advanced.html

I found it is most difficult part to pin or stick an animation at a fixed position and move up after animation when scroll up and down in HYPE.

A topical case is that Apple always use this kind of Animation, for example:

at https://www.apple.com/iphone-12-pro/

@MaxZieb posted a solution by scrollama before at HypeLama (Hype + Scrollama): Scrollytelling using IntersectionObserver for Hype, but I found it is a little complicated in practice.

Recently, I found scrollmagic is widely embedded in wordpress plugins.
So, it is possible to use scrollmagic.js as a easy solution in HYPE please?

Thanks

may help: Where I have to put prepared HTML, CSS and JS?

1 Like

Great.

Thanks for your great sample.

#1 I duplicate the rectangle in xxx timeline, and set it bbb unique element ID.
#2 duplicate the js code as below:

.setPin('#aaa') // pins the element for the the scene's duration
.setPin('#bbb') // pins the element for the the scene's duration
.addTo(controller); // assign the scene to the controller

But only one rectangle works, anyway to make multiple elements working?

Please check the attached hype file.
scrollMagic_example.hype.zip (14.2 KB)

1 Like

I think you can only pin one element to the scene.

You may have to make more than on scene and use the same controller.

This looks like it can get complex if you are running more than one timeline..

Maybe pre plan scene to element in an associated array (named)
And iterate scene creation. mainly to save duplicating code.
But as I say multiple hype timelines may be fun.

//---Single timeline.

	var controller = new ScrollMagic.Controller();
	
	 var elementsToPin = {"ScrollMagicScene1":'#aaa', "ScrollMagicScene2":'#bbb'}
	 
	
for (const scne in elementsToPin) {
 // console.log(`${scne}: ${elementsToPin[scne]}`);
  sceneCreater(scne,elementsToPin[scne])
  
}




function sceneCreater(scne,elem){

 console.log(scne);
 

 this[scne] = new ScrollMagic.Scene({
	duration: 1000, // the scene should last for a scroll distance of 1000px
	offset: 926 // start this scene after scrolling for 926px
})
	 
		// pins the element for the the scene's duration
	.setPin(elem) // pins the element for the the scene's duration

	.addTo(controller)  // assign the scene to the controller
 
	this[scne].on("progress", function (event) {
hypeDocument.goToTimeInTimelineNamed(event.progress * hypeDocument.durationForTimelineNamed('xxx'), 'xxx')

  

});

 
} 

//-- Multi timeline

	var controller = new ScrollMagic.Controller();
	
	 var elementsToPin = {"ScrollMagicScene1":['#aaa',"timeline1"]  , "ScrollMagicScene2":['#bbb',"timeline2"] }
	 
	
for (const scne in elementsToPin) {
 // console.log(`${scne}: ${elementsToPin[scne]}`);
  sceneCreater(scne,elementsToPin[scne][0],elementsToPin[scne][1])
  
}




function sceneCreater(scne,elem,timeline){

 console.log(scne);
 

 this[scne] = new ScrollMagic.Scene({
	duration: 1000, // the scene should last for a scroll distance of 1000px
	offset: 926 // start this scene after scrolling for 926px
})
	 
		// pins the element for the the scene's duration
	.setPin(elem) // pins the element for the the scene's duration

	.addTo(controller)  // assign the scene to the controller
 
	this[scne].on("progress", function (event) {
hypeDocument.goToTimeInTimelineNamed(event.progress * hypeDocument.durationForTimelineNamed(timeline), timeline)

  

});

 
}

//-- Ussing attibutes.

	var controller = new ScrollMagic.Controller();
	
	 var elementsToPin =  ['aaa', 'bbb']


var i;
for (i = 0; i < elementsToPin.length; i++) {
  var tml=  hypeDocument.getElementById( elementsToPin[i]).dataset.timeline
   var scn =  hypeDocument.getElementById( elementsToPin[i]).dataset.scrollscenename
   var elem = "#" + elementsToPin[i]
   sceneCreater(scn,elem ,tml)
}

	 
 




function sceneCreater(scne,elem,timeline){

 console.log(scne);
 

 this[scne] = new ScrollMagic.Scene({
	duration: 1000, // the scene should last for a scroll distance of 1000px
	offset: 926 // start this scene after scrolling for 926px
})
	 
		// pins the element for the the scene's duration
	.setPin(elem) // pins the element for the the scene's duration

	.addTo(controller)  // assign the scene to the controller
 
	this[scne].on("progress", function (event) {
hypeDocument.goToTimeInTimelineNamed(event.progress * hypeDocument.durationForTimelineNamed(timeline), timeline)

  

});

 
}
1 Like

Hi @MarkHunte

Great thanks for your codes.

I did lots of test and found ScrollMagic JS is really powerful, and the animation is very smooth, and much better than any other approach.

There are many playgrounds, here are some advantages and lost of potential possibilities, and also I found some problems:

1# Support Flexible layout
**2# The method of Timeline Support by set Group unique ID:
Multiple timelines,
multiple elements,
Group of elements,
multiple groups
**

Problems is that I found the animation duration is not constitutionally play. In the following sample, the animation on timeline2 should be start after the timeline1 finished but it will start early, is there any wrong with my setting?

scrollMagic_multiple_timeline_Grouped_multiple_elements.hype.zip (177.3 KB)

Question: how to allow multiple elements or groups on one timeline? I use the following code to play both elements #aaa and #bbb on timeline1, it works, but is this a right way please?

`  var elementsToPin = {"ScrollMagicScene1":['#aaa',"timeline1"], "ScrollMagicScene2":['#bbb',"timeline1"], "ScrollMagicScene3":['#ccc',"timeline2"] }` 

**3# the method of Setting Attibutes above support by setting attributes on Groups or elements.
multiple elements
multiple Groups of elements **

scrollMagic_attibutes_multiple_grouped_elements.hype.zip (182.4 KB)

Problem is almost same with the method of timeline. In the above sample file, there are two groups: group A, and Group B, and I found it is difficult for me to make the animation of Group B only start after group A end.

So, any way to make the animations continually between groups and timelines please?

Great thanks.

As I said, from the looks of it multi timeline control is going to be interesting.
Looking at the doc the does not seem to be an obvious way to do this.
Don't really have the time ( the will ) to dive more deeply into this :bomb:... :smiley:

Thanks, I see.

I checked these samples again:

https://scrollmagic.io/examples/expert/cascading_pins.html
https://scrollmagic.io/examples/expert/callback_duration.html
https://scrollmagic.io/examples/expert/mobile_advanced.html
https://scrollmagic.io/examples/expert/removing_and_destroying.html

I found there are always a triggerElement: "#trigger", which set "trigger, scene.destroy(reset), .on("enter leave"), but it is difficult to do that in Hype, right?

There may be a simple way to do it, but I did not find it in the time a gave to look.

The combination of scroll/ trigger and where the scroll leaves all the elements while running part of a timeline or mutiple timelines makes it difficult to work out.

This is more acute with the example files you give, because they are not that clear to me what the real expected behaviour is supposed to be and the scrollmagic documentation although look complete is not that great IMHO.

Thanks for reply.

I finally make it working as what I expected😄. It is not perfect as the method by TRIGGER like Scrollmagic official sample:

https://scrollmagic.io/examples/basic/simple_pinning.html

But it works with two Javascript files, it works as what I expected at least, please check:
scrollMagic_multiple_timeline_Grouped_multiple_elements_twoJS.hype.zip (179.1 KB)

The advantage of method by Trigger is that it support to trigger animation multiple times or trigger multiple Elements, but it seems not work in Hype.

To be honest, I did do an test where I added duration and start attibutes for each timeline. But as I said unclear on what is really the expected behaviour..

Glad you got what you were after.

oh... I really expect to see how you achieve, would you please like to share? :grinning:

When I get back to my Mac.. not on mine at mo.

But I simplye added attibutes. and set them as different numbers.

It was simple enough that I was able to rewrite it from you latest example.

I think I may have just had the timing wrong when I was testing it as I was not sure (sorry to say again) the expected result.

scrollMagic_multiple_timeline_Grouped_multiple_elements_twoJSMHvxxx 2.hype.zip (443.2 KB)

attribues are in the inspector

Screenshot 2020-11-21 at 17.42.26

	var controller = new ScrollMagic.Controller();
	 var elementsToPin =  ['ddd', 'fff']


var i;
for (i = 0; i < elementsToPin.length; i++) {

//this["controller" + i] = new ScrollMagic.Controller();

   // var thisController = this["controller" + i] 
var pineEl = hypeDocument.getElementById( elementsToPin[i])
  var tml=  pineEl.dataset.timeline
   var scne =  pineEl.dataset.scrollscenename
    var dur  =  Number(pineEl.dataset.dur)
     var start =  Number(pineEl.dataset.start)
   var elem = "#" + elementsToPin[i]
//  sceneCreater(scne,elem ,tml,dur ,start,thisController)
   sceneCreater(scne,elem ,tml,dur,start,)
}

	 
 



  // function sceneCreater(scne,elem,timeline,dur,start,thisController){
function sceneCreater(scne,elem,timeline,dur,start){

 console.log(scne);
 

 this[scne] = new ScrollMagic.Scene({
	duration: dur, // the scene should last for a scroll distance of 1000px
	offset: start // start this scene after scrolling for 926px
})
	 
		// pins the element for the the scene's duration
	.setPin(elem) // pins the element for the the scene's duration

	//.addTo(this["controller" + i] )  // assign the scene to the controller
	.addTo(controller)  // assign the scene to the controller
 
	this[scne].on("progress", function (event) {
hypeDocument.goToTimeInTimelineNamed(event.progress * hypeDocument.durationForTimelineNamed(timeline), timeline)

  

});

 
}
1 Like

:grinning: Really amazing!!!

Oh, no sorry, thank for so much great work!!!

So, this method is use attributes to control timeline, and also support timelines and and multiple groups of elements.

When I add an iPad or iPhone layout, it will not working, should I duplicate a Js file of attribType() for the new layout?

Have a nice day.

I am surprised you do not know the answer to some of this,

You will run into issues because you are using IDs.

So use class names instead of id.


You will also need to know which layout you are on so that you can target it's elements.
It will not work if you try and blanket init for all layouts and elements. Some attributes will likely not exist yet in the DOM.


For example.

Desk layout.
Give the elements the class name of 'pinDesk'

ipad layout.
Give the elements the class name of 'pinPad'


side note: ( you can by the way, if you had one layout, just give all the pin elements a single class name and querySelectAll them. This will save hard coding an array of ids)


Then in the code you can get the layout name and use a switch to change which pin.. class you are looking for.

     elementsToPin = []

	 switch(hypeDocument.currentLayoutName()) {
  case 'ipad':
  elementsToPin =  document.querySelectorAll('.pinPad')
break;
  case 'desk':
 elementsToPin =  document.querySelectorAll('.pinDesk')
break;
 
}

scrollMagic_multiple_timeline_Grouped_multiple_elements_twoJSMHClassNames.hype.zip (28.1 KB)


note: I have added the scrollMagic debug addIndicators to the head, and the ..addIndicators() option in the code.

You will need to remove that when going live.
<script src="http://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/debug.addIndicators.js">

1 Like

Hello,

WOW, What I should say, thanks so much, this is not only Scrollmagic solution in Hype, but also great javascript study case for us.

Thanks for so much detailed information. For now, there are value setting of data-start like 1000 or 3000, and I note the trigger is always at the relative middle of the browser window.

Is it possible to set animations of elements or group of elements to be ALWAYS started at relative middle of browser window too? but not manually set value like 1000 or 3000?

Alex you need to go over the scrollmagic docs.
I think I saw some use of percent of the page in regard to triggers, which would make sense to be able to usr

Hey, guys!
I'm working on a scrolling project since this summer. I was already found the scrollmagic solution but I did not understand how to implement it on my project. I wrote many many posts in this forum but when I'm not familiar with coding, every explain I received it was very difficult to understand!

After all I was forced to find other solution. Now I work with manipulating timeline animations with script which @MaxZieb was so kind at inventing it for me.

But now I found this discussion here and I'm wondering will it be better to start all over again and build my project with scrollmagic. I really don't now. I don't now because I can't understand how you achieved the thing! I did not understand nothing of posts above!

If what I want isn't too much, would it be possible to explain to me step by step how you did it?

I will send my first try on personal messages because it is secret yet. Thank you!

I already checked your site by private message, and I think it works great, especially scroll videos.
what exactly do you want?

Thank you! I'm wondering which approach is more correct. But maybe I'll just leave it as it is.