diff --git a/.gitignore b/.gitignore
index 0e828e1..478e4e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
**lock*
**_site**
**.jekyll**
+galaxy-react/public/models
diff --git a/galaxy-react/.env b/galaxy-react/.env
new file mode 100644
index 0000000..ba7cc18
--- /dev/null
+++ b/galaxy-react/.env
@@ -0,0 +1 @@
+GENERATE_SOURCEMAP=false
diff --git a/galaxy-react/.gitignore b/galaxy-react/.gitignore
new file mode 100644
index 0000000..9c3ae34
--- /dev/null
+++ b/galaxy-react/.gitignore
@@ -0,0 +1,25 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# production
+/build
+
+# misc
+.DS_Store
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+public/models
diff --git a/galaxy-react/package.json b/galaxy-react/package.json
new file mode 100644
index 0000000..653251f
--- /dev/null
+++ b/galaxy-react/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "galaxy",
+ "version": "0.1.0",
+ "private": true,
+ "dependencies": {
+ "@react-three/drei": "^9.109.2",
+ "@react-three/fiber": "^8.16.8",
+ "@react-three/postprocessing": "^2.16.2",
+ "@testing-library/jest-dom": "^5.17.0",
+ "@testing-library/react": "^13.4.0",
+ "@testing-library/user-event": "^13.5.0",
+ "@types/jest": "^27.5.2",
+ "@types/node": "^16.18.104",
+ "@types/react": "^18.3.3",
+ "@types/react-dom": "^18.3.0",
+ "@types/three": "^0.167.1",
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "react-scripts": "5.0.1",
+ "three": "^0.167.1",
+ "three-stdlib": "^2.30.5",
+ "typescript": "^4.9.5",
+ "web-vitals": "^2.1.4"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject"
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ]
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
+}
diff --git a/galaxy-react/public/favicon.ico b/galaxy-react/public/favicon.ico
new file mode 100644
index 0000000..a11777c
Binary files /dev/null and b/galaxy-react/public/favicon.ico differ
diff --git a/galaxy-react/public/index.html b/galaxy-react/public/index.html
new file mode 100644
index 0000000..aa069f2
--- /dev/null
+++ b/galaxy-react/public/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
diff --git a/galaxy-react/public/logo192.png b/galaxy-react/public/logo192.png
new file mode 100644
index 0000000..fc44b0a
Binary files /dev/null and b/galaxy-react/public/logo192.png differ
diff --git a/galaxy-react/public/logo512.png b/galaxy-react/public/logo512.png
new file mode 100644
index 0000000..a4e47a6
Binary files /dev/null and b/galaxy-react/public/logo512.png differ
diff --git a/galaxy-react/public/manifest.json b/galaxy-react/public/manifest.json
new file mode 100644
index 0000000..080d6c7
--- /dev/null
+++ b/galaxy-react/public/manifest.json
@@ -0,0 +1,25 @@
+{
+ "short_name": "React App",
+ "name": "Create React App Sample",
+ "icons": [
+ {
+ "src": "favicon.ico",
+ "sizes": "64x64 32x32 24x24 16x16",
+ "type": "image/x-icon"
+ },
+ {
+ "src": "logo192.png",
+ "type": "image/png",
+ "sizes": "192x192"
+ },
+ {
+ "src": "logo512.png",
+ "type": "image/png",
+ "sizes": "512x512"
+ }
+ ],
+ "start_url": ".",
+ "display": "standalone",
+ "theme_color": "#000000",
+ "background_color": "#ffffff"
+}
diff --git a/galaxy-react/public/robots.txt b/galaxy-react/public/robots.txt
new file mode 100644
index 0000000..e9e57dc
--- /dev/null
+++ b/galaxy-react/public/robots.txt
@@ -0,0 +1,3 @@
+# https://www.robotstxt.org/robotstxt.html
+User-agent: *
+Disallow:
diff --git a/galaxy-react/readme.md b/galaxy-react/readme.md
new file mode 100644
index 0000000..fd8e019
--- /dev/null
+++ b/galaxy-react/readme.md
@@ -0,0 +1,18 @@
+react-three fiber
+
+```sh
+$ npm i
+$ npm run start
+```
+
+## install
+
+```sh
+# npx create-react-app galaxy --template typescript
+# npm install three three-stdlib @types/three @react-three/fiber @react-three/fiber @react-three/drei @react-three/postprocessing
+```
+
+## ref
+
+- galaxy.glb : https://sketchfab.com/3d-models/need-some-space-d6521362b37b48e3a82bce4911409303
+- tsx : https://gist.github.com/artokun/fb7f0c68a01ba5d9813abb3ccce254c4
diff --git a/galaxy-react/src/App.css b/galaxy-react/src/App.css
new file mode 100644
index 0000000..74b5e05
--- /dev/null
+++ b/galaxy-react/src/App.css
@@ -0,0 +1,38 @@
+.App {
+ text-align: center;
+}
+
+.App-logo {
+ height: 40vmin;
+ pointer-events: none;
+}
+
+@media (prefers-reduced-motion: no-preference) {
+ .App-logo {
+ animation: App-logo-spin infinite 20s linear;
+ }
+}
+
+.App-header {
+ background-color: #282c34;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ font-size: calc(10px + 2vmin);
+ color: white;
+}
+
+.App-link {
+ color: #61dafb;
+}
+
+@keyframes App-logo-spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+}
diff --git a/galaxy-react/src/App.test.tsx b/galaxy-react/src/App.test.tsx
new file mode 100644
index 0000000..2a68616
--- /dev/null
+++ b/galaxy-react/src/App.test.tsx
@@ -0,0 +1,9 @@
+import React from 'react';
+import { render, screen } from '@testing-library/react';
+import App from './App';
+
+test('renders learn react link', () => {
+ render();
+ const linkElement = screen.getByText(/learn react/i);
+ expect(linkElement).toBeInTheDocument();
+});
diff --git a/galaxy-react/src/App.tsx b/galaxy-react/src/App.tsx
new file mode 100644
index 0000000..aa7016e
--- /dev/null
+++ b/galaxy-react/src/App.tsx
@@ -0,0 +1,9 @@
+import React from 'react';
+import './App.css';
+import { ThreeFiberGalaxy } from './pages/galaxy';
+
+function App() {
+ return
+}
+
+export default App;
diff --git a/galaxy-react/src/index.css b/galaxy-react/src/index.css
new file mode 100644
index 0000000..e8cd35b
--- /dev/null
+++ b/galaxy-react/src/index.css
@@ -0,0 +1,23 @@
+html {
+ height: 100%;
+}
+
+body {
+ background-color: #000;
+ margin: 0;
+ height: 100%;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+div#root{
+ height: 100%;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
+ monospace;
+}
diff --git a/galaxy-react/src/index.tsx b/galaxy-react/src/index.tsx
new file mode 100644
index 0000000..032464f
--- /dev/null
+++ b/galaxy-react/src/index.tsx
@@ -0,0 +1,19 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import './index.css';
+import App from './App';
+import reportWebVitals from './reportWebVitals';
+
+const root = ReactDOM.createRoot(
+ document.getElementById('root') as HTMLElement
+);
+root.render(
+
+
+
+);
+
+// If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+reportWebVitals();
diff --git a/galaxy-react/src/logo.svg b/galaxy-react/src/logo.svg
new file mode 100644
index 0000000..9dfc1c0
--- /dev/null
+++ b/galaxy-react/src/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/galaxy-react/src/pages/galaxy.tsx b/galaxy-react/src/pages/galaxy.tsx
new file mode 100644
index 0000000..f0e4774
--- /dev/null
+++ b/galaxy-react/src/pages/galaxy.tsx
@@ -0,0 +1,112 @@
+import * as THREE from 'three'
+import { Points, useGLTF, OrbitControls, ScrollControls, Scroll } from '@react-three/drei'
+import { GLTF } from 'three-stdlib'
+import { useFrame, Canvas } from '@react-three/fiber'
+import { useMemo, useRef } from 'react'
+import { EffectComposer, SelectiveBloom } from '@react-three/postprocessing'
+
+type GLTFResult = GLTF & {
+ nodes: {
+ Object_2: THREE.Mesh
+ }
+ materials: {
+ ['Scene_-_Root']: THREE.PointsMaterial
+ }
+}
+
+export function Galaxy(props: JSX.IntrinsicElements['group']) {
+ const ref = useRef(null!)
+ const galaxyCenterLightRef = useRef(null!)
+ const { nodes } = useGLTF('./models/galaxy.glb') as GLTFResult
+ const [positions, colors] = useMemo(() => {
+ nodes.Object_2.geometry.center()
+ const positions = new Float32Array(
+ nodes.Object_2.geometry.attributes.position.array.buffer
+ )
+ const colors = new Float32Array(positions.length)
+
+ const getDistanceToCenter = (x: number, y: number, z: number) =>
+ Math.sqrt(x * x + y * y + z * z)
+
+ // make colors closer to 0,0,0 be more reddish and colors further away be more blueish
+ const color = new THREE.Color()
+ for (let i = 0; i < positions.length; i += 3) {
+ const x = positions[i]
+ const y = positions[i + 1]
+ const z = positions[i + 2]
+ const distanceToCenter = getDistanceToCenter(x, y, z)
+ const normalizedDistanceToCenter = distanceToCenter / 100
+
+ // make colors closer to 0,0,0 be more reddish and colors further away be more blueish (do not use hsl)
+ color.setHSL(
+ (0.15 * (0.21 + Math.cos(distanceToCenter * 0.02))) / 2,
+ 0.75,
+ 0.6
+ )
+ color.setRGB(
+ Math.cos(normalizedDistanceToCenter),
+ THREE.MathUtils.randFloat(0, 0.8),
+ Math.sin(normalizedDistanceToCenter)
+ )
+ color.toArray(colors, i)
+ }
+
+ return [positions, colors]
+ }, [nodes])
+ //const starTexture = useLoader(THREE.TextureLoader, '/star.png')
+
+ // slowly rotate the galaxy
+ useFrame(({ clock }) => {
+ ref.current.rotation.z = clock.getElapsedTime() / 2
+ // zoom in and out
+ ref.current.scale.setScalar(Math.sin(clock.getElapsedTime() / 2) + 1.5)
+ })
+
+ // make particles glow
+
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
+
+useGLTF.preload('./models/galaxy.glb')
+
+export const ThreeFiberGalaxy = () => {
+ return (
+
+ )
+}
diff --git a/galaxy-react/src/react-app-env.d.ts b/galaxy-react/src/react-app-env.d.ts
new file mode 100644
index 0000000..6431bc5
--- /dev/null
+++ b/galaxy-react/src/react-app-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/galaxy-react/src/reportWebVitals.ts b/galaxy-react/src/reportWebVitals.ts
new file mode 100644
index 0000000..49a2a16
--- /dev/null
+++ b/galaxy-react/src/reportWebVitals.ts
@@ -0,0 +1,15 @@
+import { ReportHandler } from 'web-vitals';
+
+const reportWebVitals = (onPerfEntry?: ReportHandler) => {
+ if (onPerfEntry && onPerfEntry instanceof Function) {
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ getCLS(onPerfEntry);
+ getFID(onPerfEntry);
+ getFCP(onPerfEntry);
+ getLCP(onPerfEntry);
+ getTTFB(onPerfEntry);
+ });
+ }
+};
+
+export default reportWebVitals;
diff --git a/galaxy-react/src/setupTests.ts b/galaxy-react/src/setupTests.ts
new file mode 100644
index 0000000..8f2609b
--- /dev/null
+++ b/galaxy-react/src/setupTests.ts
@@ -0,0 +1,5 @@
+// jest-dom adds custom jest matchers for asserting on DOM nodes.
+// allows you to do things like:
+// expect(element).toHaveTextContent(/react/i)
+// learn more: https://github.com/testing-library/jest-dom
+import '@testing-library/jest-dom';
diff --git a/galaxy-react/tsconfig.json b/galaxy-react/tsconfig.json
new file mode 100644
index 0000000..a273b0c
--- /dev/null
+++ b/galaxy-react/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src"
+ ]
+}
diff --git a/galaxy/static/.DS_Store b/galaxy/static/.DS_Store
deleted file mode 100644
index 1b18240..0000000
Binary files a/galaxy/static/.DS_Store and /dev/null differ
diff --git a/galaxy/static/pkg/galaxy/.DS_Store b/galaxy/static/pkg/galaxy/.DS_Store
deleted file mode 100644
index 1b18240..0000000
Binary files a/galaxy/static/pkg/galaxy/.DS_Store and /dev/null differ
diff --git a/readme.md b/readme.md
index 4703f1a..a0635cb 100644
--- a/readme.md
+++ b/readme.md
@@ -1,12 +1,38 @@
# ai `star`
-- [particles.js](https://github.com/VincentGarreau/particles.js)
-- [galaxy](https://github.com/the-halfbloodprince/GalaxyM1199)
-- [solar-sys](https://github.com/solarcg/SolarSys)
+strive to build a [solar system](https://eyes.nasa.gov/apps/solar-system/).
-## example
+## galaxy
+
+```sh
+$ cd galaxy
+$ yarn install
+$ yarn dev
+```
+
+## galaxy-react
+
+```sh
+$ cd galaxy-react
+$ npm i
+$ npm run start
+```
+
+## solar & particle
+
+```sh
+$ cd xxx
+$ open index.html
+```
+
+## ref
-- [galaxy2](https://github.com/the-halfbloodprince/Galaxy-M2999)
- [100-stars](https://stars.chromeexperiments.com/)
- [nasa/solar-system](https://eyes.nasa.gov/apps/solar-system/)
- [nasa/3d-resources](https://github.com/nasa/NASA-3D-Resources)
+- [jeromeetienne/threex.planets](https://github.com/jeromeetienne/threex.planets)
+- [artokun/galaxy.tsx](https://gist.github.com/artokun/fb7f0c68a01ba5d9813abb3ccce254c4)
+- [VincentGarreau/particles.js](https://github.com/VincentGarreau/particles.js)
+- [the-halfbloodprince/GalaxyM1199](https://github.com/the-halfbloodprince/GalaxyM1199)
+- [the-halfbloodprince/Galaxy-M2999](https://github.com/the-halfbloodprince/Galaxy-M2999)
+- [solarcg/SolarSys](https://github.com/solarcg/SolarSys)