diff --git a/package.json b/package.json index 257d601..1e6d996 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ }, "dependencies": { "@studio-freight/lenis": "^0.1.13", - "animejs": "^3.2.1", "dayjs": "^1.11.5", "embla-carousel": "^7.0.0", "focus-visible": "^5.2.0", @@ -30,7 +29,6 @@ "@sveltejs/adapter-node": "^1.0.0-next.86", "@sveltejs/adapter-vercel": "^1.0.0-next.66", "@sveltejs/kit": "^1.0.0-next.405", - "@types/animejs": "^3.1.5", "@typescript-eslint/eslint-plugin": "^5.33.0", "@typescript-eslint/parser": "^5.33.0", "browserslist": "^4.21.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d4362b6..b7f8ccf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,10 +6,8 @@ specifiers: '@sveltejs/adapter-node': ^1.0.0-next.86 '@sveltejs/adapter-vercel': ^1.0.0-next.66 '@sveltejs/kit': ^1.0.0-next.405 - '@types/animejs': ^3.1.5 '@typescript-eslint/eslint-plugin': ^5.33.0 '@typescript-eslint/parser': ^5.33.0 - animejs: ^3.2.1 browserslist: ^4.21.3 cssnano: ^5.1.13 dayjs: ^1.11.5 @@ -37,7 +35,6 @@ specifiers: dependencies: '@studio-freight/lenis': 0.1.13 - animejs: 3.2.1 dayjs: 1.11.5 embla-carousel: 7.0.0 focus-visible: 5.2.0 @@ -51,7 +48,6 @@ devDependencies: '@sveltejs/adapter-node': 1.0.0-next.86 '@sveltejs/adapter-vercel': 1.0.0-next.66 '@sveltejs/kit': 1.0.0-next.405_svelte@3.49.0+vite@3.0.7 - '@types/animejs': 3.1.5 '@typescript-eslint/eslint-plugin': 5.33.0_njno5y7ry2l2lcmiu4tywxkwnq '@typescript-eslint/parser': 5.33.0_qugx7qdu5zevzvxaiqyxfiwquq browserslist: 4.21.3 @@ -489,10 +485,6 @@ packages: engines: {node: '>=10.13.0'} dev: true - /@types/animejs/3.1.5: - resolution: {integrity: sha512-4i3i1YuNaNEPoHBJY78uzYu8qKIwyx96G04tnVtNhRMQC9I1Xhg6fY9GeWmZAzudaesKKrPkQgTCthT1zSGYyg==} - dev: true - /@types/json-schema/7.0.11: resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} dev: true @@ -693,10 +685,6 @@ packages: uri-js: 4.4.1 dev: true - /animejs/3.2.1: - resolution: {integrity: sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A==} - dev: false - /ansi-regex/5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} diff --git a/src/animations/RevealQueue.ts b/src/animations/RevealQueue.ts deleted file mode 100644 index 53ca03e..0000000 --- a/src/animations/RevealQueue.ts +++ /dev/null @@ -1,65 +0,0 @@ -interface AnimationsQueueItem { - node: Node - animation: Function - delay: number -} - -export class RevealQueue { - items: AnimationsQueueItem[] = [] - queuedItems: AnimationsQueueItem[] = [] - timer = null - observer = null - - constructor () { - if (typeof IntersectionObserver === 'undefined') return - - this.observer = new IntersectionObserver(entries => { - entries.forEach(entry => { - if (entry.isIntersecting) { - this.observer.unobserve(entry.target) - const item = this.findItemFromNode(entry.target) - this.queuedItems.push(item) - - if (this.timer === null) { - this.run() - } - } - }) - }) - } - - // Add an animation in queue - add (node: Node, animation: Function, delay: number) { - this.items.push({ - node, - animation, - delay, - }) - this.observer.observe(node) - } - - // Remove node from queue and unobserve from IO - remove (node: Node) { - this.observer.unobserve(node) - this.items = this.items.filter(v => v.node !== node) - this.queuedItems = this.queuedItems.filter(v => v.node !== node) - } - - // Run animation - run () { - if (this.queuedItems.length === 0) { - this.timer = null - return - } - - const item = this.queuedItems[0] - item.animation() - this.remove(item.node) - this.timer = window.setTimeout(this.run.bind(this), item.delay) - } - - // Find item from node - findItemFromNode (node: Node) { - return this.items.find(i => i.node === node) - } -} \ No newline at end of file diff --git a/src/animations/crossfade.ts b/src/animations/crossfade.ts index b110bf9..3b38540 100644 --- a/src/animations/crossfade.ts +++ b/src/animations/crossfade.ts @@ -14,6 +14,7 @@ export const [send, receive] = crossfade({ const style = getComputedStyle(node) const transform = style.transform === 'none' ? '' : style.transform const sd = 1 - start + return { duration, easing, diff --git a/src/animations/index.ts b/src/animations/index.ts deleted file mode 100644 index 1717f65..0000000 --- a/src/animations/index.ts +++ /dev/null @@ -1,326 +0,0 @@ -import anime, { type AnimeParams } from 'animejs' -import type { TransitionConfig } from 'svelte/transition' - - -// Options interface -interface TransitionOptions { - direct?: boolean - children?: string - targets?: Element - from?: number | string - to?: number | string - opacity?: boolean - rotate?: any - rotateX?: number - rotateRandom?: boolean - duration?: number - stagger?: number - scale?: number[] - delay?: number - easing?: string - clear?: boolean -} - - -/** - * Effect: Fly - * @returns Anime.js animation - */ -export const fly = ( - node: Element, - { - direct = false, - targets = node, - children, - from = 16, - to = 0, - opacity = true, - rotate = false, - rotateX = 0, - rotateRandom = false, - duration = 1600, - stagger, - scale = null, - delay = 0, - easing = 'easeOutQuart', - clear = false - }: TransitionOptions -): TransitionConfig => { - const anim = anime({ - autoplay: !direct, - targets: children ? node.querySelectorAll(children) : targets, - ...(opacity && { opacity: [0, 1] }), - ...(scale && { scale }), - ...(rotate && { - rotate: - // If Array, use it, otherwise use the value up to 0 - Array.isArray(rotate) - ? rotate - : [rotateRandom ? anime.random(-rotate, rotate) : rotate, 0] - }), - ...(rotateX && { rotateX: [rotateX, 0] }), - translateY: [from, to], - translateZ: 0, - duration, - easing, - delay: stagger ? anime.stagger(stagger, { start: delay }) : delay, - complete: ({ animatables }) => { - // Remove styles on end - if (clear) { - animatables.forEach((el: AnimeParams) => { - el.target.style.transform = '' - opacity && (el.target.style.opacity = '') - }) - } - } - }) - - return direct ? anim : { - tick: (t: number, u: number) => anim - } -} - - -/** - * Effect: Fade - * @returns Anime.js animation - */ -export const fade = ( - node: Element, - { - direct = false, - targets = node, - children, - from = 0, - to = 1, - duration = 1600, - stagger, - delay = 0, - easing = 'easeInOutQuart', - clear = false - }: TransitionOptions -): TransitionConfig => { - - const anim = anime({ - autoplay: !direct, - targets: children ? node.querySelectorAll(children) : targets, - opacity: [from, to], - duration, - easing, - delay: stagger ? anime.stagger(stagger, { start: delay }) : delay, - complete: ({ animatables }) => { - // Remove styles on end - if (clear) { - animatables.forEach((el: AnimeParams) => { - el.target.style.opacity = '' - }) - } - } - }) - - return direct ? anim : { - tick: (t: number, u: number) => anim - } -} - - -/** - * Effect: Scale - * @returns Anime.js animation - */ -export const scale = ( - node: Element, - { - direct = false, - from = 0, - to = 1, - duration = 1200, - delay = 0, - easing = 'easeOutQuart', - clear = false - }: TransitionOptions -): TransitionConfig => { - const anim = anime({ - autoplay: !direct, - targets: node, - scaleY: [from, to], - translateZ: 0, - duration, - easing, - delay, - complete: ({ animatables }) => { - // Remove styles on end - if (clear) { - animatables.forEach((el: AnimeParams) => { - el.target.style.transform = '' - }) - } - } - }) - - return direct ? anim : { - tick: (t: number, u: number) => anim - } -} - - -/** - * Effect: Words reveal - * @description Anime.js animation - */ -export const words = ( - node: Element, - { - direct = false, - children = 'span', - from = '45%', - to = 0, - duration = 1200, - stagger = 60, - rotate = 0, - delay = 0, - opacity = true, - easing = 'easeOutQuart', - clear = false - }: TransitionOptions -): TransitionConfig => { - const anim = anime({ - autoplay: !direct, - targets: node.querySelectorAll(children), - ...(opacity && { opacity: [0, 1] }), - translateY: [from, to], - ...(rotate && { rotateX: [rotate, 0] }), - translateZ: 0, - duration, - easing, - delay: stagger ? anime.stagger(stagger, { start: delay }) : delay, - complete: ({ animatables }) => { - // Remove styles on end - if (clear) { - animatables.forEach((el: AnimeParams) => { - el.target.style.transform = '' - opacity && (el.target.style.opacity = '') - }) - } - } - }) - - return direct ? anim : { - tick: (t: number, u: number) => anim - } -} - - - -/** - * Run animation on reveal - * @description IntersectionObserver triggering an animation function or a callback - */ -export const reveal = ( - node: Element | any, - { - enable = true, - targets = node, - animation, - options = {}, - callback, - callbackTrigger, - once = true, - threshold = 0.2, - rootMargin = '0px 0px 0px', - queue = null, - queueDelay = 0, - }: revealOptions -) => { - let observer: IntersectionObserver - - // Kill if IntersectionObserver is not supported - if (typeof IntersectionObserver === 'undefined' || !enable) return - - // Use animation with provided node selector - if (animation) { - const anim = animation(node, { - ...options, - direct: true, - autoplay: false - }) - - // If a queue exists, let it run animations - if (queue) { - queue.add(node, anim.play, queueDelay) - - return { - destroy () { - queue.remove(node) - } - } - } - - observer = new IntersectionObserver(entries => { - entries.forEach(entry => { - if (entry.isIntersecting) { - anim && anim.play() - once && observer.unobserve(entry.target) - } - }) - }, { threshold, rootMargin }) - - observer.observe(node) - } - - // Custom callback - else if (callback) { - observer = new IntersectionObserver(entries => { - entries.forEach(entry => { - const cb = callback(entry) - - if (entry.isIntersecting) { - // Run callback - callbackTrigger && callbackTrigger(cb) - - // Run IntersectionObserver only once - once && observer.unobserve(entry.target) - } - }) - }, { threshold }) - - const elements = typeof targets === 'string' ? node.querySelectorAll(targets) : targets - - if (elements) { - // Observe each element - if (elements.length > 0) { - elements.forEach((target: Element) => { - observer.observe(target) - }) - } - // Directly observe - else { - observer.observe(elements) - } - } - } - - // Methods - return { - // Destroy - destroy () { - observer && observer.disconnect() - } - } -} - -interface revealOptions { - animation?: Function - options?: TransitionOptions - queue?: any - callback?: Function - callbackTrigger?: any - targets?: string | Element - enable?: boolean - once?: boolean - threshold?: number, - rootMargin?: string, - queueDelay?: number -} - -export { RevealQueue } from './RevealQueue' diff --git a/src/components/atoms/ScrollingTitle.svelte b/src/components/atoms/ScrollingTitle.svelte index ce1044b..9c2278e 100644 --- a/src/components/atoms/ScrollingTitle.svelte +++ b/src/components/atoms/ScrollingTitle.svelte @@ -8,7 +8,7 @@ import SplitText from '$components/SplitText.svelte' - import { reveal, fly } from '$animations/index' + import reveal from '$animations/reveal' import { DURATION } from '$utils/contants' export let variant: string = 'lines' @@ -14,16 +14,14 @@ {#if tag === 'h1'}

diff --git a/src/components/molecules/Switcher.svelte b/src/components/molecules/Switcher.svelte index e05341d..90e5f05 100644 --- a/src/components/molecules/Switcher.svelte +++ b/src/components/molecules/Switcher.svelte @@ -5,7 +5,7 @@ diff --git a/src/routes/[country]/[location]/index.svelte b/src/routes/[country]/[location]/index.svelte index 859d3e5..0735e13 100644 --- a/src/routes/[country]/[location]/index.svelte +++ b/src/routes/[country]/[location]/index.svelte @@ -146,13 +146,12 @@ /** * Animations */ - const animationDelay = $navigating ? DURATION.PAGE_IN : 0 const animation = timeline([ // Title word ['.location-page__intro .word', { y: ['110%', 0], }, { - at: 0.2 + animationDelay, + at: 0.2, }], // Illustration @@ -160,7 +159,7 @@ scale: [1.06, 1], opacity: [0, 1], }, { - at: 0.4 + animationDelay, + at: 0.4, duration: 2.4, }], @@ -168,7 +167,7 @@ ['.location-page__intro .of', { opacity: [0, 1], }, { - at: 0.95 + animationDelay, + at: 0.95, duration: 1.2, }], @@ -177,11 +176,11 @@ y: ['10%', 0], opacity: [0, 1], }, { - at: 0.9 + animationDelay, + at: 0.9, duration: 1.2, }] ], { - delay: DELAY.PAGE_LOADING / 1000, + delay: $navigating ? DELAY.PAGE_LOADING / 1000 : 0, defaultOptions: { duration: 1.6, easing: quartOut, diff --git a/src/routes/credits.svelte b/src/routes/credits.svelte index ddfa6c1..aea05f7 100644 --- a/src/routes/credits.svelte +++ b/src/routes/credits.svelte @@ -4,6 +4,7 @@