main
reng 1 month ago
parent 32ceb9c4c6
commit 93d6ea9f6b
  1. 20
      package-lock.json
  2. 1
      package.json
  3. 158
      public/data.json
  4. 7
      src/App.jsx
  5. 1
      src/assets/lottie/Grayscale_landing.json
  6. 1
      src/assets/lottie/circle.json
  7. 1
      src/assets/lottie/egg_bg.json
  8. 1
      src/assets/lottie/hint.json
  9. 2
      src/comps/canvas.jsx
  10. 9
      src/index.css
  11. 13
      src/pages/explore.jsx
  12. 39
      src/pages/keywords.jsx

20
package-lock.json generated

@ -9,6 +9,7 @@
"version": "0.0.0",
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"lottie-react": "^2.4.1",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-router-dom": "^7.13.0",
@ -2831,6 +2832,25 @@
"dev": true,
"license": "MIT"
},
"node_modules/lottie-react": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/lottie-react/-/lottie-react-2.4.1.tgz",
"integrity": "sha512-LQrH7jlkigIIv++wIyrOYFLHSKQpEY4zehPicL9bQsrt1rnoKRYCYgpCUe5maqylNtacy58/sQDZTkwMcTRxZw==",
"license": "MIT",
"dependencies": {
"lottie-web": "^5.10.2"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/lottie-web": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.13.0.tgz",
"integrity": "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ==",
"license": "MIT"
},
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",

@ -11,6 +11,7 @@
},
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"lottie-react": "^2.4.1",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-router-dom": "^7.13.0",

