Add minimap so user can tell where they are on page

This commit is contained in:
Triston Armstrong 2024-10-05 10:14:00 -04:00
parent d14b240333
commit 665e82ca43
7 changed files with 103 additions and 16 deletions

BIN
bun.lockb

Binary file not shown.

View File

@ -1,32 +1,31 @@
import { useState, useRef, useEffect } from "kaioken"
import { useRef, useEffect } from "kaioken"
import { CardSelector } from "./CardSelector"
import { NotesSigal } from "../signals"
import { NotesSigal, canvasDimentsion } from "../signals"
import { NoteCard } from "./NoteCard"
import notes from "../signals/notes"
import { MiniMap } from "./MiniMap"
export default function InfiniteCanvas() {
const [dimensions, setDimensions] = useState({ width: 3000, height: 3000 })
const containerRef = useRef<HTMLDivElement>(null)
useEffect(() => {
window.scrollTo({
left: (dimensions.width / 2) - (window.innerWidth / 2),
top: (dimensions.height / 2) - (window.innerHeight / 2)
left: (canvasDimentsion.value.width / 2) - (window.innerWidth / 2),
top: (canvasDimentsion.value.height / 2) - (window.innerHeight / 2)
})
const updateDimensions = () => {
setDimensions((prevDimensions) => ({
width: Math.max(prevDimensions.width, window.innerWidth),
height: Math.max(prevDimensions.height, window.innerHeight),
}))
canvasDimentsion.value = {
width: Math.max(canvasDimentsion.value.width, window.innerWidth),
height: Math.max(canvasDimentsion.value.height, window.innerHeight),
}
}
updateDimensions()
window.addEventListener("resize", updateDimensions)
notes.loadLocalStorage()
return () => {
window.removeEventListener("resize", updateDimensions)
}
@ -35,6 +34,7 @@ export default function InfiniteCanvas() {
return (
<>
<CardSelector />
<MiniMap />
<div
className="h-screen w-full absolute top-0 left-0"
@ -43,8 +43,8 @@ export default function InfiniteCanvas() {
className="absolute top-0 left-0"
ref={containerRef}
style={{
width: `${dimensions.width.toString()}px`,
height: `${dimensions.width.toString()}px`,
width: `${canvasDimentsion.value.width}px`,
height: `${canvasDimentsion.value.width}px`,
backgroundSize: "30px 30px",
backgroundImage: "radial-gradient(circle, rgba(255, 255, 255, 0.2) 1px, transparent 1px)",
}}>

View File

@ -0,0 +1,78 @@
import { signal, useEffect, useRef } from "kaioken"
import notes from "../signals/notes"
import { Card } from "../types/Card"
import { canvasDimentsion } from "../signals"
import { LayerEnum } from "../utils/enums"
const _MAP_OFFSET = 20
const _MAP_SCALE_FACTOR = 10
const _defaults = { width: 0, height: 0 }
export function MiniMap() {
const el = useRef<HTMLDivElement>(null)
const scrollX = signal(0)
const scrollY = signal(0)
const elMeta = el.current?.getBoundingClientRect() ?? _defaults
const viewportWidth = window.innerWidth
const viewportHeight = window.innerHeight
const xPos = viewportWidth - elMeta?.width - _MAP_OFFSET
const yPos = viewportHeight - elMeta.height - _MAP_OFFSET
const width = canvasDimentsion.value.width / _MAP_SCALE_FACTOR
const height = canvasDimentsion.value.height / _MAP_SCALE_FACTOR
useEffect(() => {
function _handleScroll(_e: Event) {
scrollX.value = window.scrollX
scrollY.value = window.scrollY
}
window.addEventListener('scroll', _handleScroll)
return () => window.removeEventListener('scroll', _handleScroll)
}, [])
return (
<div ref={el} style={{
position: 'fixed',
backgroundColor: '#ffffff11',
width: `${width}px`,
height: `${height}px`,
translate: `${xPos}px ${yPos}px`,
zIndex: `${LayerEnum.MINIMAP}`,
borderRadius: '4px'
}}>
{Object.keys(notes.notes.value).map((noteKey: Card['id']) => {
const note = notes.notes.value[noteKey]
return (
<div
style={{
position: 'absolute',
width: `${note.dimensions.w / _MAP_SCALE_FACTOR}px`,
height: `${note.dimensions.h / _MAP_SCALE_FACTOR}px`,
top: `${(note.position.y / _MAP_SCALE_FACTOR)}px`,
left: `${(note.position.x / _MAP_SCALE_FACTOR)}px`,
backgroundColor: "#666",
border: '1px solid #222',
borderRadius: '2px'
}}
></div>
)
})}
<div style={{
position: 'absolute',
width: `${viewportWidth / _MAP_SCALE_FACTOR}px`,
height: `${viewportHeight / _MAP_SCALE_FACTOR}px`,
top: `${scrollY.value / _MAP_SCALE_FACTOR}px`,
left: `${scrollX.value / _MAP_SCALE_FACTOR}px`,
border: '1px solid #777',
zIndex: `${LayerEnum.MINIMAP}`,
backgroundColor: '#fff1',
borderRadius: '2px'
}}></div>
</div >
)
}

View File

@ -3,7 +3,7 @@ import { NotesSigal, focusedItem } from "../signals"
import { Card } from "../types"
import { useDebounce } from "../utils/useDebounce"
import notes from "../signals/notes"
import { save } from "@tauri-apps/api/dialog"
import { LayerEnum } from "../utils/enums"
namespace NoteCard {
export interface NoteCardProps {
@ -56,14 +56,12 @@ export function NoteCard({ key: itemKey, data: item }: NoteCard.NoteCardProps) {
window.addEventListener('mouseup', _handleMouseUp)
}
return (
<div
onmousedown={() => focusedItem.value = itemKey}
className="select-none transition flex flex-col justify-stretch shadow-lg rounded border border-[#3c3c3c] absolute"
style={{
zIndex: focusedItem.value == itemKey ? '999' : '0',
zIndex: `${focusedItem.value == itemKey ? LayerEnum.CARD_ELEVATED : LayerEnum.CARD}`,
width: `${item.dimensions.w}px`,
height: `${item.dimensions.h}px`,
top: `${item.position.y}px`,

View File

@ -2,5 +2,6 @@ import { signal } from "kaioken"
/** this should be an ID of some card/item */
export const focusedItem = signal<string | null>(null)
export const canvasDimentsion = signal({ width: 3000, height: 3000 })
export * as NotesSigal from "./notes"

View File

@ -8,6 +8,10 @@
box-sizing: border-box;
}
*::-webkit-scrollbar {
display: none;
}
html {
overflow: scroll;
}

6
src/utils/enums.ts Normal file
View File

@ -0,0 +1,6 @@
export enum LayerEnum {
BACKGROUND,
CARD,
CARD_ELEVATED,
MINIMAP,
}