Skip to content

Commit

Permalink
feat(people): StarBackground 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
manudeli committed Mar 17, 2024
1 parent 73e142a commit 716c9f1
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 7 deletions.
164 changes: 164 additions & 0 deletions apps/people/src/app/components/StarBackground.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
'use client'

import React, { useEffect } from 'react'

interface Props {
speedFactor?: number
backgroundColor?: string
starColor?: [number, number, number]
starCount?: number
}

export default function StarBackground(props: Props) {
const {
speedFactor = 0.05,
backgroundColor = 'black',
starColor = [255, 255, 255],
starCount = 5000,
} = props

useEffect(() => {
const canvas = document.getElementById(
'starfield'
) as HTMLCanvasElement | null

if (canvas) {
const c = canvas.getContext('2d')

if (c) {
let w = window.innerWidth
let h = window.innerHeight

const setCanvasExtents = () => {
canvas.width = w
canvas.height = h
}

setCanvasExtents()

window.onresize = () => {
setCanvasExtents()
}

const makeStars = (count: number) => {
const out = []
for (let i = 0; i < count; i++) {
const s = {
x: Math.random() * 1600 - 800,
y: Math.random() * 900 - 450,
z: Math.random() * 1000,
}
out.push(s)
}
return out
}

const stars = makeStars(starCount)

const clear = () => {
c.fillStyle = backgroundColor
c.fillRect(0, 0, canvas.width, canvas.height)
}

const putPixel = (x: number, y: number, brightness: number) => {
const rgb =
'rgba(' +
starColor[0] +
',' +
starColor[1] +
',' +
starColor[2] +
',' +
brightness +
')'
c.fillStyle = rgb
c.fillRect(x, y, 1, 1)
}

const moveStars = (distance: number) => {
const count = stars.length
for (let i = 0; i < count; i++) {
const s = stars[i]
s.z -= distance
while (s.z <= 1) {
s.z += 1000
}
}
}

let prevTime: number
const init = (time: number) => {
prevTime = time
requestAnimationFrame(tick)
}

const tick = (time: number) => {
const elapsed = time - prevTime
prevTime = time

moveStars(elapsed * speedFactor)

clear()

const cx = w / 2
const cy = h / 2

const count = stars.length
for (let i = 0; i < count; i++) {
const star = stars[i]

const x = cx + star.x / (star.z * 0.001)
const y = cy + star.y / (star.z * 0.001)

if (x < 0 || x >= w || y < 0 || y >= h) {
continue
}

const d = star.z / 1000.0
const b = 1 - d * d

putPixel(x, y, b)
}

requestAnimationFrame(tick)
}

requestAnimationFrame(init)

// add window resize listener:
window.addEventListener('resize', function () {
w = window.innerWidth
h = window.innerHeight
setCanvasExtents()
})
} else {
console.error('Could not get 2d context from canvas element')
}
} else {
console.error('Could not find canvas element with id "starfield"')
}

return () => {
window.onresize = null
}
}, [starColor, backgroundColor, speedFactor, starCount])

return (
<canvas
id="starfield"
style={{
padding: 0,
margin: 0,
position: 'fixed',
top: 0,
right: 0,
bottom: 0,
left: 0,
zIndex: 10,
opacity: 1,
pointerEvents: 'none',
mixBlendMode: 'screen',
}}
></canvas>
)
}
15 changes: 8 additions & 7 deletions apps/people/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { SuspenseImage } from '@suspensive/react-image'
import { Reorder, motion } from 'framer-motion'
import { useState } from 'react'
import { Card, type CardData } from './components/Card'
import StarBackground from './components/StarBackground'
import { initialCards } from '~/mock/cardDatas'

export default function Home() {
Expand All @@ -15,13 +16,13 @@ export default function Home() {
>(null)

return (
<Stack
overflow="hidden"
backgroundColor="#13120f"
height="100vh"
as={motion.div}
spacing={10}
>
<Stack overflow="hidden" height="100vh" as={motion.div} spacing={10}>
<StarBackground
starCount={1000}
starColor={[255, 255, 255]}
speedFactor={0.05}
backgroundColor="#0b0b09"
/>
<Flex.Center flex={1}>
<Suspense clientOnly fallback={null}>
<Suspense
Expand Down

0 comments on commit 716c9f1

Please sign in to comment.