sonovice
sonovice
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
Done. FYI:
[...]

const SlideAnimation: Component<{
component: Component,
direction: "left" | "right"
}> = (props) => (
<Motion
initial={{transform: props.direction === "left" ? "translateX(-100%)" : "translateX(100%)"}}
animate={{transform: "translateX(0%)"}}
exit={{transform: props.direction === "left" ? "translateX(100%)" : "translateX(-100%)"}}
transition={{duration: 0.3}}
style="position: absolute; width: 100%; height: 100%;"
>
<props.component/>
</Motion>
)

const Layout: Component = () => {
const [previousPath, setPreviousPath] = createSignal<string>("/");
const [slideDirection, setSlideDirection] = createSignal<"left" | "right">("right");
const currentPath = () => useLocation().pathname;

function calcDirection() {
const normalizedCurrentPath = currentPath().replace(/\/$/, "");
const normalizedPreviousPath = previousPath().replace(/\/$/, "");
const depth = normalizedCurrentPath.split("/").length - normalizedPreviousPath.split("/").length;
setSlideDirection(depth < 0 ? "right" : "left");
}

createEffect(() => {
if (currentPath() !== previousPath()) {
calcDirection();
setPreviousPath(currentPath());
}
})

return (
<div>
<Presence initial={false}>
<Switch>

<Match when={currentPath() === "/"}>
<SlideAnimation component={Home} direction={slideDirection()}/>
</Match>

<Match when={currentPath() === "/about"}>
<SlideAnimation component={About} direction={slideDirection()}/>
</Match>

</Switch>
</Presence>
</div>
);
}


const App = () => (
<HashRouter root={Layout}/>
);

render(() => <App/>, document.getElementById("root")!);
[...]

const SlideAnimation: Component<{
component: Component,
direction: "left" | "right"
}> = (props) => (
<Motion
initial={{transform: props.direction === "left" ? "translateX(-100%)" : "translateX(100%)"}}
animate={{transform: "translateX(0%)"}}
exit={{transform: props.direction === "left" ? "translateX(100%)" : "translateX(-100%)"}}
transition={{duration: 0.3}}
style="position: absolute; width: 100%; height: 100%;"
>
<props.component/>
</Motion>
)

const Layout: Component = () => {
const [previousPath, setPreviousPath] = createSignal<string>("/");
const [slideDirection, setSlideDirection] = createSignal<"left" | "right">("right");
const currentPath = () => useLocation().pathname;

function calcDirection() {
const normalizedCurrentPath = currentPath().replace(/\/$/, "");
const normalizedPreviousPath = previousPath().replace(/\/$/, "");
const depth = normalizedCurrentPath.split("/").length - normalizedPreviousPath.split("/").length;
setSlideDirection(depth < 0 ? "right" : "left");
}

createEffect(() => {
if (currentPath() !== previousPath()) {
calcDirection();
setPreviousPath(currentPath());
}
})

return (
<div>
<Presence initial={false}>
<Switch>

<Match when={currentPath() === "/"}>
<SlideAnimation component={Home} direction={slideDirection()}/>
</Match>

<Match when={currentPath() === "/about"}>
<SlideAnimation component={About} direction={slideDirection()}/>
</Match>

</Switch>
</Presence>
</div>
);
}


const App = () => (
<HashRouter root={Layout}/>
);

render(() => <App/>, document.getElementById("root")!);
13 replies
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
Now I have to figure out how to change the transformations dynamically based on previous and next route. Basically "slide right" if I go deeper in the path structure (e.g. "/" -> "/dashboard/") and "slide left" if I go up.
13 replies
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
I took your ideas and came up with this, kinda abusing the router:
import {render} from "solid-js/web";
import {A, HashRouter, useLocation} from "@solidjs/router";
import {Motion, Presence} from "solid-motionone";
import {Match, Switch} from "solid-js";
import "./styles.css";

const Home = () => (
<div class="blue">
<p>Home</p>
<A href="/about">About</A>
</div>
);

const About = () => (
<div class="orange">
<p>About</p>
<A href="/">Home</A>
</div>
);

const SlideInAnimation = (props: any) => (
<Motion
initial={{transform: "translateX(100%)"}}
animate={{transform: "translateX(0%)"}}
exit={{transform: "translateX(-100%)"}}
transition={{duration: 0.3}}
style="position: absolute; width: 100%; height: 100%;"
>
{props.component}
</Motion>
)


