Skip to content

Commit

Permalink
Merge pull request #872 from tutors-sdk/ux/animations
Browse files Browse the repository at this point in the history
introduce core set of animations
  • Loading branch information
edeleastar authored Dec 2, 2024
2 parents a7cc0d9 + e708ca7 commit 75392d0
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 68 deletions.
2 changes: 2 additions & 0 deletions src/lib/runes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ export const iconHeight = rune("140");
export const imageHeight = rune("h-32");
export const textSize = rune("text-base");
export const avatarWidth = rune("w-12");

export const animationDelay = rune(200);
56 changes: 34 additions & 22 deletions src/lib/ui/animations.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
import { cubicInOut, cubicOut } from "svelte/easing";
import { animationDelay } from "$lib/runes";
import { cubicOut, elasticOut, backOut, linear } from "svelte/easing";

export const cardTransition = () => {
return {
css: (t: string) => {
return `transform: scale(${t}); `;
},
easing: cubicInOut,
baseScale: 0.5,
duration: 250,
delay: 250
};
export const scaleTransition = {
duration: animationDelay.value,
start: 0.4,
easing: cubicOut
};

export const talkTransition = () => {
return {
css: (t: string) => {
return `transform: scale(${t}); `;
},
easing: cubicOut,
baseScale: 0.5,
duration: 200,
delay: 200
};
export const slideFromLeft = {
in: { x: -200, duration: animationDelay.value, delay: animationDelay.value },
out: { x: -200, duration: animationDelay.value }
};

export const viewDelay = 500;
export const slideFromRight = {
in: { x: 200, duration: animationDelay.value, delay: animationDelay.value },
out: { x: 200, duration: animationDelay.value }
};

// export const popTransition = {
// duration: 100,
// start: 0.2,
// easing: elasticOut,
// opacity: 0
// };

// export const slideTransition = {
// duration: 250,
// y: 20,
// easing: cubicOut,
// opacity: 0
// };

// export const bounceTransition = {
// duration: 100,
// y: 20,
// easing: backOut,
// opacity: 0
// };
29 changes: 21 additions & 8 deletions src/lib/ui/learning-objects/content/Lab.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import { onDestroy, onMount } from "svelte";
import { goto, afterNavigate } from "$app/navigation";
import type { LiveLab } from "$lib/services/models/live-lab";
import { fly } from "svelte/transition";
import { slideFromLeft } from "$lib/ui/animations";
interface Props {
lab: LiveLab;
Expand Down Expand Up @@ -37,6 +39,10 @@
goto(`${lab.url}/${step}`);
}
}
let isLoaded = $state(false);
onMount(() => {
isLoaded = true;
});
</script>

<svelte:head>
Expand All @@ -49,21 +55,28 @@
</svelte:head>

<div class="w-full">
<div class="bg-primary-50 dark:bg-primary-900 sticky top-0 block w-full rounded border lg:hidden">
<div class="sticky top-0 block w-full rounded border bg-primary-50 lg:hidden dark:bg-primary-900">
<nav class="flex flex-wrap justify-between p-2">
{@html lab.horizontalNavbarHtml}
</nav>
</div>

<div class="max-w-l flex">
<div class="mr-2 hidden h-auto w-72 lg:block">
<div class="card bg-surface-100 dark:bg-surface-950 dark:border-primary-500 border-[1px] sticky top-6 m-2 h-auto rounded-xl py-4">
<nav class="nav-list">
<ul>
{@html lab.navbarHtml}
</ul>
</nav>
</div>
{#if isLoaded}
<div
in:fly={slideFromLeft.in}
out:fly={slideFromLeft.out}
class="card sticky top-6 m-2 h-auto rounded-xl border-[1px] bg-surface-100 py-4 dark:border-primary-500
dark:bg-surface-950"
>
<nav class="nav-list">
<ul>
{@html lab.navbarHtml}
</ul>
</nav>
</div>
{/if}
</div>
<div id="lab-panel" class="min-h-screen flex-1">
<article class="prose mr-4 max-w-none dark:prose-invert prose-pre:max-w-[70vw]">
Expand Down
8 changes: 7 additions & 1 deletion src/lib/ui/learning-objects/layout/Cards.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import type { Lo } from "$lib/services/models/lo-types";
import { setShowHide } from "$lib/services/models/lo-utils";
import Card from "$lib/ui/themes/card/Card.svelte";
import { cubicOut } from "svelte/easing";
import { scale } from "svelte/transition";
import { scaleTransition } from "$lib/ui/animations";
interface Props {
los?: Lo[];
Expand All @@ -18,6 +21,7 @@
let pinBuffer = "";
let ignorePin = "";
let refresh = $state(true);
let isLoaded = $state(false);
function keypressInput(e: { key: string }) {
pinBuffer = pinBuffer.concat(e.key);
Expand All @@ -35,11 +39,13 @@
ignorePin = currentCourse?.value?.properties.ignorepin.toString();
window.addEventListener("keydown", keypressInput);
}
isLoaded = true;
});
</script>

{#if los.length > 0}
{#if los.length > 0 && isLoaded}
<div
transition:scale|local={scaleTransition}
class="mx-auto mb-2 place-items-center overflow-hidden rounded-xl bg-surface-100 p-4 dark:bg-surface-900 {border
? bordered
: unbordered}"
Expand Down
2 changes: 1 addition & 1 deletion src/lib/ui/learning-objects/layout/Units.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<div class={inSidebar ? "flex flex-col" : "grid grid-cols-1"}>
{#each units as unit}
<div
class="bg-surface-100 dark:bg-surface-900 border-primary-500 mx-auto mb-2 w-full place-items-center overflow-hidden rounded-xl border-[1px] p-4"
class="mx-auto mb-2 w-full place-items-center overflow-hidden rounded-xl border-[1px] border-primary-500 bg-surface-100 p-4 dark:bg-surface-900"
>
<div class="flex w-full justify-between pb-2">
<h2 id={unit.id} class="p-2 {text}">
Expand Down
19 changes: 14 additions & 5 deletions src/lib/ui/learning-objects/structure/Context.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script lang="ts">
import type { Lo } from "$lib/services/models/lo-types";
import type { Snippet } from "svelte";
import { onMount, type Snippet } from "svelte";
import LoContextPanel from "../layout/LoContextPanel.svelte";
import { slideFromRight } from "$lib/ui/animations";
import { fly } from "svelte/transition";
type Props = {
children: Snippet;
Expand All @@ -16,16 +18,23 @@
loContext = loContext.parentLo!;
}
}
let isLoaded = $state(false);
onMount(() => {
isLoaded = true;
});
</script>

<div class="ml-10 mr-10 flex justify-between">
<div class="w-full">
{@render children()}
</div>
{#if loContext}
<div class="mr-2 hidden h-auto w-72 xl:block">
<div class="sticky top-6 h-auto">
<LoContextPanel {loContext} />
{#if loContext && isLoaded}
<div in:fly={slideFromRight.in} out:fly={slideFromRight.out}>
<div class="mr-2 hidden h-auto w-72 xl:block">
<div class="sticky top-6 h-auto">
<LoContextPanel {loContext} />
</div>
</div>
</div>
{/if}
Expand Down
11 changes: 4 additions & 7 deletions src/lib/ui/navigators/SecondaryNavigator.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import Breadcrumbs from "../themes/icons/Breadcrumbs.svelte";
import EditCoursButton from "./buttons/EditCoursButton.svelte";
import IconBar from "../themes/icons/IconBar.svelte";
import { slideFromLeft } from "../animations";
let firstDivClass = $state("");
let otherDivClass = $state("");
Expand All @@ -20,17 +21,13 @@
</script>

{#if !currentCourse?.value?.isPortfolio}
<div in:fly={{ x: -200, duration: 300, delay: 300 }} out:fly={{ x: -200, duration: 300 }}>
<div
class="border-primary-100 bg-primary-50 dark:border-primary-800 {firstDivClass} z-10 flex h-12 border-b-[1px]"
>
<div in:fly={slideFromLeft.in} out:fly={slideFromLeft.out}>
<div class="border-primary-100 bg-primary-50 dark:border-primary-800 {firstDivClass} z-10 flex h-12 border-b-[1px]">
<Breadcrumbs />
{#if currentCourse?.value}
<div class="flex flex-auto"></div>
{#if currentCourse?.value?.properties.github}
<div
class="bg-primary-200 {otherDivClass} my-2 mr-2 hidden rounded-lg bg-opacity-80 lg:flex lg:flex-none"
>
<div class="bg-primary-200 {otherDivClass} my-2 mr-2 hidden rounded-lg bg-opacity-80 lg:flex lg:flex-none">
<EditCoursButton />
</div>
{/if}
Expand Down
9 changes: 7 additions & 2 deletions src/lib/ui/themes/LayoutMenu.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { setDisplayMode, setTheme, themes } from "./styles/icon-lib.svelte";
import Icon from "./icons/Icon.svelte";
import { lightMode } from "$lib/runes";
import { animationDelay, lightMode } from "$lib/runes";
import Menu from "$lib/ui/utils/Menu.svelte";
import { layout } from "$lib/runes";
import MenuItem from "$lib/ui/utils/MenuItem.svelte";
Expand Down Expand Up @@ -49,7 +49,12 @@
<h6>Themes</h6>
<ul class="list">
{#each themes as theme}
<MenuItem type="lightMode" isActive={selectedTheme === theme.name} text={theme.name} onClick={() => changeTheme(theme.name)}/>
<MenuItem
type="lightMode"
isActive={selectedTheme === theme.name}
text={theme.name}
onClick={() => changeTheme(theme.name)}
/>
{/each}
</ul>
{/snippet}
Expand Down
61 changes: 46 additions & 15 deletions src/routes/(auth)/auth/SigninWithGithub.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,32 @@

<div class="bg-surface-100-800 mx-auto mb-2 place-items-center overflow-hidden rounded-xl p-4">
<div class="flex flex-wrap justify-center">
<div class="card !bg-surface-50 dark:!bg-surface-700 w-4/5 border-y-8 border-{getIcon('note').color}-500 m-2">
<div class="card w-4/5 border-y-8 !bg-surface-50 dark:!bg-surface-700 border-{getIcon('note').color}-500 m-2">
<header class="card-header flex flex-row items-center justify-between p-3">
<div class="flex-auto text-center !text-black dark:!text-white">Tutors Sign In</div>
</header>
<footer class="card-footer">
<div class="bg-surface-100-800 mx-auto mb-2 place-items-center overflow-hidden rounded-xl p-4">
<div class="flex flex-wrap justify-center">
<button
type="button"
class="btn bg-primary-500 hover:bg-primary-600 w-2/3 transform text-white transition-transform hover:scale-105"
onclick={handleSignInWithProgress}
>
{#if showProgress}
<Progress width="w-32" />
{:else}
{#if showProgress}
<div class="flex w-full place-items-center justify-center p-4">
<Progress value={null} meterAnimate="my-custom-animation" />
</div>
{:else}
<div class="bg-surface-100-800 mx-auto mb-2 place-items-center overflow-hidden rounded-xl p-4">
<div class="flex flex-wrap justify-center">
<button
type="button"
class="btn w-full transform bg-primary-500 text-white transition-transform hover:scale-105 hover:bg-primary-600"
onclick={handleSignInWithProgress}
>
<span><Icon icon="mdi:github" /></span>
<span>Sign in with GitHub</span>
{/if}
</button>
</button>
</div>
</div>
</div>
{/if}
</footer>
</div>
<div class="card !bg-surface-50 dark:!bg-surface-700 w-4/5 border-y-8 border-{getIcon('topic').color}-500 m-2">
<div class="card w-4/5 border-y-8 !bg-surface-50 dark:!bg-surface-700 border-{getIcon('topic').color}-500 m-2">
<footer class="card-footer mt-4">
<article class="prose mx-auto w-[80%] max-w-none dark:prose-invert">
<TutorsTerms />
Expand All @@ -52,3 +54,32 @@
</div>
</div>
</div>

<style>
/*
Note: The `:global` modifier is used to apply the
animation to the progress bar because Svelte styles
are scoped by default.
*/
:global(.my-custom-animation) {
animation: my-custom-animation 2s ease-in-out infinite;
}
@keyframes my-custom-animation {
0% {
translate: -100%;
}
25% {
scale: 1;
}
50% {
scale: 0.25 1;
translate: 50%;
}
75% {
scale: 1;
}
100% {
translate: 200%;
}
}
</style>
10 changes: 3 additions & 7 deletions src/routes/(home)/CourseList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,18 @@
}
</script>

<div class="card container mx-auto my-1 p-4">
<div class="container card mx-auto my-1 p-4">
<p class="p-4 text-2xl">Favourites</p>
<div class="mx-auto grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3">
{#each courseVisits.filter((cv) => cv.favourite) as courseVisit (courseVisit.id)}
<div animate:flip={{ duration: 300 }}>
<CourseVisitCard {courseVisit} {deleteCourse} {starUnstarCourse} />
</div>
<CourseVisitCard {courseVisit} {deleteCourse} {starUnstarCourse} />
{/each}
</div>

<p class="p-4 text-2xl">Recently accessed</p>
<div class="mx-auto grid grid-cols-1 lg:grid-cols-2 xl:grid-cols-3">
{#each courseVisits.filter((cv) => !cv.favourite) as courseVisit (courseVisit.id)}
<div animate:flip={{ duration: 300 }}>
<CourseVisitCard {courseVisit} {deleteCourse} {starUnstarCourse} />
</div>
<CourseVisitCard {courseVisit} {deleteCourse} {starUnstarCourse} />
{/each}
</div>
</div>

0 comments on commit 75392d0

Please sign in to comment.