@@ -201,7 +778,62 @@ export default function WorkFlow() {
) : (
<>
{taskObject?.projectName}:{taskObject?.taskName}
-
{taskObject?.taskDescription}
+ {/* 实时反馈当前 currentLoadingText */}
+
+
+
+ {currentLoadingText}
+
+
+
+
>
)}
@@ -212,31 +844,13 @@ export default function WorkFlow() {
) : (
<>
- {
- currentStep === '1' ? (
-
- {renderSketchContent()}
-
- ) : (
-
- )
- }
-
+
+ {renderSketchContent()}
+
>
)}
-
+
{isLoading ? (
<>
@@ -247,59 +861,99 @@ export default function WorkFlow() {
) : (
setIsDragging(false)}
>
- {currentStep === '1' ? (
+ {currentStep === '3' ? (
<>
- {taskSketch.map((sketch, index) => (
-
!isDragging && setCurrentSketchIndex(index)}
- initial={false}
- animate={{
- scale: currentSketchIndex === index ? 1.05 : 1,
- rotateY: currentSketchIndex === index ? 5 : 0,
- rotateX: currentSketchIndex === index ? -5 : 0,
- translateZ: currentSketchIndex === index ? '20px' : '0px',
- transition: {
- type: "spring",
- stiffness: 300,
- damping: 20
- }
- }}
- style={{
- transformStyle: 'preserve-3d',
- perspective: '1000px'
- }}
+ {renderedVideos}
+ {isGeneratingVideo && taskVideos.length < taskSketch.length && (
+
-
+
- 场景 {index + 1}
+ 场景 {taskVideos.length + 1}
- ))}
- {isGeneratingSketch && sketchCount < MOCK_SKETCH_COUNT && (
-
-
-
)}
>
) : (
<>
+ {renderedSketches}
+ {isGeneratingSketch && sketchCount < MOCK_SKETCH_COUNT && (
+
+
+
+ 场景 {sketchCount + 1}
+
+
+ )}
>
)}
@@ -311,22 +965,21 @@ export default function WorkFlow() {
{/* AI 建议栏 */}
-
-
-
-
-
+
+
+
setIsEditModalOpen(false)}
+ taskStatus={taskObject?.taskStatus || '1'}
+ taskSketch={taskSketch}
+ currentSketchIndex={currentSketchIndex}
+ onSketchSelect={setCurrentSketchIndex}
+ />
)
}
\ No newline at end of file
diff --git a/components/parallax.tsx b/components/parallax.tsx
new file mode 100644
index 0000000..3234f3b
--- /dev/null
+++ b/components/parallax.tsx
@@ -0,0 +1,221 @@
+import React, { useEffect, useRef } from 'react';
+import styled from 'styled-components';
+
+// 导入图片资源
+import mono from '@/assets/3dr_mono.png';
+import chihiro from '@/assets/3dr_chihiro.png';
+import howlcastle from '@/assets/3dr_howlcastle.png';
+import monobg from '@/assets/3dr_monobg.jpg';
+import spirited from '@/assets/3dr_spirited.jpg';
+import howlbg from '@/assets/3dr_howlbg.jpg';
+
+const Parallax = () => {
+ const pageXRef = useRef(null);
+ const cardsRef = useRef(null);
+
+ useEffect(() => {
+ const pageX = pageXRef.current;
+ const cards = cardsRef.current;
+ const images = document.querySelectorAll('.card__img');
+ const backgrounds = document.querySelectorAll('.card__bg');
+
+ let timeout;
+ const range = 40;
+
+ // 计算旋转角度
+ const calcValue = (a, b) => ((a / b) * range - range / 2).toFixed(1);
+
+ // 视差动画函数
+ const parallax = (e) => {
+ const x = e.clientX;
+ const y = e.clientY;
+
+ if (timeout) {
+ window.cancelAnimationFrame(timeout);
+ }
+
+ timeout = window.requestAnimationFrame(() => {
+ const xValue = calcValue(x, window.innerWidth);
+ const yValue = calcValue(y, window.innerHeight);
+
+ // 设置卡片容器的旋转角度
+ cards.style.transform = `rotateX(${yValue}deg) rotateY(${xValue}deg)`;
+
+ // 设置所有图片的位移
+ images.forEach(item => {
+ item.style.transform = `translateX(${-xValue}px) translateY(${yValue}px)`;
+ });
+
+ // 设置所有背景的位置
+ backgrounds.forEach(item => {
+ item.style.backgroundPosition = `${xValue * 0.45}px ${-yValue * 0.45}px`;
+ });
+ });
+ };
+
+ pageX.addEventListener('mousemove', parallax, false);
+
+ return () => {
+ if (pageX) {
+ pageX.removeEventListener('mousemove', parallax);
+ }
+ };
+ }, []);
+
+ return (
+
+
+ Movies
+ Popular
+
+ {/* 幽灵公主 */}
+
+
+
+
+ Princess Mononoke
+
+
+
+ {/* 千与千寻 */}
+
+
+
+
+ Spirited Away
+
+
+
+ {/* 哈尔的移动城堡 */}
+
+
+
+
+ Howl's Moving Castle
+
+
+
+
+ );
+};
+
+// 样式定义
+const PageX = styled.div`
+ width: 1000px;
+ height: 700px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden;
+ perspective: 1800px;
+ background: #642b73;
+ background: linear-gradient(to bottom, #c6426e, #642b73);
+`;
+
+const Cards = styled.div`
+ display: inline-block;
+ min-width: 595px;
+ padding: 30px 35px;
+ perspective: 1800px;
+ transform-origin: 50% 50%;
+ transform-style: preserve-3d;
+ border-radius: 15px;
+ text-align: left;
+ background: #fff;
+ box-shadow: 0px 10px 20px 20px rgba(0, 0, 0, 0.17);
+
+ h1 {
+ margin-bottom: 30px;
+ transform: translateZ(35px);
+ letter-spacing: -1px;
+ font-size: 32px;
+ font-weight: 800;
+ color: #3e3e42;
+ }
+
+ h3 {
+ margin-bottom: 6px;
+ transform: translateZ(25px);
+ font-size: 16px;
+ color: #eb285d;
+ }
+`;
+
+const Card = styled.div`
+ display: inline-block;
+ width: 175px;
+ height: 250px;
+ position: relative;
+ overflow: hidden;
+ perspective: 1200px;
+ transform-style: preserve-3d;
+ transform: translatez(35px);
+ transition: transform 200ms ease-out;
+ text-align: center;
+ border-radius: 15px;
+ box-shadow: 5px 5px 20px -5px rgba(0, 0, 0, 0.6);
+
+ &:not(:last-child) {
+ margin-right: 30px;
+ }
+
+ &.princess-mononoke .card__img {
+ top: 14px;
+ right: -10px;
+ height: 110%;
+ }
+
+ &.spirited-away .card__img {
+ top: 25px;
+ }
+
+ &.howl-s-moving-castle .card__img {
+ top: 5px;
+ left: -4px;
+ height: 110%;
+ }
+`;
+
+const CardBg = styled.div`
+ bottom: -50px;
+ left: -50px;
+ position: absolute;
+ right: -50px;
+ top: -50px;
+ transform-origin: 50% 50%;
+ transform: translateZ(-50px);
+ z-index: 0;
+ background: ${props => `url(${props.bg}) center/cover no-repeat`};
+`;
+
+const CardImg = styled.img`
+ position: relative;
+ height: 100%;
+`;
+
+const CardText = styled.div`
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 70px;
+ position: absolute;
+ z-index: 2;
+ bottom: 0;
+ background: linear-gradient(
+ to bottom,
+ rgba(0, 0, 0, 0) 0%,
+ rgba(0, 0, 0, 0.55) 100%
+ );
+`;
+
+const CardTitle = styled.p`
+ margin-bottom: 3px;
+ padding: 0 10px;
+ font-size: 18px;
+ font-weight: 700;
+ color: #fff;
+`;
+
+export default Parallax;
\ No newline at end of file
diff --git a/components/ui/edit-modal.tsx b/components/ui/edit-modal.tsx
new file mode 100644
index 0000000..fbde2a6
--- /dev/null
+++ b/components/ui/edit-modal.tsx
@@ -0,0 +1,173 @@
+'use client';
+
+import React, { useState } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import { X, FileText, Users, Video, Music, Scissors, Settings } from 'lucide-react';
+import { cn } from '@/lib/utils';
+import { ScriptTabContent } from './script-tab-content';
+
+interface EditModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+ taskStatus: string;
+ taskSketch: any[];
+ currentSketchIndex: number;
+ onSketchSelect: (index: number) => void;
+}
+
+const tabs = [
+ { id: '1', label: '脚本', icon: FileText },
+ { id: '2', label: '角色', icon: Users },
+ { id: '3', label: '分镜视频', icon: Video },
+ { id: '4', label: '背景音', icon: Music },
+ { id: '5', label: '剪辑', icon: Scissors },
+ { id: 'settings', label: '设置', icon: Settings },
+];
+
+export function EditModal({
+ isOpen,
+ onClose,
+ taskStatus,
+ taskSketch,
+ currentSketchIndex,
+ onSketchSelect
+}: EditModalProps) {
+ const [activeTab, setActiveTab] = useState('1');
+
+ const isTabDisabled = (tabId: string) => {
+ if (tabId === 'settings') return false;
+ return parseInt(tabId) > parseInt(taskStatus);
+ };
+
+ const renderTabContent = () => {
+ switch (activeTab) {
+ case '1':
+ return (
+
+ );
+ default:
+ return (
+
+ {tabs.find(tab => tab.id === activeTab)?.label} 内容区域
+
+ );
+ }
+ };
+
+ return (
+
+ {isOpen && (
+ <>
+ {/* 背景遮罩 */}
+
+
+ {/* 弹窗内容 */}
+
+
+ {/* 标签栏 */}
+
+
+ {tabs.map((tab) => {
+ const Icon = tab.icon;
+ const disabled = isTabDisabled(tab.id);
+ return (
+ !disabled && setActiveTab(tab.id)}
+ whileHover={disabled ? undefined : { scale: 1.02 }}
+ whileTap={disabled ? undefined : { scale: 0.98 }}
+ >
+
+ {tab.label}
+ {activeTab === tab.id && (
+
+ )}
+
+ );
+ })}
+
+
+ {/* 关闭按钮 */}
+
+
+
+
+
+
+
+ {/* 内容区域 */}
+
+
+
+ {renderTabContent()}
+
+
+
+
+ {/* 底部操作栏 */}
+
+
+
+ >
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/components/ui/glass-icon-button.tsx b/components/ui/glass-icon-button.tsx
new file mode 100644
index 0000000..3faeea4
--- /dev/null
+++ b/components/ui/glass-icon-button.tsx
@@ -0,0 +1,71 @@
+'use client';
+
+import React from 'react';
+import { motion } from 'framer-motion';
+import { LucideIcon } from 'lucide-react';
+import { cn } from '@/lib/utils';
+
+interface GlassIconButtonProps extends React.ButtonHTMLAttributes
{
+ icon: LucideIcon;
+ tooltip?: string;
+ variant?: 'primary' | 'secondary' | 'danger';
+ size?: 'sm' | 'md' | 'lg';
+}
+
+const variantStyles = {
+ primary: 'bg-blue-500/10 hover:bg-blue-500/20 border-blue-500/20',
+ secondary: 'bg-white/10 hover:bg-white/20 border-white/20',
+ danger: 'bg-red-500/10 hover:bg-red-500/20 border-red-500/20',
+};
+
+const sizeStyles = {
+ sm: 'p-2',
+ md: 'p-3',
+ lg: 'p-4',
+};
+
+const iconSizes = {
+ sm: 'w-4 h-4',
+ md: 'w-5 h-5',
+ lg: 'w-6 h-6',
+};
+
+export function GlassIconButton({
+ icon: Icon,
+ tooltip,
+ variant = 'secondary',
+ size = 'md',
+ className,
+ ...props
+}: GlassIconButtonProps) {
+ return (
+
+
+ {tooltip && (
+
+ {tooltip}
+
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/components/ui/script-tab-content.tsx b/components/ui/script-tab-content.tsx
new file mode 100644
index 0000000..d1bce78
--- /dev/null
+++ b/components/ui/script-tab-content.tsx
@@ -0,0 +1,202 @@
+'use client';
+
+import React, { useRef, useEffect } from 'react';
+import { motion, AnimatePresence } from 'framer-motion';
+import { Trash2, RefreshCw } from 'lucide-react';
+import { GlassIconButton } from './glass-icon-button';
+import { cn } from '@/lib/utils';
+
+interface ScriptTabContentProps {
+ taskSketch: any[];
+ currentSketchIndex: number;
+ onSketchSelect: (index: number) => void;
+}
+
+export function ScriptTabContent({
+ taskSketch = [],
+ currentSketchIndex = 0,
+ onSketchSelect
+}: ScriptTabContentProps) {
+ const thumbnailsRef = useRef(null);
+ const scriptsRef = useRef(null);
+
+ // 确保 taskSketch 是数组
+ const sketches = Array.isArray(taskSketch) ? taskSketch : [];
+
+ // 模拟脚本数据
+ const mockScripts = sketches.map((_, index) => ({
+ id: `script-${index}`,
+ content: `这是第 ${index + 1} 个分镜的脚本内容,描述了场景中的主要动作和对话。这里可以添加更多细节来丰富场景表现。`
+ }));
+
+ // 自动滚动到选中项
+ useEffect(() => {
+ if (thumbnailsRef.current && scriptsRef.current) {
+ const thumbnailContainer = thumbnailsRef.current;
+ const scriptContainer = scriptsRef.current;
+
+ // 计算缩略图滚动位置
+ const thumbnailWidth = thumbnailContainer.children[0]?.clientWidth ?? 0;
+ const thumbnailGap = 16; // gap-4 = 16px
+ const thumbnailScrollPosition = (thumbnailWidth + thumbnailGap) * currentSketchIndex;
+
+ // 计算脚本文字滚动位置
+ const scriptElement = scriptContainer.children[currentSketchIndex] as HTMLElement;
+ const scriptScrollPosition = scriptElement?.offsetLeft ?? 0;
+
+ // 平滑滚动到目标位置
+ thumbnailContainer.scrollTo({
+ left: thumbnailScrollPosition - thumbnailContainer.clientWidth / 2 + thumbnailWidth / 2,
+ behavior: 'smooth'
+ });
+
+ scriptContainer.scrollTo({
+ left: scriptScrollPosition - scriptContainer.clientWidth / 2 + scriptElement?.clientWidth / 2,
+ behavior: 'smooth'
+ });
+ }
+ }, [currentSketchIndex]);
+
+ // 如果没有数据,显示空状态
+ if (sketches.length === 0) {
+ return (
+
+ );
+ }
+
+ return (
+
+ {/* 上部分 */}
+
+ {/* 分镜缩略图行 */}
+
+
+ {sketches.map((sketch, index) => (
+
onSketchSelect(index)}
+ whileHover={{ scale: 1.05 }}
+ whileTap={{ scale: 0.95 }}
+ >
+
+
+ 场景 {index + 1}
+
+
+ ))}
+
+
+
+ {/* 脚本预览行 - 单行滚动 */}
+
+
+ {mockScripts.map((script, index) => {
+ const isActive = currentSketchIndex === index;
+ return (
+
onSketchSelect(index)}
+ initial={false}
+ animate={{
+ scale: isActive ? 1.02 : 1,
+ }}
+ >
+
+
+ {script.content}
+
+ {index < mockScripts.length - 1 && (
+ |
+ )}
+
+
+ );
+ })}
+
+
+ {/* 渐变遮罩 */}
+
+
+
+
+
+ {/* 下部分 */}
+
+ {/* 左列:脚本编辑器 */}
+
+ {}}
+ layoutId="script-editor"
+ />
+
+
+ {/* 右列:预览和操作 */}
+
+ {/* 选中的分镜预览 */}
+
+
+
+
+ {/* 操作按钮 */}
+
+
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/components/vanta-halo-background.tsx b/components/vanta-halo-background.tsx
new file mode 100644
index 0000000..ffddbbc
--- /dev/null
+++ b/components/vanta-halo-background.tsx
@@ -0,0 +1,111 @@
+// src/components/VantaHaloBackground.jsx
+'use client';
+
+import React, { useRef, useEffect, memo } from 'react'
+import dynamic from 'next/dynamic'
+import * as THREE from 'three'
+
+interface VantaHaloBackgroundProps {
+ onLoaded?: () => void;
+}
+
+// 预加载 Vanta 脚本
+const preloadVantaScript = () => {
+ const link = document.createElement('link')
+ link.rel = 'preload'
+ link.as = 'script'
+ link.href = '/lib/vanta.halo.min.js' // 确保路径正确
+ document.head.appendChild(link)
+}
+
+// 使用 React.memo 来避免不必要的重渲染
+const VantaHaloBackground = memo(({ onLoaded }: VantaHaloBackgroundProps) => {
+ const vantaRef = useRef(null)
+ const effectInstance = useRef(null)
+ const frameId = useRef()
+
+ useEffect(() => {
+ let canceled = false
+ preloadVantaScript()
+
+ const loadVanta = async () => {
+ try {
+ const VANTA = await import('../lib/vanta.halo.min.js')
+
+ if (canceled || !vantaRef.current || effectInstance.current) return
+
+ // 使用 requestAnimationFrame 来控制动画帧率
+ const animate = () => {
+ if (effectInstance.current) {
+ effectInstance.current.frameRequestId = requestAnimationFrame(animate)
+ }
+ }
+
+ effectInstance.current = VANTA.default({
+ el: vantaRef.current,
+ THREE,
+ mouseControls: true,
+ touchControls: true,
+ gyroControls: false,
+ scale: 1.0,
+ scaleMobile: 1.0,
+ amplitudeFactor: 1.5,
+ ringFactor: 1.3,
+ size: 1.2,
+ minHeight: 200.00,
+ minWidth: 200.00,
+ // 优化渲染性能的参数
+ fps: 30, // 限制帧率
+ renderCacheSize: 4, // 缓存大小
+ })
+
+ frameId.current = requestAnimationFrame(animate)
+
+ // 通知加载完成
+ if (onLoaded) {
+ onLoaded();
+ }
+ } catch (error) {
+ console.error('Failed to load Vanta effect:', error)
+ }
+ }
+
+ // 使用 requestIdleCallback 在浏览器空闲时初始化
+ if ('requestIdleCallback' in window) {
+ requestIdleCallback(() => loadVanta(), { timeout: 2000 })
+ } else {
+ setTimeout(loadVanta, 100)
+ }
+
+ return () => {
+ canceled = true
+ if (frameId.current) {
+ cancelAnimationFrame(frameId.current)
+ }
+ if (effectInstance.current) {
+ effectInstance.current.destroy()
+ effectInstance.current = null
+ }
+ }
+ }, [onLoaded])
+
+ return (
+
+ )
+})
+
+VantaHaloBackground.displayName = 'VantaHaloBackground'
+
+export default VantaHaloBackground
diff --git a/lib/vanta.halo.min.js b/lib/vanta.halo.min.js
new file mode 100644
index 0000000..baedb63
--- /dev/null
+++ b/lib/vanta.halo.min.js
@@ -0,0 +1 @@
+!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports._vantaEffect=t():e._vantaEffect=t()}("undefined"!=typeof self?self:this,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r:e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})}},t={};e.r(t),e.d(t,{default:()=>f}),Number.prototype.clamp=function(e,t){return Math.min(Math.max(this,e),t)};function i(e){for(;e.children&&e.children.length>0;)i(e.children[0]),e.remove(e.children[0]);e.geometry&&e.geometry.dispose(),e.material&&(Object.keys(e.material).forEach((t=>{e.material[t]&&null!==e.material[t]&&"function"==typeof e.material[t].dispose&&e.material[t].dispose()})),e.material.dispose())}const n="object"==typeof window;let o=n&&window.THREE||{};n&&!window.VANTA&&(window.VANTA={});const s=n&&window.VANTA||{};s.register=(e,t)=>s[e]=e=>new t(e),s.version="0.5.24";const r=function(){return Array.prototype.unshift.call(arguments,"[VANTA]"),console.error.apply(this,arguments)};s.VantaBase=class{constructor(e={}){if(!n)return!1;s.current=this,this.windowMouseMoveWrapper=this.windowMouseMoveWrapper.bind(this),this.windowTouchWrapper=this.windowTouchWrapper.bind(this),this.windowGyroWrapper=this.windowGyroWrapper.bind(this),this.resize=this.resize.bind(this),this.animationLoop=this.animationLoop.bind(this),this.restart=this.restart.bind(this);const t="function"==typeof this.getDefaultOptions?this.getDefaultOptions():this.defaultOptions;if(this.options=Object.assign({mouseControls:!0,touchControls:!0,gyroControls:!1,minHeight:200,minWidth:200,scale:1,scaleMobile:1},t),(e instanceof HTMLElement||"string"==typeof e)&&(e={el:e}),Object.assign(this.options,e),this.options.THREE&&(o=this.options.THREE),this.el=this.options.el,null==this.el)r('Instance needs "el" param!');else if(!(this.options.el instanceof HTMLElement)){const e=this.el;if(this.el=(i=e,document.querySelector(i)),!this.el)return void r("Cannot find element",e)}var i,a;this.prepareEl(),this.initThree(),this.setSize();try{this.init()}catch(e){return r("Init error",e),this.renderer&&this.renderer.domElement&&this.el.removeChild(this.renderer.domElement),void(this.options.backgroundColor&&(console.log("[VANTA] Falling back to backgroundColor"),this.el.style.background=(a=this.options.backgroundColor,"number"==typeof a?"#"+("00000"+a.toString(16)).slice(-6):a)))}this.initMouse(),this.resize(),this.animationLoop();const c=window.addEventListener;c("resize",this.resize),window.requestAnimationFrame(this.resize),this.options.mouseControls&&(c("scroll",this.windowMouseMoveWrapper),c("mousemove",this.windowMouseMoveWrapper)),this.options.touchControls&&(c("touchstart",this.windowTouchWrapper),c("touchmove",this.windowTouchWrapper)),this.options.gyroControls&&c("deviceorientation",this.windowGyroWrapper)}setOptions(e={}){Object.assign(this.options,e),this.triggerMouseMove()}prepareEl(){let e,t;if("undefined"!=typeof Node&&Node.TEXT_NODE)for(e=0;e=0&&n>=0&&i<=t.width&&n<=t.height&&(this.mouseX=i,this.mouseY=n,this.options.mouseEase||this.triggerMouseMove(i,n))}windowTouchWrapper(e){const t=this.getCanvasRect();if(!t)return!1;if(1===e.touches.length){const i=e.touches[0].clientX-t.left,n=e.touches[0].clientY-t.top;i>=0&&n>=0&&i<=t.width&&n<=t.height&&(this.mouseX=i,this.mouseY=n,this.options.mouseEase||this.triggerMouseMove(i,n))}}windowGyroWrapper(e){const t=this.getCanvasRect();if(!t)return!1;const i=Math.round(2*e.alpha)-t.left,n=Math.round(2*e.beta)-t.top;i>=0&&n>=0&&i<=t.width&&n<=t.height&&(this.mouseX=i,this.mouseY=n,this.options.mouseEase||this.triggerMouseMove(i,n))}triggerMouseMove(e,t){void 0===e&&void 0===t&&(this.options.mouseEase?(e=this.mouseEaseX,t=this.mouseEaseY):(e=this.mouseX,t=this.mouseY)),this.uniforms&&(this.uniforms.iMouse.value.x=e/this.scale,this.uniforms.iMouse.value.y=t/this.scale);const i=e/this.width,n=t/this.height;"function"==typeof this.onMouseMove&&this.onMouseMove(i,n)}setSize(){this.scale||(this.scale=1),"undefined"!=typeof navigator&&(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)||window.innerWidth<600)&&this.options.scaleMobile?this.scale=this.options.scaleMobile:this.options.scale&&(this.scale=this.options.scale),this.width=Math.max(this.el.offsetWidth,this.options.minWidth),this.height=Math.max(this.el.offsetHeight,this.options.minHeight)}initMouse(){(!this.mouseX&&!this.mouseY||this.mouseX===this.options.minWidth/2&&this.mouseY===this.options.minHeight/2)&&(this.mouseX=this.width/2,this.mouseY=this.height/2,this.triggerMouseMove(this.mouseX,this.mouseY))}resize(){this.setSize(),this.camera&&(this.camera.aspect=this.width/this.height,"function"==typeof this.camera.updateProjectionMatrix&&this.camera.updateProjectionMatrix()),this.renderer&&(this.renderer.setSize(this.width,this.height),this.renderer.setPixelRatio(window.devicePixelRatio/this.scale)),"function"==typeof this.onResize&&this.onResize()}isOnScreen(){const e=this.el.offsetHeight,t=this.el.getBoundingClientRect(),i=window.pageYOffset||(document.documentElement||document.body.parentNode||document.body).scrollTop,n=t.top+i;return n-window.innerHeight<=i&&i<=n+e}animationLoop(){this.t||(this.t=0),this.t2||(this.t2=0);const e=performance.now();if(this.prevNow){let t=(e-this.prevNow)/(1e3/60);t=Math.max(.2,Math.min(t,5)),this.t+=t,this.t2+=(this.options.speed||1)*t,this.uniforms&&(this.uniforms.iTime.value=.016667*this.t2)}return this.prevNow=e,this.options.mouseEase&&(this.mouseEaseX=this.mouseEaseX||this.mouseX||0,this.mouseEaseY=this.mouseEaseY||this.mouseY||0,Math.abs(this.mouseEaseX-this.mouseX)+Math.abs(this.mouseEaseY-this.mouseY)>.1&&(this.mouseEaseX+=.05*(this.mouseX-this.mouseEaseX),this.mouseEaseY+=.05*(this.mouseY-this.mouseEaseY),this.triggerMouseMove(this.mouseEaseX,this.mouseEaseY))),(this.isOnScreen()||this.options.forceAnimate)&&("function"==typeof this.onUpdate&&this.onUpdate(),this.scene&&this.camera&&(this.renderer.render(this.scene,this.camera),this.renderer.setClearColor(this.options.backgroundColor,this.options.backgroundAlpha)),this.fps&&this.fps.update&&this.fps.update(),"function"==typeof this.afterRender&&this.afterRender()),this.req=window.requestAnimationFrame(this.animationLoop)}restart(){if(this.scene)for(;this.scene.children.length;)this.scene.remove(this.scene.children[0]);"function"==typeof this.onRestart&&this.onRestart(),this.init()}init(){"function"==typeof this.onInit&&this.onInit()}destroy(){"function"==typeof this.onDestroy&&this.onDestroy();const e=window.removeEventListener;e("touchstart",this.windowTouchWrapper),e("touchmove",this.windowTouchWrapper),e("scroll",this.windowMouseMoveWrapper),e("mousemove",this.windowMouseMoveWrapper),e("deviceorientation",this.windowGyroWrapper),e("resize",this.resize),window.cancelAnimationFrame(this.req);const t=this.scene;t&&t.children&&i(t),this.renderer&&(this.renderer.domElement&&this.el.removeChild(this.renderer.domElement),this.renderer=null,this.scene=null),s.current===this&&(s.current=null)}};const a=s.VantaBase;let c="object"==typeof window&&window.THREE;class h extends a{constructor(e){c=e.THREE||c,c.Color.prototype.toVector=function(){return new c.Vector3(this.r,this.g,this.b)},super(e),this.updateUniforms=this.updateUniforms.bind(this)}init(){this.mode="shader",this.uniforms={iTime:{type:"f",value:1},iResolution:{type:"v2",value:new c.Vector2(1,1)},iDpr:{type:"f",value:window.devicePixelRatio||1},iMouse:{type:"v2",value:new c.Vector2(this.mouseX||0,this.mouseY||0)}},super.init(),this.fragmentShader&&this.initBasicShader()}setOptions(e){super.setOptions(e),this.updateUniforms()}initBasicShader(e=this.fragmentShader,t=this.vertexShader){t||(t="uniform float uTime;\nuniform vec2 uResolution;\nvoid main() {\n gl_Position = vec4( position, 1.0 );\n}"),this.updateUniforms(),"function"==typeof this.valuesChanger&&this.valuesChanger();const i=new c.ShaderMaterial({uniforms:this.uniforms,vertexShader:t,fragmentShader:e}),n=this.options.texturePath;n&&(this.uniforms.iTex={type:"t",value:(new c.TextureLoader).load(n)});const o=new c.Mesh(new c.PlaneGeometry(2,2),i);this.scene.add(o),this.camera=new c.Camera,this.camera.position.z=1}updateUniforms(){const e={};let t,i;for(t in this.options)i=this.options[t],-1!==t.toLowerCase().indexOf("color")?e[t]={type:"v3",value:new c.Color(i).toVector()}:"number"==typeof i&&(e[t]={type:"f",value:i});return Object.assign(this.uniforms,e)}resize(){super.resize(),this.uniforms.iResolution.value.x=this.width/this.scale,this.uniforms.iResolution.value.y=this.height/this.scale}}let l="object"==typeof window&&window.THREE;class u extends h{constructor(e){l=e.THREE||l,super(e)}getDefaultOptions(){return{baseColor:6745,color2:15918901,backgroundColor:1251907,amplitudeFactor:1,ringFactor:1,rotationFactor:1,xOffset:0,yOffset:0,size:1,speed:1,mouseEase:!0,scaleMobile:1,scale:1}}onInit(){const e={minFilter:l.LinearFilter,magFilter:l.LinearFilter,format:l.RGBFormat},t=this.width*window.devicePixelRatio/this.scale,i=this.height*window.devicePixelRatio/this.scale;this.bufferTarget=new l.WebGLRenderTarget(t,i,e),this.bufferFeedback=new l.WebGLRenderTarget(t,i,e)}initBasicShader(e,t){super.initBasicShader(e,t),this.uniforms.iBuffer={type:"t",value:this.bufferTarget.texture}}onUpdate(){this.uniforms.iBuffer.value=this.bufferFeedback.texture;const e=this.renderer;e.setRenderTarget(this.bufferTarget),e.render(this.scene,this.camera),e.setRenderTarget(null),e.clear();let t=this.bufferTarget;this.bufferTarget=this.bufferFeedback,this.bufferFeedback=t}onResize(){if(this.bufferTarget){const e=this.width*window.devicePixelRatio/this.scale,t=this.height*window.devicePixelRatio/this.scale;this.bufferTarget.setSize(e,t),this.bufferFeedback.setSize(e,t)}}onDestroy(){this.bufferTarget=null,this.bufferFeedback=null}}const f=s.register("HALO",u);return u.prototype.fragmentShader="uniform vec2 iResolution;\nuniform float iDpr;\nuniform vec2 iMouse;\nuniform float iTime;\n\nuniform float xOffset;\nuniform float yOffset;\nuniform vec3 baseColor;\nuniform vec3 color2;\nuniform vec3 backgroundColor;\nuniform float size;\nuniform float shape;\nuniform float ringFactor;\nuniform float rotationFactor;\nuniform float amplitudeFactor;\n\nuniform sampler2D iBuffer;\nuniform sampler2D iTex;\nconst float PI = 3.14159265359;\n\n// float length2(vec2 p) { return dot(p, p); }\n\n// float noise(vec2 p){\n// return fract(sin(fract(sin(p.x) * (43.13311)) + p.y) * 31.0011);\n// }\n\n// float worley(vec2 p) {\n// float d = 1e30;\n// for (int xo = -1; xo <= 1; ++xo) {\n// for (int yo = -1; yo <= 1; ++yo) {\n// vec2 tp = floor(p) + vec2(xo, yo);\n// d = min(d, length2(p - tp - vec2(noise(tp))));\n// }\n// }\n// vec2 uv = gl_FragCoord.xy / iResolution.xy;\n// float timeOffset = 0.15 * sin(iTime * 2.0 + 10.0*(uv.x - uv.y));\n// return 3.0*exp(-4.0*abs(2.0*d - 1.0 + timeOffset));\n// }\n\n// float fworley(vec2 p) {\n// return sqrt(\n// 1.1 * // light\n// worley(p*10. + .3 + iTime*.0525) *\n// sqrt(worley(p * 50. / size + 0.1 + iTime * -0.75)) *\n// 4.1 *\n// sqrt(sqrt(worley(p * -1. + 9.3))));\n// }\n\nvec4 j2hue(float c) {\n return .5+.5*cos(6.28*c+vec4(0,-2.1,2.1,0));\n}\n\nvec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }\n\nfloat snoise(vec2 v){\n const vec4 C = vec4(0.211324865405187, 0.366025403784439,\n -0.577350269189626, 0.024390243902439);\n vec2 i = floor(v + dot(v, C.yy) );\n vec2 x0 = v - i + dot(i, C.xx);\n vec2 i1;\n i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);\n vec4 x12 = x0.xyxy + C.xxzz;\n x12.xy -= i1;\n i = mod(i, 289.0);\n vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 ))\n + i.x + vec3(0.0, i1.x, 1.0 ));\n vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy),\n dot(x12.zw,x12.zw)), 0.0);\n m = m*m ;\n m = m*m ;\n vec3 x = 2.0 * fract(p * C.www) - 1.0;\n vec3 h = abs(x) - 0.5;\n vec3 ox = floor(x + 0.5);\n vec3 a0 = x - ox;\n m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );\n vec3 g;\n g.x = a0.x * x0.x + h.x * x0.y;\n g.yz = a0.yz * x12.xz + h.yz * x12.yw;\n return 130.0 * dot(m, g);\n}\n\nvec2 sincos( float x ){return vec2(sin(x), cos(x));}\nvec2 rotate2d(vec2 uv, float phi){vec2 t = sincos(phi); return vec2(uv.x*t.y-uv.y*t.x, uv.x*t.x+uv.y*t.y);}\nvec3 rotate3d(vec3 p, vec3 v, float phi){ v = normalize(v); vec2 t = sincos(-phi); float s = t.x, c = t.y, x =-v.x, y =-v.y, z =-v.z; mat4 M = mat4(x*x*(1.-c)+c,x*y*(1.-c)-z*s,x*z*(1.-c)+y*s,0.,y*x*(1.-c)+z*s,y*y*(1.-c)+c,y*z*(1.-c)-x*s,0.,z*x*(1.-c)-y*s,z*y*(1.-c)+x*s,z*z*(1.-c)+c,0.,0.,0.,0.,1.);return (vec4(p,1.)*M).xyz;}\n\n// Classic Perlin 3D Noise\n// by Stefan Gustavson\nvec4 permute(vec4 x){return mod(((x*34.0)+1.0)*x, 289.0);}\nvec4 taylorInvSqrt(vec4 r){return 1.79284291400159 - 0.85373472095314 * r;}\nvec3 fade(vec3 t) {return t*t*t*(t*(t*6.0-15.0)+10.0);}\nfloat p3d(vec3 P){\n vec3 Pi0 = floor(P); // Integer part for indexing\n vec3 Pi1 = Pi0 + vec3(1.0); // Integer part + 1\n Pi0 = mod(Pi0, 289.0);\n Pi1 = mod(Pi1, 289.0);\n vec3 Pf0 = fract(P); // Fractional part for interpolation\n vec3 Pf1 = Pf0 - vec3(1.0); // Fractional part - 1.0\n vec4 ix = vec4(Pi0.x, Pi1.x, Pi0.x, Pi1.x);\n vec4 iy = vec4(Pi0.yy, Pi1.yy);\n vec4 iz0 = Pi0.zzzz;\n vec4 iz1 = Pi1.zzzz;\n\n vec4 ixy = permute(permute(ix) + iy);\n vec4 ixy0 = permute(ixy + iz0);\n vec4 ixy1 = permute(ixy + iz1);\n\n vec4 gx0 = ixy0 / 7.0;\n vec4 gy0 = fract(floor(gx0) / 7.0) - 0.5;\n gx0 = fract(gx0);\n vec4 gz0 = vec4(0.5) - abs(gx0) - abs(gy0);\n vec4 sz0 = step(gz0, vec4(0.0));\n gx0 -= sz0 * (step(0.0, gx0) - 0.5);\n gy0 -= sz0 * (step(0.0, gy0) - 0.5);\n\n vec4 gx1 = ixy1 / 7.0;\n vec4 gy1 = fract(floor(gx1) / 7.0) - 0.5;\n gx1 = fract(gx1);\n vec4 gz1 = vec4(0.5) - abs(gx1) - abs(gy1);\n vec4 sz1 = step(gz1, vec4(0.0));\n gx1 -= sz1 * (step(0.0, gx1) - 0.5);\n gy1 -= sz1 * (step(0.0, gy1) - 0.5);\n\n vec3 g000 = vec3(gx0.x,gy0.x,gz0.x);\n vec3 g100 = vec3(gx0.y,gy0.y,gz0.y);\n vec3 g010 = vec3(gx0.z,gy0.z,gz0.z);\n vec3 g110 = vec3(gx0.w,gy0.w,gz0.w);\n vec3 g001 = vec3(gx1.x,gy1.x,gz1.x);\n vec3 g101 = vec3(gx1.y,gy1.y,gz1.y);\n vec3 g011 = vec3(gx1.z,gy1.z,gz1.z);\n vec3 g111 = vec3(gx1.w,gy1.w,gz1.w);\n\n vec4 norm0 = taylorInvSqrt(vec4(dot(g000, g000), dot(g010, g010), dot(g100, g100), dot(g110, g110)));\n g000 *= norm0.x;\n g010 *= norm0.y;\n g100 *= norm0.z;\n g110 *= norm0.w;\n vec4 norm1 = taylorInvSqrt(vec4(dot(g001, g001), dot(g011, g011), dot(g101, g101), dot(g111, g111)));\n g001 *= norm1.x;\n g011 *= norm1.y;\n g101 *= norm1.z;\n g111 *= norm1.w;\n\n float n000 = dot(g000, Pf0);\n float n100 = dot(g100, vec3(Pf1.x, Pf0.yz));\n float n010 = dot(g010, vec3(Pf0.x, Pf1.y, Pf0.z));\n float n110 = dot(g110, vec3(Pf1.xy, Pf0.z));\n float n001 = dot(g001, vec3(Pf0.xy, Pf1.z));\n float n101 = dot(g101, vec3(Pf1.x, Pf0.y, Pf1.z));\n float n011 = dot(g011, vec3(Pf0.x, Pf1.yz));\n float n111 = dot(g111, Pf1);\n\n vec3 fade_xyz = fade(Pf0);\n vec4 n_z = mix(vec4(n000, n100, n010, n110), vec4(n001, n101, n011, n111), fade_xyz.z);\n vec2 n_yz = mix(n_z.xy, n_z.zw, fade_xyz.y);\n float n_xyz = mix(n_yz.x, n_yz.y, fade_xyz.x);\n return 2.2 * n_xyz;\n}\n\n\nvoid main() {\n vec2 res2 = iResolution.xy * iDpr;\n vec2 pixel = vec2(gl_FragCoord.xy - 0.5 * res2) / res2.y; // center-origin pixel coord\n pixel.x -= xOffset * res2.x / res2.y;\n pixel.y -= yOffset;\n\n vec2 uv = gl_FragCoord.xy / res2; // 0 to 1\n\n // float nn1 = snoise(uv * 0.25 + iTime * 0.005 + mixedColor.b * 0.01) * 0.1;\n // float nn2 = snoise(uv * 0.25 + iTime * 0.005 + mixedColor.b * 0.01 + 1000.) * 0.1;\n // uv += vec2(nn1, nn2);\n\n // PERLIN DISTORTION\n // float noiseScale = 10.;\n // float timeScale = 0.5;\n // uv += vec2( p3d(vec3(uv * noiseScale, iTime * timeScale)), p3d(vec3(1000. + uv * noiseScale , iTime * timeScale)) ) * 0.001;\n\n // uv = rotate2d(uv, 0.001);\n // pixel = rotate2d(pixel, 0.001);\n\n vec2 mouse2 = (iMouse * iDpr / res2 - 0.5) * vec2(1.,-1.);\n vec2 uvBig = (uv - 0.5) * 0.996 + 0.5;\n\n vec4 oldImage = texture2D(iBuffer, uv);\n vec3 mixedColor = oldImage.rgb - backgroundColor;\n\n // float spinDist = 0.002 + 0.002 * sin(iTime * 0.4);\n float cropDist = 0.01;\n float cropXOffset = 0.2;\n float cropYOffset = 0.2;\n // float cropXOffset = 0.4 + 0.1 * sin(iTime * 0.4);\n // float cropYOffset = 0.4 + 0.1 * cos(iTime * 0.6);\n\n vec2 offset = uv + vec2((mixedColor.g - cropXOffset) * cropDist, (mixedColor.r - cropYOffset) * cropDist);\n\n // float nn = snoise(uv * 10.) * 0.001;\n // offset += nn;\n\n float spinDist = 0.001;\n float spinSpeed = 0.2 + 0.15 * cos(iTime * 0.5);\n float timeFrac = mod(iTime, 6.5);\n vec2 offset2 = uvBig + vec2(cos(timeFrac * spinSpeed) * spinDist, sin(timeFrac * spinSpeed) * spinDist);\n\n mixedColor = texture2D(iBuffer, offset).rgb * 0.4\n + texture2D(iBuffer, offset2).rgb * 0.6\n - backgroundColor;\n\n\n // mixedColor *= .875;\n float fadeAmt = 0.0015; // fade this amount each frame // 0.002\n mixedColor = (mixedColor - fadeAmt) * .995;\n\n // float nn = snoise(uvBig * 10.) * 20.;\n // mixedColor *= clamp(nn, 0.98, 1.0);\n\n vec4 spectrum = abs( abs( .95*atan(uv.x, uv.y) -vec4(0,2,4,0) ) -3. )-1.;\n float angle = atan(pixel.x, pixel.y);\n float dist = length(pixel - mouse2*0.15) * 8. + sin(iTime) * .01;\n\n // mixedColor *= pow(1.-dist*0.002, 2.);\n\n\n // Flowery shapes\n // float edge = abs(dist * 0.5);\n float flowerPeaks = .05 * amplitudeFactor * size;\n float flowerPetals = 7.;\n float edge = abs((dist + sin(angle * flowerPetals + iTime * 0.5) * sin(iTime * 1.5) * flowerPeaks) * 0.65 / size);\n // float edge = abs((dist + sin(angle * 4. + iTime * 2.) * sin(iTime * 3.) * 0.75) * 1.);\n\n // vec4 rainbow = abs( abs( .95*mod(iTime * 1., 2. * PI) - vec4(0,2,4,0) ) -3. )-1.;\n // vec4 rainbow = vec4(0,2,4,0);\n\n float colorChangeSpeed = 0.75 + 0.05 * sin(iTime) * 1.5;\n float rainbowInput = timeFrac * colorChangeSpeed;\n // NOISE!\n // float nn = snoise(uv * 0.25 + iTime * 0.005 + mixedColor.b * 0.01) * 20.;\n // rainbowInput += nn;\n\n float brightness = 0.7;\n vec4 rainbow = sqrt(j2hue(cos(rainbowInput))) + vec4(baseColor,0) - 1.0 + brightness;\n float factor = smoothstep(1., .9, edge) * pow(edge, 2.);\n vec3 color = rainbow.rgb * smoothstep(1., .9, edge) * pow(edge, 20.);\n vec4 ring = vec4(\n backgroundColor + clamp( mixedColor + color, 0., 1.)\n , 1.0);\n\n // float t = fworley(uv * u_resolution.xy / 1500.0);\n // t *= exp(-length2(abs(0.7*uv - 1.0)));\n // float tExp = pow(t, 2. - t);\n // vec3 c1 = color1 * (1.0 - t);\n // vec3 c2 = color2 * tExp;\n // vec4 cells = vec4(mixedColor * 0.25, 1.) + vec4(pow(t, 1.0 - t) * (c1 + c2), 1.0);\n // gl_FragColor = clamp(ring + cells * 0.5, 0.0, 1.0);\n\n // float nn = snoise(uv * 10.) * 0.01; // creepy!\n gl_FragColor = ring;\n}\n",t})()));
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 6d94201..2ed405e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -44,6 +44,7 @@
"@types/react": "18.2.22",
"@types/react-beautiful-dnd": "^13.1.8",
"@types/react-dom": "18.2.7",
+ "@types/three": "^0.177.0",
"antd": "^5.26.2",
"autoprefixer": "10.4.15",
"class-variance-authority": "^0.7.0",
@@ -67,20 +68,24 @@
"react-dom": "18.2.0",
"react-grid-layout": "^1.5.1",
"react-hook-form": "^7.53.0",
+ "react-intersection-observer": "^9.16.0",
"react-resizable": "^3.0.5",
"react-resizable-panels": "^2.1.3",
"react-textarea-autosize": "^8.5.9",
"recharts": "^2.12.7",
"sonner": "^1.5.0",
+ "styled-components": "^6.1.19",
"swiper": "^11.2.8",
"tailwind-merge": "^2.5.2",
"tailwindcss": "3.3.3",
"tailwindcss-animate": "^1.0.7",
+ "three": "^0.177.0",
"typescript": "5.2.2",
"vaul": "^0.9.9",
"zod": "^3.23.8"
},
"devDependencies": {
+ "@types/lodash": "^4.17.19",
"@types/react-grid-layout": "^1.3.5"
}
},
@@ -201,6 +206,12 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@dimforge/rapier3d-compat": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmmirror.com/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz",
+ "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==",
+ "license": "Apache-2.0"
+ },
"node_modules/@dnd-kit/accessibility": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
@@ -260,6 +271,21 @@
"integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==",
"license": "MIT"
},
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmmirror.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
+ "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/memoize": "^0.8.1"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmmirror.com/@emotion/memoize/-/memoize-0.8.1.tgz",
+ "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==",
+ "license": "MIT"
+ },
"node_modules/@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.7.5.tgz",
@@ -2178,6 +2204,12 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@tweenjs/tween.js": {
+ "version": "23.1.3",
+ "resolved": "https://registry.npmmirror.com/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
+ "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
+ "license": "MIT"
+ },
"node_modules/@types/d3-array": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
@@ -2247,6 +2279,13 @@
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
},
+ "node_modules/@types/lodash": {
+ "version": "4.17.19",
+ "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.19.tgz",
+ "integrity": "sha512-NYqRyg/hIQrYPT9lbOeYc3kIRabJDn/k4qQHIXUpx88CBDww2fD15Sg5kbXlW86zm2XEW4g0QxkTI3/Kfkc7xQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "20.6.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.6.2.tgz",
@@ -2311,6 +2350,39 @@
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.23.0.tgz",
"integrity": "sha512-YIoDCTH3Af6XM5VuwGG/QL/CJqga1Zm3NkU3HZ4ZHK2fRMPYP1VczsTUqtsf43PH/iJNVlPHAo2oWX7BSdB2Hw=="
},
+ "node_modules/@types/stats.js": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmmirror.com/@types/stats.js/-/stats.js-0.17.4.tgz",
+ "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/stylis": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmmirror.com/@types/stylis/-/stylis-4.2.5.tgz",
+ "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/three": {
+ "version": "0.177.0",
+ "resolved": "https://registry.npmmirror.com/@types/three/-/three-0.177.0.tgz",
+ "integrity": "sha512-/ZAkn4OLUijKQySNci47lFO+4JLE1TihEjsGWPUT+4jWqxtwOPPEwJV1C3k5MEx0mcBPCdkFjzRzDOnHEI1R+A==",
+ "license": "MIT",
+ "dependencies": {
+ "@dimforge/rapier3d-compat": "~0.12.0",
+ "@tweenjs/tween.js": "~23.1.3",
+ "@types/stats.js": "*",
+ "@types/webxr": "*",
+ "@webgpu/types": "*",
+ "fflate": "~0.8.2",
+ "meshoptimizer": "~0.18.1"
+ }
+ },
+ "node_modules/@types/webxr": {
+ "version": "0.5.22",
+ "resolved": "https://registry.npmmirror.com/@types/webxr/-/webxr-0.5.22.tgz",
+ "integrity": "sha512-Vr6Stjv5jPRqH690f5I5GLjVk8GSsoQSYJ2FVd/3jJF7KaqfwPi3ehfBS96mlQ2kPCwZaX6U0rG2+NGHBKkA/A==",
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/parser": {
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
@@ -2431,6 +2503,12 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@webgpu/types": {
+ "version": "0.1.63",
+ "resolved": "https://registry.npmmirror.com/@webgpu/types/-/types-0.1.63.tgz",
+ "integrity": "sha512-s9Kuh0nE/2+nKrvmKNMB2fE5Zlr3DL2t3OFKM55v5jRcfCOxbkOHhQoshoFum5mmXIfEtRXtLCWmkeTJsVjE9w==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/acorn": {
"version": "8.12.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz",
@@ -2931,6 +3009,15 @@
"node": ">= 6"
}
},
+ "node_modules/camelize": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/camelize/-/camelize-1.0.1.tgz",
+ "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/caniuse-lite": {
"version": "1.0.30001667",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz",
@@ -3463,6 +3550,26 @@
"tiny-invariant": "^1.0.6"
}
},
+ "node_modules/css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/css-to-react-native": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
+ "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
+ "license": "MIT",
+ "dependencies": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@@ -4495,6 +4602,12 @@
"reusify": "^1.0.4"
}
},
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmmirror.com/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "license": "MIT"
+ },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -5577,6 +5690,12 @@
"node": ">= 8"
}
},
+ "node_modules/meshoptimizer": {
+ "version": "0.18.1",
+ "resolved": "https://registry.npmmirror.com/meshoptimizer/-/meshoptimizer-0.18.1.tgz",
+ "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==",
+ "license": "MIT"
+ },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -6048,9 +6167,10 @@
}
},
"node_modules/picocolors": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
- "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -7015,6 +7135,21 @@
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
+ "node_modules/react-intersection-observer": {
+ "version": "9.16.0",
+ "resolved": "https://registry.npmmirror.com/react-intersection-observer/-/react-intersection-observer-9.16.0.tgz",
+ "integrity": "sha512-w9nJSEp+DrW9KmQmeWHQyfaP6b03v+TdXynaoA964Wxt7mdR3An11z4NNCQgL4gKSK7y1ver2Fq+JKH6CWEzUA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -7456,6 +7591,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "license": "MIT"
+ },
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -7744,6 +7885,80 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/styled-components": {
+ "version": "6.1.19",
+ "resolved": "https://registry.npmmirror.com/styled-components/-/styled-components-6.1.19.tgz",
+ "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==",
+ "license": "MIT",
+ "dependencies": {
+ "@emotion/is-prop-valid": "1.2.2",
+ "@emotion/unitless": "0.8.1",
+ "@types/stylis": "4.2.5",
+ "css-to-react-native": "3.2.0",
+ "csstype": "3.1.3",
+ "postcss": "8.4.49",
+ "shallowequal": "1.1.0",
+ "stylis": "4.3.2",
+ "tslib": "2.6.2"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/styled-components"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0",
+ "react-dom": ">= 16.8.0"
+ }
+ },
+ "node_modules/styled-components/node_modules/@emotion/unitless": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz",
+ "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
+ "license": "MIT"
+ },
+ "node_modules/styled-components/node_modules/postcss": {
+ "version": "8.4.49",
+ "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz",
+ "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/styled-components/node_modules/stylis": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.3.2.tgz",
+ "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==",
+ "license": "MIT"
+ },
+ "node_modules/styled-components/node_modules/tslib": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
+ "license": "0BSD"
+ },
"node_modules/styled-jsx": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz",
@@ -7960,6 +8175,12 @@
"node": ">=0.8"
}
},
+ "node_modules/three": {
+ "version": "0.177.0",
+ "resolved": "https://registry.npmmirror.com/three/-/three-0.177.0.tgz",
+ "integrity": "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg==",
+ "license": "MIT"
+ },
"node_modules/throttle-debounce": {
"version": "5.0.2",
"resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
diff --git a/package.json b/package.json
index 6296263..d1b376a 100644
--- a/package.json
+++ b/package.json
@@ -45,6 +45,7 @@
"@types/react": "18.2.22",
"@types/react-beautiful-dnd": "^13.1.8",
"@types/react-dom": "18.2.7",
+ "@types/three": "^0.177.0",
"antd": "^5.26.2",
"autoprefixer": "10.4.15",
"class-variance-authority": "^0.7.0",
@@ -68,20 +69,24 @@
"react-dom": "18.2.0",
"react-grid-layout": "^1.5.1",
"react-hook-form": "^7.53.0",
+ "react-intersection-observer": "^9.16.0",
"react-resizable": "^3.0.5",
"react-resizable-panels": "^2.1.3",
"react-textarea-autosize": "^8.5.9",
"recharts": "^2.12.7",
"sonner": "^1.5.0",
+ "styled-components": "^6.1.19",
"swiper": "^11.2.8",
"tailwind-merge": "^2.5.2",
"tailwindcss": "3.3.3",
"tailwindcss-animate": "^1.0.7",
+ "three": "^0.177.0",
"typescript": "5.2.2",
"vaul": "^0.9.9",
"zod": "^3.23.8"
},
"devDependencies": {
+ "@types/lodash": "^4.17.19",
"@types/react-grid-layout": "^1.3.5"
}
}
diff --git a/public/assets/3dr_chihiro.png b/public/assets/3dr_chihiro.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2993facd15846656abd49d88495a6447d707872
GIT binary patch
literal 12943
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
FV1muQIrRVl
literal 0
HcmV?d00001
diff --git a/public/assets/3dr_howlbg.jpg b/public/assets/3dr_howlbg.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..fc8c7fef485e5cb39e8deda97674098afa27cd73
GIT binary patch
literal 5456
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