const Layout = () => {
const currentPath = () => useLocation().pathname;

return (
<div>
<Presence initial={false}>
<Switch>

{/* Home Route */}
<Match when={currentPath() === "/"}>
<SlideInAnimation component={<Home/>}/>
</Match>

{/* About Route */}
<Match when={currentPath() === "/about"}>
<SlideInAnimation component={<About/>}/>
</Match>

</Switch>
</Presence>
</div>
);
};


const App = () => (
<HashRouter root={Layout}/>
);

// Render the App
render(() => <App/>, document.getElementById("root")!);
import {render} from "solid-js/web";
import {A, HashRouter, useLocation} from "@solidjs/router";
import {Motion, Presence} from "solid-motionone";
import {Match, Switch} from "solid-js";
import "./styles.css";

const Home = () => (
<div class="blue">
<p>Home</p>
<A href="/about">About</A>
</div>
);

const About = () => (
<div class="orange">
<p>About</p>
<A href="/">Home</A>
</div>
);

const SlideInAnimation = (props: any) => (
<Motion
initial={{transform: "translateX(100%)"}}
animate={{transform: "translateX(0%)"}}
exit={{transform: "translateX(-100%)"}}
transition={{duration: 0.3}}
style="position: absolute; width: 100%; height: 100%;"
>
{props.component}
</Motion>
)


const Layout = () => {
const currentPath = () => useLocation().pathname;

return (
<div>
<Presence initial={false}>
<Switch>

{/* Home Route */}
<Match when={currentPath() === "/"}>
<SlideInAnimation component={<Home/>}/>
</Match>

{/* About Route */}
<Match when={currentPath() === "/about"}>
<SlideInAnimation component={<About/>}/>
</Match>

</Switch>
</Presence>
</div>
);
};


const App = () => (
<HashRouter root={Layout}/>
);

// Render the App
render(() => <App/>, document.getElementById("root")!);
13 replies
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
Ah, got it. So I have to have all pages of my app already in the DOM, otherwise things vanish. Thank you!
13 replies
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
It seems as if it impossible to trigger exit and animate at the same time with solid router :/
13 replies
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
Thanks! This kinda works, but now I have a blank screen between two pages. The animation for the next page only starts after the exit animation of the previous one finished. If I remove exitBeforeEnter, there is no exit animation.
13 replies
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
import {render} from "solid-js/web";
import {A, HashRouter, Route} from "@solidjs/router";
import {Motion, Presence} from "solid-motionone";
import "./styles.css";

const Home = () => (
<div class="blue">
<p>Home</p>
<A href="/about">About</A>
</div>
);

const About = () => (
<div class="orange">
<p>About</p>
<A href="/">Home</A>
</div>
);

const Layout = (props: any) => {
return (
<div>
<Presence exitBeforeEnter>
<Motion
initial={{transform: "translateX(100%)"}}
animate={{transform: "translateX(0%)"}}
exit={{transform: "translateX(-100%)"}}
transition={{duration: 0.3}}
>
{props.children}
</Motion>
</Presence>
</div>
);
};


const App = () => (
<HashRouter root={Layout}>
<Route path="/" component={Home}/>
<Route path="/about" component={About}/>
</HashRouter>
);

// Render the App
render(() => <App/>, document.getElementById("root")!);
import {render} from "solid-js/web";
import {A, HashRouter, Route} from "@solidjs/router";
import {Motion, Presence} from "solid-motionone";
import "./styles.css";

const Home = () => (
<div class="blue">
<p>Home</p>
<A href="/about">About</A>
</div>
);

const About = () => (
<div class="orange">
<p>About</p>
<A href="/">Home</A>
</div>
);

const Layout = (props: any) => {
return (
<div>
<Presence exitBeforeEnter>
<Motion
initial={{transform: "translateX(100%)"}}
animate={{transform: "translateX(0%)"}}
exit={{transform: "translateX(-100%)"}}
transition={{duration: 0.3}}
>
{props.children}
</Motion>
</Presence>
</div>
);
};


const App = () => (
<HashRouter root={Layout}>
<Route path="/" component={Home}/>
<Route path="/about" component={About}/>
</HashRouter>
);

// Render the App
render(() => <App/>, document.getElementById("root")!);
13 replies
SSolidJS
Created by sonovice on 9/16/2024 in #support
Animate page transition
Thanks for the hint. I am still having a hard time to get it right. Only the initial page load is animated, other transitions are not. Current code:
13 replies