FIX: ScrambleText bug
IT IS SO SATISFYING 😍
This commit is contained in:
@@ -1,14 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="px-6 h-20 flex items-center bg-zinc-900 bg-opacity-40"
|
class="px-6 h-20 flex items-center bg-zinc-900 bg-opacity-40">
|
||||||
@mouseenter="$refs.configPaneTitle.scramble(0.15, 100)">
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-lg">
|
<h1 class="text-lg">
|
||||||
<ScrambleText ref="configPaneTitle" class="align-middle" :text="$t(`config_options.${page}.title`)" />
|
<ScrambleText class="align-middle" :text="$t(`config_options.${page}.title`)" />
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-xs text-muted-foreground">
|
<p class="text-xs text-muted-foreground">
|
||||||
{{ $t(`config_options.${page}.subtitle`) }}
|
<ScrambleText class="align-middle" :text="$t(`config_options.${page}.subtitle`)" :replace-interval="5" />
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,8 +6,7 @@
|
|||||||
:data-selected="current_tab===config.id"
|
:data-selected="current_tab===config.id"
|
||||||
class="px-4 h-20 flex items-center hover:bg-zinc-900 data-[selected=true]:bg-zinc-200 data-[selected=true]:text-black border-solid border-0 border-b"
|
class="px-4 h-20 flex items-center hover:bg-zinc-900 data-[selected=true]:bg-zinc-200 data-[selected=true]:text-black border-solid border-0 border-b"
|
||||||
:class="config.disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
|
:class="config.disabled ? 'cursor-not-allowed' : 'cursor-pointer'"
|
||||||
@click="current_tab=config.disabled ? current_tab : config.id; $refs.configSelect[index].scramble()"
|
@click="current_tab=config.disabled ? current_tab : config.id; $refs.configSelect[index].scramble()">
|
||||||
@mouseenter="$refs.configSelect[index].scramble(0.15, 100)">
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-lg" :class="{'text-muted-foreground': config.disabled}">
|
<h1 class="text-lg" :class="{'text-muted-foreground': config.disabled}">
|
||||||
<ScrambleText ref="configSelect" class="align-middle" :text="$t(`config_options.${config.id}.title`)" />
|
<ScrambleText ref="configSelect" class="align-middle" :text="$t(`config_options.${config.id}.title`)" />
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<Menubar class="w-full h-20 rounded-none bg-zinc-950 border-l-0">
|
<Menubar class="w-full h-20 rounded-none bg-zinc-950 border-l-0">
|
||||||
<div class="p-2">
|
<div class="p-2 min-w-48">
|
||||||
<h1 class="text-3xl">ZERO/ONE</h1>
|
<h1 class="text-3xl">
|
||||||
<p class="text-xs text-muted-foreground">Haptic Configuration Tool</p>
|
<ScrambleText
|
||||||
|
text="ZERO/ONE" scramble-on-mount :scramble-amount="1" :fill-interval="100"
|
||||||
|
:replace-interval="100" />
|
||||||
|
</h1>
|
||||||
|
<p class="text-xs text-muted-foreground">
|
||||||
|
<ScrambleText text="Haptic Configuration Tool" scramble-on-mount scramble-amount="1" fill-interval="35" replace-interval="40" />
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<MenubarMenu>
|
<MenubarMenu>
|
||||||
<MenubarTrigger v-t="'navbar.device.title'" />
|
<MenubarTrigger v-t="'navbar.device.title'" />
|
||||||
@@ -42,4 +48,5 @@ import {
|
|||||||
MenubarTrigger,
|
MenubarTrigger,
|
||||||
MenubarContent,
|
MenubarContent,
|
||||||
} from '@/components/ui/menubar/index.js'
|
} from '@/components/ui/menubar/index.js'
|
||||||
|
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||||
</script>
|
</script>
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
class="px-4 h-20 flex items-center"
|
class="px-4 h-20 flex items-center">
|
||||||
@mouseenter="$refs.configPaneTitle.scramble(0.15, 100)">
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-lg">
|
<h1 class="text-lg">
|
||||||
<ScrambleText ref="configPaneTitle" class="align-middle" :text="$t(`profiles.title`)" />
|
{{ $t(`profiles.title`) }}
|
||||||
</h1>
|
</h1>
|
||||||
<p class="text-xs text-muted-foreground">
|
<p class="text-xs text-muted-foreground">
|
||||||
{{ $t(`profiles.subtitle`) }}
|
{{ $t(`profiles.subtitle`) }}
|
||||||
@@ -36,7 +35,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import SchemaTest from '@/components/SchemaTest.vue'
|
import SchemaTest from '@/components/SchemaTest.vue'
|
||||||
import { Separator } from '@/components/ui/separator/index.js'
|
import { Separator } from '@/components/ui/separator/index.js'
|
||||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
|
||||||
import {
|
import {
|
||||||
Command,
|
Command,
|
||||||
CommandEmpty,
|
CommandEmpty,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<div class="px-4 py-5">
|
<div class="px-4 py-5">
|
||||||
<h1 class="text-lg">
|
<h1 class="text-lg">
|
||||||
<ScrambleReveal :text="$t('preview.title')" />
|
{{ $t('preview.title')}}
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
@@ -37,13 +37,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import ScrambleReveal from '@/components/effects/ScrambleText.vue'
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import DeviceBar from '@/components/device-gui/DeviceBar.vue'
|
import DeviceBar from '@/components/device-gui/DeviceBar.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DevicePreview',
|
name: 'DevicePreview',
|
||||||
components: { DeviceBar, ScrambleReveal },
|
components: { DeviceBar },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
profiles: [],
|
profiles: [],
|
||||||
|
|||||||
@@ -26,24 +26,52 @@ const props = defineProps({
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 15,
|
default: 15,
|
||||||
},
|
},
|
||||||
|
scrambleOnMount: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
let scrambling = false
|
|
||||||
|
|
||||||
const content = ref('')
|
const content = ref('')
|
||||||
|
|
||||||
function randomCharacter(characterSet = props.characterSet) {
|
function randomCharacter(characterSet = props.characterSet) {
|
||||||
return props.characterSet.charAt(Math.floor(Math.random() * characterSet.length))
|
return props.characterSet.charAt(Math.floor(Math.random() * characterSet.length))
|
||||||
}
|
}
|
||||||
|
|
||||||
function scramble(scrambleAmount = props.scrambleAmount, replaceInterval = props.replaceInterval, fillInterval = props.fillInterval, characterSet = props.characterSet, text = props.text) {
|
function replaceContent(text = props.text, replaceInterval = props.replaceInterval, steps = 0) {
|
||||||
if (scrambling) return
|
if (steps > text.length + 16) {
|
||||||
scrambling = true
|
content.value = text
|
||||||
|
}
|
||||||
|
console.log('hey')
|
||||||
|
if (content.value !== text) {
|
||||||
|
// get all the indices of characters that don't match text
|
||||||
|
const indices = []
|
||||||
|
for (let i = 0; i < text.length; i++) {
|
||||||
|
if (content.value.charAt(i) !== text.charAt(i)) {
|
||||||
|
indices.push(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (indices.length > 0) {
|
||||||
|
const index = indices[Math.floor(Math.random() * indices.length)]
|
||||||
|
content.value = content.value.substring(0, index) + text.charAt(index) + content.value.substring(index + 1)
|
||||||
|
} else if (content.value.length < text.length) {
|
||||||
|
content.value += text.charAt(content.value.length)
|
||||||
|
} else {
|
||||||
|
content.value = content.value.substring(0, content.value.length - 1)
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
replaceContent(text, replaceInterval, steps + 1)
|
||||||
|
}, replaceInterval * (1 + Math.random()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function scramble(scrambleAmount = props.scrambleAmount, replaceInterval = props.replaceInterval, fillInterval = props.fillInterval, characterSet = props.characterSet, text = props.text, fillText = props.text) {
|
||||||
content.value = ''
|
content.value = ''
|
||||||
const fillContent = function() {
|
const fillContent = function() {
|
||||||
if (content.value.length < text.length) {
|
if (content.value.length < text.length) {
|
||||||
if (Math.random() > scrambleAmount) {
|
const char = fillText.charAt(content.value.length) || ''
|
||||||
content.value += text.charAt(content.value.length)
|
if (char === ' ' || Math.random() > scrambleAmount) {
|
||||||
|
content.value += char
|
||||||
} else {
|
} else {
|
||||||
content.value += randomCharacter(characterSet)
|
content.value += randomCharacter(characterSet)
|
||||||
}
|
}
|
||||||
@@ -51,23 +79,7 @@ function scramble(scrambleAmount = props.scrambleAmount, replaceInterval = props
|
|||||||
setTimeout(fillContent, fillInterval)
|
setTimeout(fillContent, fillInterval)
|
||||||
else fillContent()
|
else fillContent()
|
||||||
} else {
|
} else {
|
||||||
const replaceContent = function() {
|
replaceContent(text, replaceInterval, 0)
|
||||||
if (content.value !== text) {
|
|
||||||
// get all the indices of characters that don't match text
|
|
||||||
const indices = []
|
|
||||||
for (let i = 0; i < content.value.length; i++) {
|
|
||||||
if (content.value.charAt(i) !== text.charAt(i)) {
|
|
||||||
indices.push(i)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const index = indices[Math.floor(Math.random() * indices.length)]
|
|
||||||
content.value = content.value.substring(0, index) + text.charAt(index) + content.value.substring(index + 1)
|
|
||||||
setTimeout(replaceContent, replaceInterval * (1 + Math.random()))
|
|
||||||
} else {
|
|
||||||
scrambling = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
replaceContent()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fillContent()
|
fillContent()
|
||||||
@@ -76,11 +88,15 @@ function scramble(scrambleAmount = props.scrambleAmount, replaceInterval = props
|
|||||||
defineExpose({ scramble })
|
defineExpose({ scramble })
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
scramble()
|
if (props.scrambleOnMount) {
|
||||||
|
scramble()
|
||||||
|
} else {
|
||||||
|
content.value = props.text
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(() => props.text, () => {
|
watch(() => props.text, () => {
|
||||||
scramble()
|
replaceContent()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user