Skip to content

Commit b677a8a

Browse files
committed
major overhaul - refined editor, added touch, added mobile view
1 parent d60c999 commit b677a8a

18 files changed

+882
-335
lines changed

demo/@/components/custom/CopyButton.vue

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
<template>
2-
<Button
3-
v-bind="$attrs"
4-
class="relative p-2 bg-transparent hover:bg-transparent hover:scale-105 rounded-md"
5-
@click="handleClick"
6-
>
2+
<Button v-bind="$attrs" @click="handleClick">
73
<Clipboard v-bind="$attrs" class="clipboard" ref="clipboard" />
84
<ClipboardCheck
95
v-bind="$attrs"
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<template>
2+
<template v-for="(char, index) in currentText" :key="index">
3+
<span
4+
class="lift-down"
5+
v-bind="$attrs"
6+
v-if="char !== '\n'"
7+
:style="{
8+
animationDelay: `${index * offset}s`,
9+
animationDuration: `${text.length * offset + offset * 10}s`,
10+
}"
11+
>{{ char }}</span
12+
>
13+
<template v-else>
14+
<br class="w-screen" />
15+
</template>
16+
</template>
17+
</template>
18+
19+
<script setup lang="ts">
20+
import { watch } from "vue";
21+
import { useWindowSize } from "@vueuse/core";
22+
23+
const HTML_SPACE = "\u00a0";
24+
const { width } = useWindowSize();
25+
26+
let { text } = $defineProps({
27+
text: {
28+
type: String,
29+
required: true,
30+
},
31+
});
32+
33+
const offset = 0.3;
34+
35+
let newText = $ref(text.replace(/ /g, HTML_SPACE));
36+
37+
let brokenText = $ref(newText.replace(/\s/, HTML_SPACE + "\n"));
38+
39+
let currentText = $ref(brokenText);
40+
41+
watch(
42+
() => width.value,
43+
(val) => {
44+
if (val < 768) {
45+
currentText = brokenText;
46+
} else {
47+
currentText = newText;
48+
}
49+
},
50+
{ immediate: true },
51+
);
52+
</script>
53+
54+
<style lang="scss" scoped>
55+
.lift-down {
56+
display: inline-block;
57+
animation: liftDown 3s ease-in-out infinite;
58+
animation-fill-mode: forwards;
59+
}
60+
61+
@keyframes liftDown {
62+
0%,
63+
100% {
64+
transform: translateY(0);
65+
}
66+
50% {
67+
transform: translateY(-5px);
68+
}
69+
}
70+
71+
.dot-fade {
72+
display: inline-block;
73+
animation: dotFade 4s ease-in-out infinite;
74+
animation-fill-mode: forwards;
75+
}
76+
77+
@keyframes dotFade {
78+
0%,
79+
100% {
80+
opacity: 0;
81+
}
82+
50% {
83+
opacity: 1;
84+
}
85+
}
86+
</style>

demo/@/components/custom/animation-controls/AnimationControls.vue

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
<template>
2-
<div class="grid h-screen z-10 p-4 relative">
2+
<div class="grid lg:h-screen h-full max-h-screen-md w-full max-w-screen-md z-10 relative">
33
<Tabs
4-
class="overflow-scroll"
4+
class="overflow-scroll p-4 w-full h-full"
55
:model-value="storedControls.selectedControl"
66
@update:model-value="
77
(key) => {
88
storedControls.selectedControl = key.toString();
99
}
1010
"
1111
>
12-
<TabsList class="w-full flex gap-2 sticky top-0 overflow-x-scroll">
13-
<TabsTrigger value="controls">Controls</TabsTrigger>
14-
<TabsTrigger value="keyframes">Keyframes</TabsTrigger>
15-
<slot name="tabs-trigger"></slot>
12+
<TabsList class="w-full flex gap-2 sticky top-0">
13+
<div class="flex w-full items-center justify-center overflow-x">
14+
<TabsTrigger value="controls">Controls</TabsTrigger>
15+
<TabsTrigger value="keyframes">Keyframes</TabsTrigger>
16+
<slot name="tabs-trigger"></slot>
17+
</div>
1618
</TabsList>
1719

