Skip to content

Advanced page and component animations #7003

Open
@benbesen

Description

@benbesen

Describe the problem

I've been using Svelte for a couple of weeks and really love it. I'm mainly working on animated and highly interactive experiences and I bumped into a couple of "problems" with Svelte here:
I'm used to having control over all the elements in the DOM, no matter if its the page itself or it's children. Svelte's transition and animation possibilities are great but in my opinion lacks a bit if you want more control then just animating a page/component DOM node's in and out.

  • How can I control how components animate/behave when their parent page is animating out
  • How can I access the page component itself during transition, for example to tell it to stop a certain action

This is the only way for example I was able to not have the page jump on pagechange (using sveltekit) and it feels quite hacky...

// Pagetransition.svelte

<script>
	import { fly } from 'svelte/transition';
	export let refresh = '';
	let scrollY = 0;

	let prevScrollY = 0;
	let toScroll = 0;

	$: {
		toScroll = 0;
		if (refresh === '/') {
			toScroll = prevScrollY;
			prevScrollY = 0;
		} else if (refresh.includes('products')) {
			storeScroll();
		} else {
			prevScrollY = 0;
		}
	}

	function storeScroll() {
		prevScrollY = scrollY;
	}
</script>

<svelte:window bind:scrollY />

{#key refresh}
	<div
		in:fly={{ y: 5, duration: 1000, delay: 400 }}
		out:fly={{ y: 5, duration: 500 }}
		on:introstart={(event) => {
			// 'intro started';
			event.target.style.position = null;
			event.target.style.top = null;
			event.target.style.left = null;
			event.target.style.right = null;

			window.scrollTo(0, toScroll);
		}}
		on:outrostart={(event) => {
			// 'outro started';
			event.target.style.position = 'fixed';
			event.target.style.top = -scrollY + 'px';
			event.target.style.left = 0 + 'px';
			event.target.style.right = 0 + 'px';
			// scrollY = 0;
		}}
		on:introend={() => {
			// 'intro ended'
		}}
		on:outroend={(event) => {
			// 'outro ended';
			event.target.style.position = null;
			event.target.style.top = null;
			event.target.style.left = null;
			event.target.style.right = null;
		}}
	>
		<slot />
	</div>
{/key}

Describe the proposed solution

I'm not sure what the best approach in Svelte would be, but what could be great is calling specific hooks/functions within the transitioning/animating component: something like onIntroStart, onIntroEnd,... a bit like on:introstart, on:introend which already exist on the parent level for the transitions, but you can't access or trigger anything within the component, it's purely accessing the top level node from the outside.
I think it's good not to have to use these all the time, but I would love to have full control over how every element behaves during a transition.
It could be hooks/functions like described above with a done callback, which tells the component "your ready to be detached/unmounted" now.

Alternatives considered

It's hard for me to figure out an alternative as I don't know what Svelte does under the hood, but any way to have full control and access to the components transition states and children would be great.

Importance

i cannot use svelte without it

Metadata

Metadata

Assignees

No one assigned

    Labels

    compilerChanges relating to the compilerfeature requestruntimeChanges relating to runtime APIs

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions