92 lines
No EOL
3.2 KiB
TypeScript
92 lines
No EOL
3.2 KiB
TypeScript
import classNames from 'classnames'
|
|
import { CSSProperties, useEffect, useMemo, useState } from 'react'
|
|
|
|
function Homepage2() {
|
|
|
|
const floorClient = (number: number) => Math.floor(number / 50)
|
|
|
|
const [columns, setColumns] = useState(0)
|
|
const [rows, setRows] = useState(0)
|
|
const [params, setParams] = useState({ columns, rows, quantity: columns * rows })
|
|
const [position, setPosition] = useState([0, 0])
|
|
const [active, setActve] = useState(false)
|
|
const [action, setAction] = useState(false)
|
|
const [count, setCount] = useState(0)
|
|
|
|
useEffect(() => {
|
|
function handleResize() {
|
|
setColumns(floorClient(document.body.clientWidth))
|
|
setRows(floorClient(document.body.clientHeight))
|
|
}
|
|
handleResize()
|
|
window.addEventListener('resize', handleResize)
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
const timeout = setTimeout(() => {
|
|
setParams({ columns, rows, quantity: columns * rows })
|
|
}, 500)
|
|
return () => clearTimeout(timeout)
|
|
}, [columns, rows])
|
|
|
|
const createTiles = useMemo(() => {
|
|
|
|
const sentences = [
|
|
'Ethem ...',
|
|
'hat ...',
|
|
'lange ...',
|
|
'Hörner 🐂',
|
|
'Grüße von Mallorca 🌊 🦦 ☀️'
|
|
]
|
|
|
|
function createTile(index: number) {
|
|
|
|
const x = index % params.columns
|
|
const y = Math.floor(index / params.columns)
|
|
const xDiff = (x - position[0]) / 20
|
|
const yDiff = (y - position[1]) / 20
|
|
const pos = (Math.sqrt(xDiff * xDiff + yDiff * yDiff)).toFixed(2)
|
|
|
|
const doEffect = (posX: number, posY: number) => {
|
|
if (action)
|
|
return
|
|
setPosition([posX, posY])
|
|
setActve(e => !e)
|
|
setAction(true)
|
|
|
|
const xDiff = (x: number) => (x - posX) / 50
|
|
const yDiff = (y: number) => (y - posY) / 50
|
|
const pos = (x: number, y: number) => Math.sqrt(xDiff(x) * xDiff(x) + yDiff(y) * yDiff(y))
|
|
const diagonals = [pos(0, 0), pos(params.columns, 0), pos(0, params.rows), pos(params.columns, params.rows)]
|
|
|
|
setTimeout(() => {
|
|
setAction(false)
|
|
if (active)
|
|
setCount(e => e + 1)
|
|
}, Math.max(...diagonals) * 1000 + 1000)
|
|
}
|
|
|
|
return (
|
|
<div
|
|
key={index}
|
|
className={classNames('tile', (active ? 'active' : 'inactive'))}
|
|
style={{ '--delay': pos + 's' } as CSSProperties}
|
|
onClick={() => doEffect(x, y)}
|
|
></div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div id='tiles' style={{ '--columns': params.columns, '--rows': params.rows } as CSSProperties}>
|
|
<div className="center-div">
|
|
<h1 className={classNames('headline', (!active ? 'active' : 'inactive'))}>{sentences[count % sentences.length]}</h1>
|
|
</div>
|
|
{Array.from(Array(params.quantity)).map((_tile, index) => createTile(index))}
|
|
</div >
|
|
)
|
|
}, [params, position, active, action, count])
|
|
|
|
return createTiles
|
|
}
|
|
|
|
export default Homepage2 |