18-
<div>
20+
<div class="">
1921
<!-- <CardHeader class="grid gap-0">
2022
<CardTitle>{{
2123
controlNames[storedControls.selectedControl] ?? "🙂‍↔️"
@@ -26,7 +28,6 @@
2628
{{ animation.name }}
2729
</div>
2830
</CardHeader> -->
29-
3031
<TabsContent value="controls">
3132
<Card>
3233
<CardContent class="pt-4 grid grid-cols-2 gap-1 items-center">

demo/@/components/custom/animation-controls/AnimationControlsGroup.vue

Lines changed: 41 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<template>
22
<div
3-
class="container grid h-screen w-full grid-cols-3 m-0 p-0 relative items-center overflow-hidden"
3+
class="w-full h-screen max-w-screen-xl max-h-screen-md grid lg:grid-cols-3 grid-cols-1 lg:grid-rows-1 justify-items-center justify-center items-center overflow-scroll lg:overflow-hidden relative"
4+
v-bind="$attrs"
45
>
56
<div
6-
class="info-bar absolute top-0 right-0 p-2 flex flex-row-reverse gap-4 items-center z-[200]"
7+
class="info-bar absolute top-0 w-full lg:w-min lg:right-0 p-4 pl-6 pr-6 lg:p-4 flex flex-row-reverse lg:gap-4 gap-6 items-center justify-between lg:justify-end z-[1000]"
78
>
8-
<DarkModeToggle class="dark-mode-toggle" />
9+
<DarkModeToggle />
910
<HoverCard :open-delay="0">
1011
<HoverCardTrigger
1112
><Button class="p-0 m-0 cursor-pointer" variant="link"
@@ -36,42 +37,26 @@
3637
</div>
3738
</HoverCardContent>
3839
</HoverCard>
39-
40-
<!-- <CommandPalette
41-
:super-key="superKey"
42-
:animations="
43-
Object.values(animationGroup.animations).map((a) => a.animation)
44-
"
45-
></CommandPalette> -->
4640
</div>
4741

4842
<template v-if="!storedControls.selectedAnimation">
4943
<div
50-
class="start-screen-text absolute grid items-center w-screen gap-0 left-4 top-32"
44+
class="start-screen-text lg:absolute mt-16 w-screen h-0 grid items-center gap-0 left-0 ml-8 top-0"
5145
>
52-
<h1 class="font-bold text-7xl m-0 p-0">
53-
<span
54-
class="fraunces lift-down depth-text"
55-
v-for="(char, index) in startScreenText"
56-
:key="index"
57-
:style="{
58-
animationDelay: `${index * 0.3}s`,
59-
animationDuration: `${startScreenText.length * 0.3 + 3}s`,
60-
}"
61-
>
62-
{{ char }}
63-
</span>
64-
<span
65-
class="depth-text dot-fade"
66-
v-for="(char, index) in ellipsisText"
67-
:key="index"
68-
:style="{
69-
animationDelay: `${index * 0.3}s`,
70-
animationDuration: `${ellipsisText.length * 0.3 + 1}s`,
71-
}"
72-
>
73-
{{ char }}
74-
</span>
46+
<h1 class="fraunces font-bold lg:text-7xl text-6xl p-0 grid lg:flex">
47+
<div>
48+
<AnimatedText
49+
class="depth-text"
50+
:text="startScreenText"
51+
></AnimatedText>
52+
</div>
53+
54+
<div>
55+
<AnimatedText
56+
class="dot-fade depth-text"
57+
:text="ellipsisText"
58+
></AnimatedText>
59+
</div>
7560
</h1>
7661
<h2 class="fraunces italic font-light text-4xl w-full">
7762
from the list <List class="inline"></List> below.
@@ -88,7 +73,7 @@
8873
>
8974
<AnimationControls
9075
v-if="storedControls.selectedAnimation == name"
91-
class="animation-controls col-span-1"
76+
class="col-span-1"
9277
@slider-update="sliderUpdate"
9378
@keyframes-update="keyframesUpdate"
9479
:animation="groupObject.animation"
@@ -104,12 +89,19 @@
10489
</AnimationControls>
10590
</template>
10691

