初始化

This commit is contained in:
李琦
2026-01-15 14:57:36 +08:00
parent 20e6e9fb3f
commit a43dc4c7fb
7 changed files with 107 additions and 15878 deletions

View File

@@ -0,0 +1,33 @@
<template>
<code ref="codeBlock" :class="languageClass">{{ code }}</code>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, nextTick } from 'vue'
import hljs from 'highlight.js'
const props = defineProps<{
code: string
language: string
}>()
const codeBlock = ref<HTMLElement | null>(null)
const languageClass = `language-${props.language || 'plaintext'}`
const highlight = () => {
if (codeBlock.value) {
// Reset internal state if needed, though highlighting overwrites innerHTML
delete codeBlock.value.dataset.highlighted
hljs.highlightElement(codeBlock.value)
}
}
onMounted(() => {
highlight()
})
watch(() => props.code, () => {
nextTick(highlight)
})
</script>

View File

@@ -1,11 +1,12 @@
<template>
<div
v-if="isOpen"
class="fixed inset-0 z-[100] bg-black/90 backdrop-blur-sm flex items-center justify-center p-4 md:p-10 transition-opacity duration-300"
class="fixed inset-0 z-[100] flex items-center justify-center p-4 md:p-10 transition-opacity duration-300 pointer-events-auto"
:class="{ 'opacity-0': isAnimating, 'opacity-100': !isAnimating }"
>
<div class="absolute inset-0 bg-black/90 backdrop-blur-sm" @click="close"></div>
<div
class="bg-[#0a0a0c] border border-white/10 w-full max-w-6xl h-full md:h-[80vh] rounded-2xl flex flex-col overflow-hidden shadow-2xl transform transition-transform duration-300"
class="relative z-[101] bg-[#0a0a0c] border border-white/10 w-full max-w-6xl h-[80vh] rounded-2xl flex flex-col overflow-hidden shadow-2xl transform transition-transform duration-300"
:class="{ 'scale-95': isAnimating, 'scale-100': !isAnimating }"
>
<!-- Header -->
@@ -23,10 +24,10 @@
<div class="flex-1 flex flex-col md:flex-row h-full overflow-hidden">
<!-- Code Section -->
<div class="w-full md:w-1/2 bg-[#0d0d0d] overflow-auto p-6 border-r border-white/10 relative group">
<button class="absolute top-4 right-4 text-xs bg-white/10 px-2 py-1 rounded text-white/50 hover:text-white" @click="copyCode">
<button class="absolute top-4 right-4 text-xs bg-white/10 px-2 py-1 rounded text-white/50 hover:text-white z-10" @click="copyCode">
复制
</button>
<pre class="font-mono text-sm leading-relaxed text-gray-300">{{ code }}</pre>
<pre class="font-mono text-sm leading-relaxed"><code ref="codeBlock" :class="languageClass">{{ code }}</code></pre>
</div>
<!-- Preview Section -->
@@ -72,7 +73,8 @@
</template>
<script setup lang="ts">
import { ref, watch, onMounted, computed } from 'vue'
import { ref, watch, onMounted, computed, nextTick } from 'vue'
import hljs from 'highlight.js'
const props = defineProps<{
isOpen: boolean
@@ -87,6 +89,24 @@ const isAnimating = ref(true)
const mouseX = ref(0)
const mouseY = ref(0)
const containerRect = ref<DOMRect | null>(null)
const codeBlock = ref<HTMLElement | null>(null)
const languageClass = computed(() => {
const map: Record<string, string> = {
'mouse': 'javascript',
'glass': 'css',
'noise': 'xml',
'animate': 'css'
}
return `language-${map[props.type] || 'plaintext'}`
})
const highlightCode = () => {
if (codeBlock.value) {
delete codeBlock.value.dataset.highlighted
hljs.highlightElement(codeBlock.value)
}
}
// Watch isOpen to handle entry/exit animations
watch(() => props.isOpen, (newVal) => {
@@ -101,6 +121,11 @@ watch(() => props.isOpen, (newVal) => {
setTimeout(() => {
if (window.lucide) window.lucide.createIcons()
}, 50)
// Highlight code
nextTick(() => {
highlightCode()
})
} else {
document.body.style.overflow = ''
isAnimating.value = true