Skip to content

Commit 87c4beb

Browse files
committed
feat: visible canvas + toggle video
1 parent d746055 commit 87c4beb

File tree

1 file changed

+30
-18
lines changed

1 file changed

+30
-18
lines changed

src/App.vue

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import ControlRotary from './ControlRotary.vue';
88
let canvas, ctx, tempCanvas, tempCtx, audio
99
1010
const screen = ref()
11+
const canvasElement = ref()
1112
const video = ref()
1213
1314
const { toggle, isSupported } = useFullscreen(screen)
@@ -19,8 +20,6 @@ const recordedWidth = ref(0)
1920
const showVideo = ref(false)
2021
const initiated = ref(false)
2122
const vertical = useStorage('vertical', false)
22-
const invert = useStorage('inverted', false)
23-
2423
2524
const { width, height } = useWindowSize()
2625
const setSize = (w, h) => {
@@ -31,7 +30,7 @@ const setSize = (w, h) => {
3130
watch([width, height], ([w, h]) => setSize(w, h))
3231
3332
onMounted(() => {
34-
canvas = document.createElement('canvas')
33+
canvas = canvasElement.value
3534
ctx = canvas.getContext('2d')
3635
tempCanvas = document.createElement('canvas')
3736
tempCtx = tempCanvas.getContext('2d')
@@ -101,7 +100,6 @@ const startVideo = () => {
101100
</body></html>
102101
`);
103102
104-
// Function to handle the "Save Video" button click
105103
newWindow.saveVideo = () => {
106104
const a = newWindow.document.createElement('a');
107105
a.href = url;
@@ -124,7 +122,6 @@ const startRecording = () => {
124122
offscreenCtx = offscreenCanvas.getContext('2d');
125123
recording.value = Date.now();
126124
recordedWidth.value = speed.value;
127-
clear()
128125
};
129126
130127
const stopRecording = () => {
@@ -167,11 +164,11 @@ const recordFrame = () => {
167164
offscreenCtx.drawImage(recTemp, 0, 0)
168165
169166
offscreenCtx.drawImage(
170-
canvas, // Source canvas
171-
width.value - speed.value, 0, // Source area (rightmost line)
172-
speed.value, height.value, // Size of the copied area
173-
recordedWidth.value, 0, // Destination (append at the right)
174-
speed.value, height.value // Size of the destination area
167+
canvas,
168+
width.value - speed.value, 0,
169+
speed.value, height.value,
170+
recordedWidth.value, 0,
171+
speed.value, height.value
175172
)
176173
177174
recordedWidth.value = newWidth
@@ -221,15 +218,20 @@ onKeyStroke('Enter', (e) => { e.preventDefault(); clear(); })
221218
</script>
222219
223220
<template lang="pug">
224-
.flex.flex-col.justify-center.bg-black.relative
221+
.flex.flex-col.justify-center.bg-black.relative.w-full.items-center
225222
.fullscreen-container#screen(ref="screen")
226-
video.max-w-full(ref="video" @click="paused = !paused")
223+
canvas#spectrogram.max-w-full(
224+
@pointerdown="paused = !paused"
225+
ref="canvasElement"
226+
:width="width"
227+
:height="height"
228+
)
227229
button.absolute.m-auto.top-0.w-full.h-full.text-white.text-2xl(
228230
title="Press anywhere to start"
229231
v-if="!initiated"
230232
@click="initiate()") START
231233
232-
.flex.absolute.top-2.left-20.top-4.z-100.text-white.op-20.hover-op-100.transition(v-if="initiated")
234+
.flex.absolute.top-4.z-100.text-white.op-20.hover-op-100.transition(v-if="initiated")
233235
button.text-xl.select-none.cursor-pointer(@pointerdown="paused = !paused")
234236
.i-la-play(v-if="paused")
235237
.i-la-pause(v-else)
@@ -238,11 +240,15 @@ onKeyStroke('Enter', (e) => { e.preventDefault(); clear(); })
238240
.i-la-arrow-down(v-else)
239241
button.text-xl.select-none.cursor-pointer(@pointerdown="clear()")
240242
.i-la-trash-alt
241-
button.text-xl.select-none.cursor-pointer(@pointerdown="toggle()")
243+
button.text-xl.select-none.cursor-pointer(
244+
v-if="isSupported"
245+
@pointerdown="toggle()")
242246
.i-la-expand
247+
248+
.flex.absolute.bottom-2.mx-auto.z-100.text-white.op-20.hover-op-100.transition(v-if="initiated")
243249
button.text-xl.select-none.cursor-pointer.transition(
244-
v-if="video?.requestPictureInPicture"
245-
@pointerdown="video?.requestPictureInPicture?.()")
250+
:style="{ opacity: showVideo ? 1 : 0.5 }"
251+
@pointerdown="showVideo = !showVideo; showVideo && video?.requestPictureInPicture?.()")
246252
.i-la-external-link-square-alt
247253
button.text-xl.select-none.cursor-pointer.flex.items-center.gap-1(
248254
:class="{ 'text-red': recording }"
@@ -257,15 +263,21 @@ onKeyStroke('Enter', (e) => { e.preventDefault(); clear(); })
257263
.p-0.text-sm.font-mono(v-if="videoRecording") {{ ((time - videoRecording) / 1000).toFixed() }}s
258264
259265
260-
.absolute.top-14.left-2.flex.flex-col.text-white.items-center.overscroll-none.overflow-x-hidden.overflow-y-scroll.bg-dark-900.bg-op-20.backdrop-blur.op-40.hover-op-100.transition(v-show="initiated")
266+
.absolute.my-auto.left-2.flex.flex-col.text-white.items-center.overscroll-none.overflow-x-hidden.overflow-y-scroll.bg-dark-900.bg-op-20.backdrop-blur.op-40.hover-op-100.transition.max-h-100vh.overflow-y-scroll.scrollbar-thin.rounded-xl.p-2(v-show="initiated" style="scrollbar-width: none;")
261267
.is-group.flex.flex-col.gap-2
262268
ControlRotary(v-model="speed" :min="1" :max="5" :step="1" :fixed="0" param="SPEED")
263269
ControlRotary(v-model="frame" :min="1" :max="4" :step="1" :fixed="0" param="FRAME")
264270
ControlRotary(v-model="steepness" :min="3" :max="30" :step="0.0001" :fixed="2" param="CONTRAST")
265271
ControlRotary(v-model="midpoint" :min="0" :max="1" :step=".0001" param="MIDPOINT" :fixed="2")
266272
ControlRotary(v-model="smoothing" :min="0" :max="1" :step=".0001" param="SMOOTH" :fixed="2")
267273
268-
274+
275+
.fixed.overflow-clip.text-white.transition.bottom-22.rounded-xl.overflow-hidden.rounded-xl.border-1(v-show="showVideo")
276+
.relative.mx-auto
277+
.absolute.p-4.opacity-70.touch-none.select-none.text-md.mr-10 Right click here to enter Picture-In-Picture mode
278+
video.max-h-80.max-w-full(ref="video")
279+
button.absolute.top-2.right-2(@click="showVideo = false")
280+
.i-la-times
269281
</template>
270282
271283
<style lang="postcss" scoped>

0 commit comments

Comments
 (0)