107-
<div :class="storedControls.selectedAnimation ? 'col-span-2' : 'col-span-3'">
92+
<div
93+
:class="
94+
' ' +
95+
(storedControls?.selectedAnimation == null
96+
? 'col-span-3'
97+
: 'col-span-2')
98+
"
99+
>
108100
<slot name="animation-content"> </slot>
109101
</div>
110102

111103
<div
112-
class="menu-bar col-span-3 absolute bottom-0 p-4 m-0 w-screen h-[min-content] flex items-center justify-center"
104+
class="sticky lg:absolute bottom-0 p-4 m-0 w-screen h-[min-content] flex items-center justify-center justify-items-center"
113105
>
114106
<Menubar class="flex items-center gap-1 justify-items-center">
115107
<MenubarMenu>
@@ -181,10 +173,17 @@
181173
</Menubar>
182174
</div>
183175
</div>
176+
177+
<ClientOnly>
178+
<Teleport to="html">
179+
<Toaster />
180+
</Teleport>
181+
</ClientOnly>
184182
</template>
185183

186184
<script setup lang="ts">
187-
import { onMounted, ref, watch } from "vue";
185+
import { Teleport, onMounted, ref, watch } from "vue";
186+
import { Toaster } from "vue-sonner";
188187
189188
import CommandPalette from "@components/custom/CommandPalette.vue";
190189
@@ -249,9 +248,10 @@ import {
249248
resetAllStores,
250249
} from "./animationStores";
251250
import { SelectIcon } from "radix-vue";
251+
import { useWindowSize } from "@vueuse/core";
252+
import AnimatedText from "./AnimatedText.vue";
252253
253254
let startScreenText = $ref("Select an animation");
254-
startScreenText = startScreenText.replace(/ /g, "\u00a0");
255255
let ellipsisText = $ref("...");
256256
257257
const { superKey, animationGroup } = defineProps<{
@@ -324,9 +324,10 @@ const reset = (target: HTMLElement, all: boolean = false) => {
324324
.play();
325325
326326
animationGroup.reset();
327+
storedControls.selectedAnimation = null;
327328
328329
if (all) {
329-
resetAllStores();
330+
// resetAllStores();
330331
window.location.reload();
331332
}
332333
};
@@ -351,74 +352,4 @@ onMounted(() => {});
351352
352353
background: var(--gradient);
353354
}
354-
355-
.lift-down {
356-
display: inline-block;
357-
animation: liftDown 3s ease-in-out infinite;
358-
animation-fill-mode: forwards;
359-
}
360-
361-
@keyframes liftDown {
362-
0%,
363-
100% {
364-
transform: translateY(0);
365-
}
366-
50% {
367-
transform: translateY(-5px);
368-
}
369-
}
370-
371-
.dot-fade {
372-
display: inline-block;
373-
animation: dotFade 4s ease-in-out infinite;
374-
animation-fill-mode: forwards;
375-
}
376-
377-
@keyframes dotFade {
378-
0%,
379-
100% {
380-
opacity: 0;
381-
}
382-
50% {
383-
opacity: 1;
384-
}
385-
}
386-
387-
.remove-outline > *,
388-
* {
389-
// remove all variations of all child outlines and borders, and focus states:
390-
// outline: none !important;
391-
// border: none !important;
392-
box-shadow: none !important;
393-
394-
&:focus {
395-
// outline: none !important;
396-
// border: none !important;
397-
box-shadow: none !important;
398-
}
399-
}
400-
401-
@media (max-width: 640px) {
402-
.container {
403-
grid-template-columns: 1fr;
404-
grid-template-rows: 1fr 1fr 1fr;
405-
gap: 0;
406-
407-
height: 100%;
408-
position: relative;
409-
}
410-
411-
.animation-controls {
412-
grid-row: span 1;
413-
height: 50px;
414-
}
415-
416-
.animation-content {
417-
grid-row: 2;
418-
}
419-
420-
.menu-bar {
421-
position: sticky !important;
422-
}
423-
}
424355
</style>

0 commit comments

Comments
 (0)