@ -50,270 +50,186 @@
"keywords": {
"en": [
{
"id":1,
"title": "Overworked",
"content": "How much of your schedule is actually for yourself?"
},
{
"id":2,
"title": "Internal Burnout",
"content": "Do you spend a lot of energy just managing your own emotions?"
},
{
"id":3,
"title": "Student Loans",
"content": "How many years will it take to pay off that diploma?"
},
{
"id":4,
"title": "Renting",
"content": "What slice of your paycheck goes straight to the landlord?"
},
{
"title": "Debt",
"content": "Do you feel like you owe anyone \"time\" or \"favors\"?"
},
{
"id":5,
"title": "Adulthood",
"content": "What’s the gap between your legal age and how old you actually feel?"
},
{
"title": "Survival",
"content": "Are you living right now, or just surviving?"
},
{
"id":6,
"title": "Discipline",
"content": "Which social habits were you born with, and which did you learn to fit in?"
},
{
"id":7,
"title": "PUA",
"content": "Is the self-doubt coming from the task, or someone else’s judgment?"
},
{
"title": "Consumable",
"content": "If you took tomorrow off, would the system really stop?"
},
{
"title": "Servility",
"content": "What’s your gut reaction to an unreasonable order?"
},
{
"id":8,
"title": "Unwritten Rules",
"content": "Which unspoken rules are you quietly following?"
},
{
"id":9,
"title": "Corporate Slave",
"content": "How do you tell the \"work you\" apart from the \"real you\"?"
},
{
"title": "Curfew",
"content": "When is your most comfortable time to be home?"
},
{
"id":10,
"title": "Boundaries",
"content": "When do you say \"no\" just to protect yourself?"
},
{
"id":11,
"title": "Surveillance",
"content": "Would you act differently if you knew no one was watching?"
},
{
"title": "Inside the Wall",
"content": "Does your environment feel like a shield or a cage?"
},
{
"title": "Constriction",
"content": "What’s the biggest change you made just to adapt?"
},
{
"id":12,
"title": "Freedom",
"content": "What does \"freedom\" actually look like to you?"
},
{
"id":13,
"title": "Awakening",
"content": "Do you accept your \"factory settings\"?"
},
{
"id":14,
"title": "Lying Flat",
"content": "Are you resting to go further, or because the road has ended?"
},
{
"title": "Fighting Back",
"content": "When was the last time you spoke up or said \"no\"?"
},
{
"id":15,
"title": "Subjectivity",
"content": "Do you usually speak up, or just go with the flow?"
},
{
"title": "Undefined",
"content": "Describe yourself in three words without using your job title."
},
{
"id":16,
"title": "Being Yourself",
"content": "How much of your true self do you show in public?"
},
{
"title": "Finding Gaps",
"content": "How do you find a little breathing room in your busy life?"
},
{
"title": "Suffocating",
"content": "Which topics or places make you feel like you can't breathe?"
},
{
"id":17,
"title": "Who Gets It",
"content": "Who in your life truly understands what you’re going through?"
},
{
"id":18,
"title": "Anxiety",
"content": "Are you worried about the future, or stuck in the past?"
},
{
"title": "World-weary",
"content": "Is this feeling just pure fatigue from the way things are?"
},
{
"title": "Irony",
"content": "Have the rules you once hated become your survival instincts?"
},
{
"title": "Empathy",
"content": "Which words in this device said what you couldn't say out loud?"
},
{
"title": "Illusion",
"content": "Are your goals truly yours, or just what society wants for you?"
}
],
"zh": [
{
"id":1,
"title": "窮忙",
"content": "你今天的行程裡,有多少比例是為了自己?"
},
{
"id":2,
"title": "內耗",
"content": "你會花很多力氣處理自己的情緒嗎?"
},
{
"id":3,
"title": "學貸",
"content": "一張畢業證書要花多少年來分期付款?"
},
{
"id":4,
"title": "租屋",
"content": "這個月薪水的幾分之幾交給房東了?"
},
{
"title": "負債",
"content": "你覺得自己現在有欠下「時間」或「人情」嗎?"
},
{
"id":5,
"title": "成年",
"content": "法律定義的成年與你心理感受的成年,中間的距離有多少?"
},
{
"title": "求生存",
"content": "你會說你現在在過生活還是求生存?"
},
{
"id":6,
"title": "規訓",
"content": "你所遵守的社交習慣,哪些是天生的、哪些是後來學會的?"
},
{
"id":7,
"title": "PUA",
"content": "讓你自我懷疑的是事情本身,還是某人的評價?"
},
{
"title": "耗材",
"content": "如果你明天突然休息,系統真的會因此停擺嗎?"
},
{
"title": "奴性",
"content": "在面對不合理的指令時,你的第一反應通常是什麼?"
},
{
"id":8,
"title": "潛規則",
"content": "有哪些規則是沒被寫出來,但你卻正在默默遵守的?"
},
{
"id":9,
"title": "社畜",
"content": "你如何區分「工作時的你」與「下班後的你」?"
},
{
"title": "門禁",
"content": "覺得最舒適的回家時間是什麼時候?"
},
{
"id":10,
"title": "邊界",
"content": "你什麼時候會說不,來保護自己?"
},
{
"id":11,
"title": "監控",
"content": "如果沒人看見,你的行為表現會和現在有很大的差異嗎?"
},
{
"title": "牆內",
"content": "你覺得現在的環境帶給你的是「保護感」還是「限制感」?"
},
{
"title": "限縮",
"content": "為了適應環境,你做出的最大調整是什麼?"
},
{
"id":12,
"title": "自由",
"content": "對你來說,什麼樣的狀態才叫「自由」?"
},
{
"id":13,
"title": "覺醒",
"content": "你接受自己的出廠設定嗎?"
},
{
"id":14,
"title": "躺平",
"content": "休息是因為想走更長的路,還是因為路已經走不下去了?"
},
{
"title": "反擊",
"content": "你曾為什麼事,大聲說出不滿或拒絕?"
},
{
"title": "主體性",
"id":15,
"title": "主體",
"content": "在群體中,你通常是提出意見的人還是配合的人?"
},
{
"title": "不定義",
"content": "如果不使用職稱,你會用哪三個詞來描述自己?"
},
{
"id":16,
"title": "做自己",
"content": "在公共場所,你覺得自己有多少程度能呈現真實的樣貌?"
},
{
"title": "找縫隙",
"content": "在繁忙的節奏中,你最常用什麼方式找回自己的空間?"
},
{
"title": "窒息",
"content": "在什麼樣的環境或話題中,你會感到最明顯的壓迫感?"
},
{
"id":17,
"title": "誰懂",
"content": "你覺得目前身邊的人,誰真正理解你的處境?"
},
{
"id":18,
"title": "焦慮",
"content": "你在擔心還沒發生的未來,還是後悔已經發生的過去?"
},
{
"title": "厭世",
"content": "厭世是對現狀的疲憊嗎?"
},
{
"title": "諷刺",
"content": "在荒謬的日常中,你如何用幽默來回應生活的無奈?"
},
{
"title": "共感",
"content": "裝置中哪些話是你說不出口,但有人替你說了?"
},
{
"title": "幻覺",
"content": "你正在追求的事,有多少是你的願望,有多少是社會的投射?"
}
]
}

