ENH - clean app opening animations

This commit is contained in:
Eichenholz
2026-08-03 19:54:25 +02:00
parent e02c619d77
commit bda7b32080
5 changed files with 31 additions and 19 deletions
+13 -6
View File
@@ -573,20 +573,27 @@ button {
overflow: hidden;
background: #000;
transform-origin: 0 0;
backface-visibility: hidden;
will-change: transform, border-radius, opacity;
}
.app-window-enter-active {
transition:
transform 0.46s cubic-bezier(0.32, 0.72, 0, 1),
border-radius 0.46s cubic-bezier(0.32, 0.72, 0, 1),
opacity 0.18s ease-out;
}
.app-window-enter-active,
.app-window-leave-active {
transition:
transform 0.48s cubic-bezier(0.22, 0.95, 0.28, 1),
opacity 0.35s,
border-radius 0.48s;
transform 0.4s cubic-bezier(0.32, 0, 0.67, 0),
border-radius 0.4s cubic-bezier(0.32, 0, 0.67, 0),
opacity 0.22s ease-in;
}
.app-window-enter-from,
.app-window-leave-to {
transform: translate(var(--launch-x), var(--launch-y))
scale(var(--launch-scale-x), var(--launch-scale-y));
opacity: 0.15;
border-radius: 70px;
opacity: 0.72;
border-radius: var(--launch-radius);
}
.app-window-enter-to,
.app-window-leave-from {
+13 -8
View File
@@ -24,16 +24,21 @@ const iconFailed = ref(false)
function launch(event: MouseEvent): void {
const button = event.currentTarget as HTMLElement
const screen = button.closest('.phone-screen')
if (screen) {
const origin = button.getBoundingClientRect()
const icon = button.querySelector<HTMLElement>('.app-icon')
if (screen && icon) {
const origin = icon.getBoundingClientRect()
const target = screen.getBoundingClientRect()
const scaleX = origin.width / target.width
const scaleY = origin.height / target.height
const screenScaleX = target.width / screen.clientWidth
const screenScaleY = target.height / screen.clientHeight
const iconRadius = Number.parseFloat(getComputedStyle(icon).borderRadius)
phone.setLaunchOrigin({
height: origin.height,
scaleX: origin.width / target.width,
scaleY: origin.height / target.height,
width: origin.width,
x: origin.left - target.left,
y: origin.top - target.top,
borderRadius: iconRadius / Math.min(scaleX, scaleY),
scaleX,
scaleY,
x: (origin.left - target.left) / screenScaleX,
y: (origin.top - target.top) / screenScaleY,
})
} else {
phone.setLaunchOrigin(null)
+1 -2
View File
@@ -9,10 +9,9 @@ export type PhoneAppId =
| 'settings'
export type AppLaunchOrigin = {
height: number
borderRadius: number
scaleX: number
scaleY: number
width: number
x: number
y: number
}
+2 -1
View File
@@ -11,6 +11,7 @@ const app = computed(() => getPhoneApp(route.params.appId))
const launchStyle = computed(() => {
const origin = phone.launchOrigin
return {
'--launch-radius': `${origin?.borderRadius ?? 72}px`,
'--launch-scale-x': origin?.scaleX ?? 0.82,
'--launch-scale-y': origin?.scaleY ?? 0.82,
'--launch-x': `${origin?.x ?? 35}px`,
@@ -20,7 +21,7 @@ const launchStyle = computed(() => {
</script>
<template>
<div v-if="app" class="phone-app-window" :style="launchStyle">
<div v-if="app" class="app-window" :style="launchStyle">
<Suspense>
<component :is="app.component" />
<template #fallback>
+2 -2
View File
@@ -4,8 +4,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sky Phone</title>
<script type="module" crossorigin src="./assets/sky-index-pigPEft5.js"></script>
<link rel="stylesheet" crossorigin href="./assets/sky-index-6EjazFkC.css">
<script type="module" crossorigin src="./assets/sky-index-B21bXyap.js"></script>
<link rel="stylesheet" crossorigin href="./assets/sky-index-DIba77eO.css">
</head>
<body>
<div id="app"></div>