๐Ÿ“ฆ aquaticcalf / non-euclidean-museum

๐Ÿ“„ interaction-prompt.tsx ยท 90 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90"use client"

import { useState, useEffect } from "react"
import { motion, AnimatePresence } from "framer-motion"

interface InteractionPromptProps {
  isVisible: boolean
  action: string
  keyPrompt: string
  description?: string
  onInteract?: () => void
}

export default function InteractionPrompt({
  isVisible = false,
  action = "Interact",
  keyPrompt = "E",
  description,
  onInteract,
}: InteractionPromptProps) {
  const [keyPressed, setKeyPressed] = useState(false)

  // Handle key press
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (isVisible && e.key.toLowerCase() === keyPrompt.toLowerCase()) {
        setKeyPressed(true)
        if (onInteract) onInteract()
      }
    }

    const handleKeyUp = (e: KeyboardEvent) => {
      if (e.key.toLowerCase() === keyPrompt.toLowerCase()) {
        setKeyPressed(false)
      }
    }

    window.addEventListener("keydown", handleKeyDown)
    window.addEventListener("keyup", handleKeyUp)

    return () => {
      window.removeEventListener("keydown", handleKeyDown)
      window.removeEventListener("keyup", handleKeyUp)
    }
  }, [isVisible, keyPrompt, onInteract])

  return (
    <AnimatePresence>
      {isVisible && (
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          exit={{ opacity: 0, y: 10 }}
          className="fixed bottom-32 left-1/2 transform -translate-x-1/2 pointer-events-none"
        >
          <div className="flex flex-col items-center">
            <div className="flex items-center mb-1">
              <motion.div
                animate={{
                  scale: keyPressed ? 0.9 : 1,
                  backgroundColor: keyPressed ? "rgba(0, 255, 255, 0.8)" : "rgba(0, 170, 255, 0.2)",
                }}
                className="w-8 h-8 flex items-center justify-center border border-cyan-400 text-cyan-400 font-mono text-sm font-bold mr-2"
              >
                {keyPrompt}
              </motion.div>
              <span className="text-white font-mono text-sm tracking-wide">{action}</span>
            </div>
            {description && (
              <span className="text-cyan-300/80 font-mono text-xs max-w-xs text-center">{description}</span>
            )}
            <motion.div
              animate={{
                opacity: [0.3, 1, 0.3],
              }}
              transition={{
                duration: 1.5,
                repeat: Number.POSITIVE_INFINITY,
                ease: "linear",
              }}
              className="w-24 h-px bg-gradient-to-r from-transparent via-cyan-400 to-transparent mt-2"
            />
          </div>
        </motion.div>
      )}
    </AnimatePresence>
  )
}