forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
export type GridMode = 'bento' | 'uniform'
|
||||
|
||||
export function useGridMode() {
|
||||
const cookie = useCookie<GridMode>('grid-mode', {
|
||||
default: () => 'bento',
|
||||
maxAge: 60 * 60 * 24 * 365,
|
||||
sameSite: 'lax',
|
||||
})
|
||||
// useState ist über alle Komponenten geteilt — die Cookie-Ref ist es nicht zuverlässig
|
||||
const mode = useState<GridMode>('grid-mode', () => cookie.value)
|
||||
const uniform = computed(() => mode.value === 'uniform')
|
||||
const animating = ref(false)
|
||||
|
||||
async function toggle() {
|
||||
const next: GridMode = uniform.value ? 'bento' : 'uniform'
|
||||
if (!import.meta.client || animating.value) {
|
||||
mode.value = next
|
||||
cookie.value = next
|
||||
return
|
||||
}
|
||||
// FLIP: alte Positionen messen, solange das DOM noch den alten Zustand zeigt
|
||||
const tiles = Array.from(document.querySelectorAll<HTMLElement>('.upload-tile'))
|
||||
const oldRects = tiles.map(el => el.getBoundingClientRect())
|
||||
animating.value = true
|
||||
mode.value = next
|
||||
cookie.value = next
|
||||
await nextTick()
|
||||
tiles.forEach((el, i) => {
|
||||
const oldR = oldRects[i]
|
||||
const newR = el.getBoundingClientRect()
|
||||
const dx = oldR.left - newR.left
|
||||
const dy = oldR.top - newR.top
|
||||
const sx = newR.width ? oldR.width / newR.width : 1
|
||||
const sy = newR.height ? oldR.height / newR.height : 1
|
||||
if (!dx && !dy && sx === 1 && sy === 1) return
|
||||
el.animate(
|
||||
[
|
||||
{ transformOrigin: 'top left', transform: `translate(${dx}px, ${dy}px) scale(${sx}, ${sy})` },
|
||||
{ transformOrigin: 'top left', transform: 'none' },
|
||||
],
|
||||
{ duration: 400, easing: 'cubic-bezier(0.2, 0, 0, 1)' },
|
||||
)
|
||||
})
|
||||
setTimeout(() => {
|
||||
animating.value = false
|
||||
}, 400)
|
||||
}
|
||||
|
||||
return { mode, uniform, toggle }
|
||||
}
|
||||
Reference in New Issue
Block a user