V2: Origin based animations, Gesture Builder, New Demo, non-url-based-routing. Massive improvements.
This commit is contained in:
105
apps/origins-demo/src/views/PlayerView.vue
Normal file
105
apps/origins-demo/src/views/PlayerView.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, ref } from "vue";
|
||||
import {
|
||||
OriginGesture,
|
||||
back,
|
||||
gesture,
|
||||
useOrigin,
|
||||
type OriginContext,
|
||||
} from "@native-vue-router/core-v2";
|
||||
import InstanceCard from "../components/InstanceCard.vue";
|
||||
import { useDemoInstance } from "../lab-state";
|
||||
import { coverDown } from "../motions";
|
||||
|
||||
const origin = useOrigin();
|
||||
const identity = useDemoInstance("Player");
|
||||
const playing = ref(false);
|
||||
const position = ref(38);
|
||||
const elapsed = computed(() => `1:${String(position.value).padStart(2, "0")}`);
|
||||
const timer = window.setInterval(() => {
|
||||
if (playing.value) position.value = (position.value + 1) % 60;
|
||||
}, 1000);
|
||||
onBeforeUnmount(() => window.clearInterval(timer));
|
||||
|
||||
const dismiss = (context: OriginContext) =>
|
||||
context.canGoBack ? back(coverDown) : null;
|
||||
|
||||
const dismissGesture = gesture.to
|
||||
.down()
|
||||
.navigate((context) => (context.canGoBack ? back() : null))
|
||||
.animate(coverDown);
|
||||
|
||||
function close() {
|
||||
const action = dismiss(origin.context.value);
|
||||
if (action) void origin.perform(action);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<OriginGesture class="player-view" :gesture="dismissGesture">
|
||||
<header class="player-header">
|
||||
<button type="button" data-origin-gesture="ignore" @click="close">
|
||||
⌄
|
||||
</button>
|
||||
<span>Now playing</span>
|
||||
<button type="button" data-origin-gesture="ignore">•••</button>
|
||||
</header>
|
||||
|
||||
<div class="album-art">
|
||||
<span class="album-ring album-ring--one" />
|
||||
<span class="album-ring album-ring--two" />
|
||||
<span class="album-center">O</span>
|
||||
</div>
|
||||
|
||||
<section class="track-copy">
|
||||
<div>
|
||||
<h1>Independent Frames</h1>
|
||||
<p>The Scene Graph</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
data-origin-gesture="ignore"
|
||||
:aria-pressed="playing"
|
||||
@click="playing = !playing"
|
||||
>
|
||||
{{ playing ? "♥" : "♡" }}
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<label class="timeline">
|
||||
<input
|
||||
v-model="position"
|
||||
data-origin-gesture="ignore"
|
||||
type="range"
|
||||
min="0"
|
||||
max="59"
|
||||
/>
|
||||
<span>{{ elapsed }}</span>
|
||||
<span>3:42</span>
|
||||
</label>
|
||||
|
||||
<div class="player-controls">
|
||||
<button type="button" data-origin-gesture="ignore">↶</button>
|
||||
<button
|
||||
class="play-button"
|
||||
type="button"
|
||||
data-origin-gesture="ignore"
|
||||
@click="playing = !playing"
|
||||
>
|
||||
{{ playing ? "Ⅱ" : "▶" }}
|
||||
</button>
|
||||
<button type="button" data-origin-gesture="ignore">↷</button>
|
||||
</div>
|
||||
|
||||
<InstanceCard
|
||||
label="Player instance"
|
||||
:instance="identity.instance"
|
||||
:status="identity.status.value"
|
||||
/>
|
||||
<p class="policy-note">
|
||||
Swipe down anywhere to dismiss. Horizontal back is intentionally absent,
|
||||
like a native full-screen player.
|
||||
</p>
|
||||
<div class="drag-handle" />
|
||||
</OriginGesture>
|
||||
</template>
|
||||
Reference in New Issue
Block a user