Added About Page

This commit is contained in:
2025-09-17 23:34:37 +10:00
parent 2f6006626d
commit b9e1f6827a
30 changed files with 1270 additions and 529 deletions

View File

@@ -0,0 +1,122 @@
// directives/intersectionTransition.ts
import { Directive } from 'vue'
interface TransitionOptions {
type?: string
duration?: number | string
easing?: string
delay?: number | string
opacity?: number | string
transform?: string
threshold?: number
}
interface IntersectionElement extends HTMLElement {
_observer?: IntersectionObserver
_options?: TransitionOptions
}
function setupTransition(el: IntersectionElement, binding: any) {
// Handle different binding value types
let options: TransitionOptions = {}
if (typeof binding.value === 'string') {
// Simple string usage: v-show-on-intersect="'fade-up'"
options = { type: binding.value }
} else if (typeof binding.value === 'object') {
// Object usage: v-show-on-intersect="{ type: 'fade-up', duration: '2s', transform: 'translateX(-100px)' }"
options = { ...binding.value }
}
// Set defaults
const {
type = 'fade-up',
duration = '1s',
easing = 'cubic-bezier(0.4, 0, 0.2, 1)',
delay = '0s',
opacity = '0',
transform,
threshold = 0.1
} = options
el._options = options
// Get initial transform (custom or preset)
const initialTransform = transform || getInitialTransform(type)
// Initially hide the element
el.style.opacity = String(opacity)
el.style.transform = initialTransform
el.style.transition = `all ${duration} ${easing} ${delay}`
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// Show element
el.style.opacity = '1'
el.style.transform = 'none'
} else {
// Hide element
el.style.opacity = String(opacity)
el.style.transform = initialTransform
}
})
}, {
threshold: threshold as number
})
el._observer = observer
observer.observe(el)
}
export const intersectionTransition: Directive = {
mounted(el: IntersectionElement, binding) {
setupTransition(el, binding)
},
updated(el: IntersectionElement, binding) {
// Handle dynamic updates to the directive value
if (JSON.stringify(binding.value) !== JSON.stringify(binding.oldValue)) {
// Disconnect old observer and setup with new options
if (el._observer) {
el._observer.disconnect()
}
setupTransition(el, binding)
}
},
unmounted(el: IntersectionElement) {
if (el._observer) {
el._observer.disconnect()
}
}
}
function getInitialTransform(transitionType: string): string {
switch (transitionType) {
case 'fade-up':
return 'translateY(5em)'
case 'fade-down':
return 'translateY(-5em)'
case 'slide-left':
return 'translateX(5em)'
case 'slide-right':
return 'translateX(-5em)'
case 'scale':
return 'scale(0.8)'
case 'scale-up':
return 'scale(1.2)'
case 'rotate':
return 'rotate(180deg)'
case 'rotate-left':
return 'translateY(100px) rotate(12deg) scale(0.9)'
case 'rotate-right':
return 'translateY(100px) rotate(-12deg) scale(0.9)'
case 'flip-x':
return 'rotateX(90deg)'
case 'flip-y':
return 'rotateY(90deg)'
default:
return ''
}
}