"shared element activity transition" in ionic 2


#1

Wanted to check if anybody tried their hands on building a transition animation as represented in the guide https://github.com/codepath/android_guides/wiki/Shared-Element-Activity-Transition in ionic or ionic 2?

If not, do the veterans see this as a possibility in ionic. I’m new to ionic and still learning the ropes but definitely would want to take a stab at it.

-bhupi


#2

Turns out it wasn’t that difficult.
I extended Transition class from ionic-angular and used couple of angular animations (translateX, translateY and scale) with the animation params determined by the target images in leaving and entering views of the transition object.


#3

OMG…if you can share a tutorial or show your code here i will be super thankful


#4

Hey Baskin,

If you can profile some examples, it would be nice :wink:


#5

@5im0n @chanyap92 I did something along the lines of following

import { PageTransition, Animation } from ‘ionic-angular’;

//
// assumptions:
// - shared html elements need to have "shared-element" class in both the entering 
// and leaving views
//
export class SharedElements extends PageTransition {
    
    init() {
    
        this.enteringPage = new Animation(this.plt, this.enteringView.pageRef());
        this.add(this.enteringPage.beforeAddClass('show-page'));
        this.add(this.enteringPage.beforeRemoveClass('hide-page'));
        const leavingPage = new Animation(this.plt, this.leavingView.pageRef());
        this.add(leavingPage.beforeAddClass('hide-page'));
        this.add(leavingPage.beforeRemoveClass('show-page'));

        this.easing('ease-in').duration(200);
        
        let lEle = this.leavingView.pageRef().nativeElement;
        let eEle = this.enteringView.pageRef().nativeElement;

        let lEntity = lEle.querySelector('.shared-element');
        let eEntity = eEle.querySelectorAll('.shared-element');
        if (lEntity) {
            this.add(this.buildAnimation(lEntity, eEntity));
        }
    }

    private buildAnimation(leaving, entering): Animation {
        let fromPosition = leaving.getBoundingClientRect();
        let toPosition = entering.getBoundingClientRect();

        let flipS = toPosition.width / fromPosition.width;
        let flipY = fromPosition.top - toPosition.top;
        let flipX = fromPosition.left - toPosition.left;

        let sharedAnimation = new Animation(this.plt, entering);
        sharedAnimation
            .fromTo('translateY', `${flipY}px`, '0px', true)
            .fromTo('translateX', `${flipX}px`, '0px', true)
            .fromTo('scale', '1', flipS, true);
        return sharedAnimation;
    }
}

Also register this transition in your angular config via the app-module

import { Config } from 'ionic-angular/config/config';
export class AppModule {
     constructor(private config: Config) {
         // Register custom transitions.
         this.config.setTransition('shared-elements', SharedElements);
     }
}

And finally use it for pushing pages in your nav

    this.nav.push(
        TestPage, 
        { ...},
        { animation: 'shared-elements' }
    );

I haven’t gotten around to making the ‘back’ direction work yet though.
Hope this helps.


#6

Thank you @baskin for the sample

I have a problem with the back button in the entering view. I can’t Pop the view cause the back button is absent. Maybe you have faced the same issue ?

Another question: do you have think about the workflow to apply, remove the shared-element class on the elements ? For instance, if you have a page with users list, when you click on an item you should add the class shared-element on it to use correctly the transition. Idem when you Pop the page.

Thank again :wink:


#7

Hi sorry, I know that it is an old post but I have tried your code but it didn’t worked.
I have created a provider with your code, and imported into app.modules, registered the transition in app.modules and set the {animation : ‘shared-elements’} on all pages that will be animated and inserted the “shared-animation” class into html.

But it didn’t work.
Do I need to put the code into somewhere else?

Regards