-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(katzencore): Added Scroll Animations to composables
- Loading branch information
Maximilian Schleining
committed
Aug 12, 2024
1 parent
5732cf1
commit 3ee8fbc
Showing
4 changed files
with
118 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<script setup lang="ts"> | ||
const section1 = ref<HTMLElement | null>(null) | ||
const animation = useScrollAnimation({element:section1}) | ||
const globalScroll = useScrollAnimation({global: true}) | ||
const screenScroll = useScrollAnimation({screenHeight: true}) | ||
</script> | ||
|
||
<template> | ||
<div> | ||
<h1>Animation Test Page</h1> | ||
<div class="flex flex-col"> | ||
<div class="flex flex-row"> | ||
<p>On this page the useAnimation Composables are tested</p> | ||
</div> | ||
</div> | ||
|
||
|
||
<div class="fixed top-0 left-0 font-bold text-2xl text-black bg-white p-4 border border-black rounded-lg"> | ||
<span>GlobalScroll: {{globalScroll}}</span> | ||
|
||
<br> | ||
|
||
<span>ScreenScroll: {{screenScroll}}</span> | ||
|
||
</div> | ||
|
||
<div class="h-screen w-full bg-gray-100 flex flex-col items-center justify-between" ref="section1"> | ||
<h2>SECTION 1</h2> | ||
<p>{{animation}}</p> | ||
</div> | ||
<div class="h-screen w-full bg-red-100 flex flex-col items-center justify-center"> | ||
<h2>SECTION 2</h2> | ||
</div> | ||
|
||
<div class="h-screen w-full bg-red-100 flex flex-col items-center justify-center"> | ||
<h2>SECTION 3</h2> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
</style> |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* | ||
* Katze Animation Library | ||
* - useScrollAnimation | ||
* - useTimelineAnimation (WIP) | ||
*/ | ||
import { ref, watch } from 'vue' | ||
import type { Ref } from 'vue' | ||
import { onMounted, onUnmounted } from '#imports' | ||
|
||
interface ScrollAnimationOptions { | ||
global?: boolean | ||
screenHeight?: boolean | ||
element?: Ref<HTMLElement | null> | ||
} | ||
|
||
interface UpdateFunction { | ||
(values: ScrollAnimationValues): void | ||
} | ||
|
||
interface ScrollAnimationValues { | ||
capped: number | ||
full: number | ||
} | ||
|
||
const watchingElements: Map<HTMLElement, UpdateFunction> = new Map() | ||
const globalScrollPercentage = ref<ScrollAnimationValues>({ capped: 0, full: 0 }) | ||
const screenHeightPercentage = ref<ScrollAnimationValues>({ capped: 0, full: 0 }) | ||
|
||
export const useScrollAnimation = (options: ScrollAnimationOptions) => { | ||
let reactiveScrollProperty = ref<ScrollAnimationValues>({ capped: 0, full: 0 }) | ||
if (options.global) { | ||
reactiveScrollProperty = globalScrollPercentage | ||
} | ||
else if (options.screenHeight) { | ||
reactiveScrollProperty = screenHeightPercentage | ||
} | ||
else if (options.element) { | ||
// wait for element to be mounted | ||
onMounted(() => { | ||
const updateFunction = (values: ScrollAnimationValues) => { | ||
reactiveScrollProperty.value = values | ||
} | ||
watchingElements.set(<HTMLElement>options.element?.value, updateFunction) | ||
}) | ||
} | ||
else { | ||
throw new Error('Please provide an element or set global or screenHeight to true in the options') | ||
} | ||
|
||
onMounted(() => window.addEventListener('scroll', globalScrollListener)) | ||
onUnmounted(() => window.removeEventListener('scroll', globalScrollListener)) | ||
|
||
return reactiveScrollProperty | ||
} | ||
|
||
const globalScrollListener = () => { | ||
const scrollY = window.scrollY | ||
|
||
const globalPercent = scrollY / (document.body.scrollHeight - window.innerHeight) | ||
globalScrollPercentage.value = { capped: Math.min(1, globalPercent), full: globalPercent } | ||
|
||
const screenHeightPercent = scrollY / window.innerHeight | ||
screenHeightPercentage.value = { capped: Math.min(1, screenHeightPercent), full: screenHeightPercent } | ||
|
||
watchingElements.forEach((updateFunction, element) => { | ||
const elementTop = element.getBoundingClientRect().top | ||
const elementHeight = element.getBoundingClientRect().height | ||
const cappedValue = Math.max(0, Math.min(1, (elementTop + elementHeight) / window.innerHeight)) | ||
updateFunction({ capped: 1 - cappedValue, full: (-1 * (elementTop / window.innerHeight)) }) | ||
}) | ||
} |