Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"permissions": {
"allow": [
"Bash(bun install:*)",
"Bash(bun run:*)"
"Bash(bun run:*)",
"Bash(git checkout:*)",
"Bash(git pull:*)"
],
"deny": []
}
Expand Down
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
"dependencies": {
"@achrinza/node-ipc": "10.1.11",
"@iconscout/vue-unicons": "github:elasticdotventures/vue-unicons",
"@types/three": "^0.179.0",
"mitt": "^3.0.1",
"path": "^0.12.7",
"pinia": "3.0.3",
"three": "^0.179.1",
"v-idle-3": "^0.3.14",
"vue": "3.5.18",
"vue-cookie-law": "github:elasticdotventures/vue-cookie-law",
Expand Down
Binary file added public/sample.glb
Binary file not shown.
137 changes: 137 additions & 0 deletions src/components/Logo3D.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import * as THREE from 'three'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'

const canvasRef = ref<HTMLCanvasElement | null>(null)
const mouseX = ref(0)
const mouseY = ref(0)

let scene: THREE.Scene
let camera: THREE.PerspectiveCamera
let renderer: THREE.WebGLRenderer
let model: THREE.Group | null = null
let spotLight: THREE.SpotLight
let frontLight: THREE.DirectionalLight
let animationId: number

const initThreeJS = () => {
if (!canvasRef.value) return

// Scene
scene = new THREE.Scene()

// Camera
camera = new THREE.PerspectiveCamera(75, 1, 0.1, 1000)
camera.position.z = 5 // Moved camera back to accommodate larger model

// Renderer
renderer = new THREE.WebGLRenderer({
canvas: canvasRef.value,
alpha: true,
antialias: true,
powerPreference: "high-performance"
})
renderer.setSize(100, 100)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
renderer.setClearColor(0x000000, 0)
renderer.outputColorSpace = THREE.SRGBColorSpace
renderer.toneMapping = THREE.ACESFilmicToneMapping
renderer.toneMappingExposure = 1.0

// Lights
const ambientLight = new THREE.AmbientLight(0xffffff, 0.1)
scene.add(ambientLight)

// Create spotlight that follows mouse
spotLight = new THREE.SpotLight(0xffffff, 100, 100, Math.PI / 4, 0.5, 2)
spotLight.position.set(0, 0, 10)
spotLight.target.position.set(0, 0, 0)
scene.add(spotLight)
scene.add(spotLight.target)

// Add bright front-facing directional light
frontLight = new THREE.DirectionalLight(0xffffff, 15)
frontLight.position.set(0, 0, 10)
scene.add(frontLight)

// Load GLB model
const loader = new GLTFLoader()
loader.load('/sample.glb', (gltf) => {
model = gltf.scene
model.scale.setScalar(5.5) // Scale set to 5.5
scene.add(model)
}, undefined, (error) => {
console.error('Error loading GLB model:', error)
})

// Animation loop
const animate = () => {
animationId = requestAnimationFrame(animate)

if (model) {
// Apply mouse-based rotation
model.rotation.y = mouseX.value * 0.3
model.rotation.x = mouseY.value * 0.2

// Move spotlight to mouse position
const lightDistance = 8
spotLight.position.set(
mouseX.value * lightDistance,
mouseY.value * lightDistance,
10
)
spotLight.target.position.copy(model.position)
}

renderer.render(scene, camera)
}
animate()
}

const updateMousePosition = (event: MouseEvent) => {
if (!canvasRef.value) return

const rect = canvasRef.value.getBoundingClientRect()
const centerX = rect.left + rect.width / 2
const centerY = rect.top + rect.height / 2

const deltaX = event.clientX - centerX
const deltaY = event.clientY - centerY

const maxDistance = 200
mouseX.value = Math.max(-1, Math.min(1, deltaX / maxDistance))
mouseY.value = Math.max(-1, Math.min(1, deltaY / maxDistance))
}

onMounted(() => {
initThreeJS()
document.addEventListener('mousemove', updateMousePosition)
})

onUnmounted(() => {
document.removeEventListener('mousemove', updateMousePosition)
if (animationId) {
cancelAnimationFrame(animationId)
}
if (renderer) {
renderer.dispose()
}
})
</script>

<template>
<canvas
ref="canvasRef"
class="logo-3d"
/>
</template>

<style scoped>
.logo-3d {
width: 100px;
height: 100px;
margin-right: 10px;
cursor: pointer;
}
</style>
80 changes: 75 additions & 5 deletions src/components/PromptExecutionLogo.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,56 @@
<script setup lang="ts">
// import { ref } from 'vue'
// defineProps<{ msg: string }>()
// const count = ref(0)
import { ref, onMounted, onUnmounted } from 'vue'
import Logo3D from './Logo3D.vue'

const show3D = ref(false)
let idleTimer: number | null = null

const startIdleTimer = () => {
if (idleTimer) clearTimeout(idleTimer)

// Show 3D immediately on mouse activity
show3D.value = true

// Set timer to hide 3D after 2 seconds of inactivity
idleTimer = setTimeout(() => {
show3D.value = false
}, 2000)
}

const handleMouseMove = () => {
startIdleTimer()
}

onMounted(() => {
document.addEventListener('mousemove', handleMouseMove)
// Start with 2D logo (show3D = false by default)
})

onUnmounted(() => {
document.removeEventListener('mousemove', handleMouseMove)
if (idleTimer) clearTimeout(idleTimer)
})
</script>

<template>
<div class="logo-wrapper">
<div class="logo-container">
<img src="/PromptExecution-LogoV2-full-transparent.webp" class="logo-head" alt="Cybernetic Head"/>
<!-- 2D Logo -->
<img
src="/PromptExecution-LogoV2-full-transparent.png"
class="logo-2d"
:class="{ 'fade-out': show3D }"
alt="Cybernetic Head"
/>

<!-- 3D Logo -->
<div class="logo-3d-wrapper" :class="{ 'fade-in': show3D }">
<Logo3D />
</div>

<!-- Spacer to maintain layout -->
<div class="logo-spacer"></div>

<div class="text-container">
<div class="logo-title">PROMPT EXECUTION</div>
<div class="logo-subtitle">COGNITIVE ROBOTIC PROCESS AUTOMATION</div>
Expand Down Expand Up @@ -55,9 +98,36 @@
display: flex;
align-items: center;
height: 122px;
position: relative;
}

.logo-2d, .logo-3d-wrapper {
width: 100px;
height: 100px;
margin-right: 10px;
position: absolute;
transition: opacity 0.6s ease-in-out;
}

.logo-2d {
opacity: 1;
z-index: 1;
}

.logo-2d.fade-out {
opacity: 0;
}

.logo-3d-wrapper {
opacity: 0;
z-index: 2;
}

.logo-3d-wrapper.fade-in {
opacity: 1;
}

.logo-head {
.logo-spacer {
width: 100px;
height: 100px;
margin-right: 10px;
Expand Down