mirror of
https://github.com/cupcakearmy/fantus.git
synced 2024-12-22 16:26:25 +00:00
components
This commit is contained in:
parent
e1e4c06d08
commit
94ac7b29aa
162
components/background.tsx
Normal file
162
components/background.tsx
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import React, { useEffect } from 'react'
|
||||||
|
import { PerspectiveCamera, Scene, BufferGeometry, BufferAttribute, ShaderMaterial, Color, Points, WebGLRenderer, Camera } from 'three'
|
||||||
|
|
||||||
|
import '../styles/backgorund.styl'
|
||||||
|
|
||||||
|
// const SEPARATION = 150, AMOUNTX = 200, AMOUNTY = 200, HEIGHT = 75
|
||||||
|
const SEPARATION = 150, AMOUNTX = 50, AMOUNTY = 50, HEIGHT = 75
|
||||||
|
|
||||||
|
let container: HTMLElement | null
|
||||||
|
let camera: PerspectiveCamera
|
||||||
|
let scene: Scene
|
||||||
|
let renderer: WebGLRenderer
|
||||||
|
|
||||||
|
let count = 1
|
||||||
|
let particles: Points
|
||||||
|
|
||||||
|
let mouseX = 0
|
||||||
|
let mouseY = 0
|
||||||
|
let windowHalfX = window.innerWidth / 2
|
||||||
|
let windowHalfY = window.innerHeight / 2
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
container = window.document.getElementById('bg') || document.createElement('div')
|
||||||
|
|
||||||
|
document.body.appendChild(container)
|
||||||
|
camera = new PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000000)
|
||||||
|
scene = new Scene()
|
||||||
|
|
||||||
|
const numParticles = AMOUNTX * AMOUNTY
|
||||||
|
const positions = new Float32Array(numParticles * 3)
|
||||||
|
const scales = new Float32Array(numParticles)
|
||||||
|
|
||||||
|
let i = 0, j = 0
|
||||||
|
for (let ix = 0; ix < AMOUNTX; ix++) {
|
||||||
|
for (let iy = 0; iy < AMOUNTY; iy++) {
|
||||||
|
positions[i] = ix * SEPARATION - ((AMOUNTX * SEPARATION) / 2) // x
|
||||||
|
positions[i + 1] = 0 // y
|
||||||
|
positions[i + 2] = iy * SEPARATION - ((AMOUNTY * SEPARATION) / 2) // z
|
||||||
|
scales[j] = 1
|
||||||
|
i += 3
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const geometry = new BufferGeometry()
|
||||||
|
geometry.setAttribute('position', new BufferAttribute(positions, 3))
|
||||||
|
geometry.setAttribute('scale', new BufferAttribute(scales, 1))
|
||||||
|
|
||||||
|
const material = new ShaderMaterial({
|
||||||
|
uniforms: {
|
||||||
|
color: { value: new Color(0xffffff) },
|
||||||
|
},
|
||||||
|
vertexShader: document.getElementById('vertexshader')?.textContent || '',
|
||||||
|
fragmentShader: document.getElementById('fragmentshader')?.textContent || ''
|
||||||
|
})
|
||||||
|
|
||||||
|
particles = new Points(geometry, material)
|
||||||
|
scene.add(particles)
|
||||||
|
|
||||||
|
renderer = new WebGLRenderer({ antialias: true })
|
||||||
|
renderer.setPixelRatio(window.devicePixelRatio)
|
||||||
|
renderer.setSize(window.innerWidth, window.innerHeight)
|
||||||
|
|
||||||
|
container.appendChild(renderer.domElement)
|
||||||
|
document.addEventListener('mousemove', onDocumentMouseMove, false)
|
||||||
|
document.addEventListener('touchstart', onDocumentTouchStart, false)
|
||||||
|
document.addEventListener('touchmove', onDocumentTouchMove, false)
|
||||||
|
|
||||||
|
window.addEventListener('resize', onWindowResize, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWindowResize() {
|
||||||
|
windowHalfX = window.innerWidth / 2
|
||||||
|
windowHalfY = window.innerHeight / 2
|
||||||
|
camera.aspect = window.innerWidth / window.innerHeight
|
||||||
|
camera.updateProjectionMatrix()
|
||||||
|
renderer.setSize(window.innerWidth, window.innerHeight)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMouse(x: number, y: number) {
|
||||||
|
mouseX = (x - windowHalfX) / windowHalfX
|
||||||
|
mouseY = -(y - windowHalfY) / windowHalfY
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onDocumentMouseMove(event: MouseEvent) {
|
||||||
|
setMouse(event.clientX, event.clientY)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentTouchStart(event: TouchEvent) {
|
||||||
|
if (event.touches.length === 1) {
|
||||||
|
event.preventDefault()
|
||||||
|
setMouse(event.touches[0].pageX, event.touches[0].pageY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDocumentTouchMove(event: TouchEvent) {
|
||||||
|
if (event.touches.length === 1) {
|
||||||
|
event.preventDefault()
|
||||||
|
setMouse(event.touches[0].pageX, event.touches[0].pageY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
requestAnimationFrame(animate)
|
||||||
|
render()
|
||||||
|
}
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
// Noence from 0.0 to 1.0
|
||||||
|
const noence = (Math.sin(count / 4) + 1) / 2
|
||||||
|
const noence_inv = 1 - noence
|
||||||
|
|
||||||
|
camera.position.x = -mouseX * 500
|
||||||
|
camera.position.y = 1000 - mouseY * 500
|
||||||
|
camera.position.z = 1000 - mouseY * 250
|
||||||
|
camera.lookAt(scene.position)
|
||||||
|
|
||||||
|
if (particles.geometry instanceof BufferGeometry) {
|
||||||
|
const positions = particles.geometry.attributes.position.array
|
||||||
|
const scales = particles.geometry.attributes.scale.array
|
||||||
|
let i = 0, j = 0
|
||||||
|
for (let ix = 0; ix < AMOUNTX; ix++) {
|
||||||
|
for (let iy = 0; iy < AMOUNTY; iy++) {
|
||||||
|
const dx = Math.sin((ix + count) * 0.3)
|
||||||
|
const dy = Math.sin((iy + count) * 0.5)
|
||||||
|
// @ts-ignore
|
||||||
|
positions[i + 1] = (dx * HEIGHT) + (dy * HEIGHT)
|
||||||
|
// @ts-ignore
|
||||||
|
scales[j] = (dx + 1) * 8 + (dy + 1) * 8
|
||||||
|
i += 3
|
||||||
|
j++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
particles.material.uniforms.color.value.setRGB(1 - 0.5 * noence_inv, 0.2 + 0.8 * noence, 1)
|
||||||
|
if (particles.geometry.attributes.position instanceof BufferAttribute)
|
||||||
|
particles.geometry.attributes.position.needsUpdate = true
|
||||||
|
if (particles.geometry.attributes.scale instanceof BufferAttribute)
|
||||||
|
particles.geometry.attributes.scale.needsUpdate = true
|
||||||
|
|
||||||
|
}
|
||||||
|
renderer.render(scene, camera)
|
||||||
|
|
||||||
|
count += 0.05 + (0.01 * noence)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Background: React.FC = ({ children }) => {
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
init()
|
||||||
|
animate()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return <div id='bg'>
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Background
|
13
components/content.tsx
Normal file
13
components/content.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import '../styles/content.styl'
|
||||||
|
|
||||||
|
const Content: React.FC = ({ children }) => {
|
||||||
|
return <div className='container'>
|
||||||
|
{/* <div className='content'> */}
|
||||||
|
{children}
|
||||||
|
{/* </div> */}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Content
|
20
components/link.tsx
Normal file
20
components/link.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import NextLink, { LinkProps } from 'next/link'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
|
const Link: React.FC<LinkProps> = ({ href, children }) => {
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
let className = ''
|
||||||
|
try {
|
||||||
|
// @ts-ignore
|
||||||
|
className = children.props.className || ''
|
||||||
|
} catch { }
|
||||||
|
|
||||||
|
if (router.pathname === href)
|
||||||
|
className = `${className} active`.trim()
|
||||||
|
|
||||||
|
return <NextLink href={href}>{React.cloneElement(children as React.ReactElement, { className })}</NextLink>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Link
|
Loading…
Reference in New Issue
Block a user