@ -3,6 +3,8 @@ import './App.css'
import {Button, LangButton} from './comps/button'
import { useText } from './utils/usetext.jsx'
import { useNavigate } from 'react-router-dom';
import Lottie from 'lottie-react';
import landing_animation from './assets/lottie/Grayscale_landing.json';
function App() {
@ -12,7 +14,10 @@ function App() {
return (
<main>
<LangButton lang={nextLang} onClick={toggleLang} />
<img src="/main.png" alt="Main" className='w-full flex-1 object-contain'/>
{/* <img src="/main.png" alt="Main" className='w-full flex-1 object-contain'/> */}
<div className='w-full flex-1 flex items-center justify-center'>
<Lottie animationData={landing_animation} loop={true}/>
</div>
<Button onClick={()=>{
navigate('/keywords');
}}>{getText('button_enter')}</Button>

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
{"v":"5.12.1","fr":30,"ip":0,"op":61,"w":34,"h":34,"nm":"circle","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":24,"s":[100]},{"t":60,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[17,17,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.5,"y":1},"o":{"x":0.08,"y":0},"t":0,"s":[{"i":[[-2.376,0],[0,-2.262],[2.376,0],[0,2.262]],"o":[[2.376,0],[0,2.262],[-2.376,0],[0,-2.262]],"v":[[0,-4.096],[4.303,0],[0,4.096],[-4.303,0]],"c":true}]},{"t":60,"s":[{"i":[[-6.962,0],[0,-6.627],[6.962,0],[0,6.627]],"o":[[6.962,0],[0,6.627],[-6.962,0],[0,-6.627]],"v":[[0,-12],[12.605,0],[0,12],[-12.605,0]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":61,"st":0,"ct":1,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[17,17,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[31,31,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[34,34],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":61,"st":0,"ct":1,"bm":0}],"markers":[],"props":{}}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -106,6 +106,8 @@ export default function Canvas({ lookat, ...props }) {
// draw random circles
const context=refContext.current;
const canvas=refCanvas.current;
if(!canvas || !context) return;
context.clearRect(0, 0, canvas.width, canvas.height);
// draw random circles

@ -3,13 +3,16 @@
body{
font-family: "Space Mono", "Noto Sans TC", sans-serif;
@apply bg-black text-white;
@apply flex justify-center items-center min-h-screen;
}
.root{
@apply bg-black text-white min-h-screen flex justify-center items-center;
#root{
@apply flex-1 overflow-hidden bg-black text-white flex justify-center items-center w-full max-w-[640px] ;
}
main{
@apply bg-black text-white flex justify-center items-center min-h-screen px-[1rem] py-[3.5rem] flex flex-col justify-end gap-[3rem];
@apply bg-black text-white flex justify-center items-center min-h-screen px-[1rem] py-[3.5rem] flex flex-col justify-end gap-[3rem];
@apply w-full;
}
button{

@ -4,7 +4,9 @@ import { useText } from "../utils/usetext.jsx";
import { useNavigate } from "react-router-dom";
import About from "./about.jsx";
import Canvas from "../comps/canvas.jsx";
import Lottie from "lottie-react";
import hint_animation from '../assets/lottie/hint.json';
import egg_bg from '../assets/lottie/egg_bg.json';
const State={
Intro: 'Intro',
@ -34,8 +36,9 @@ export default function Explore() {
if(state===State.Intro){
return (
<main className="!justify-center">
<div className="text-[1.125rem]">{getText('title_explore')}</div>
<img src="hint.svg"/>
<div className="text-[1.125rem] text-center">{getText('title_explore')}</div>
{/* <img src="hint.svg"/> */}
<Lottie animationData={hint_animation} loop={true} className='w-full'/>
</main>
);
}
@ -55,7 +58,9 @@ export default function Explore() {
</section>
<div className="w-full relative aspect-[393/500]">
<img src="egg_bg.svg" alt="egg" className="w-full object-contain"/>
{/* <img src="egg_bg.svg" alt="egg" className="w-full object-contain"/> */}
<Lottie animationData={egg_bg} loop={true} className='w-full'/>
<Canvas className="absolute inset-0 top-0 left-0 w-full h-full"
lookat={selectedKeyword.indexOf(lookat)}/>
</div>

@ -29,23 +29,30 @@ export default function Keywords() {
return (
<main className="!px-0 !justify-between">
<h1 className="text-[1.125rem] mt-[3.875rem]">{getText('title_keywords')}</h1>
<section ref={refContainer} className="w-full h-[107vw] overflow-x-auto overflow-y-hidden relative">
{keywords.map((keyword, index) => (
<div key={index} className="absolute w-[54vw] aspect-[212/180] bg-contain bg-no-repeat flex items-center justify-center"
style={{
top: `${Math.floor(index/colCount) * 32}vw`,
left: `${(index % colCount) * 40 + 5*Math.floor(index/colCount)}vw`,
backgroundImage: `url(/topic${selectedKeyword.includes(keyword) ? '_select' : ''}.svg)`,
}}
onClick={()=>{
console.log('clicked keyword', keyword.title);
select(keyword);
}}>
<span className="break-word max-w-[50%] text-center">{keyword.title}</span>
<h1 className="text-[1.125rem]">{getText('title_keywords')}</h1>
<section className='w-full flex-1 flex items-center justify-center'>
<div ref={refContainer} className="w-full overflow-x-auto">
<div className='w-[264%] grid grid-cols-6 aspect-[1036/424] overflow-y-hidden'>
{keywords.map((keyword, index) => (
<div key={index} className="w-full h-full bg-no-repeat relative" >
<div className="absolute top-[-15%] w-[123%] h-[128%] bg-no-repeat bg-contain flex items-center justify-center"
style={{
left: `${15*Math.floor(index/colCount)}%`,
backgroundImage: `url(/topic${selectedKeyword.includes(keyword) ? '_select' : ''}.svg)`,
}}
onClick={()=>{
console.log('clicked keyword', keyword.title);
select(keyword);
}}>
<span className="break-word text-center w-[50%]">{keyword.title}</span>
</div>
</div>
))}
</div>
))}
</div>
</section>
<div className="w-full px-[1.5rem]">

Loading…
Cancel
Save