generated from Klectr/KTemplate
Compare commits
No commits in common. "5b0b8c222442e89ceb32f8bd10848b826b834a59" and "0866f0b47020812fc3f70b0e2244f1d7b9dddb06" have entirely different histories.
5b0b8c2224
...
0866f0b470
@ -1,5 +1,5 @@
|
|||||||
import { useRef, useEffect } from "kaioken"
|
import { useRef, useEffect } from "kaioken"
|
||||||
import { ImagesSignal, NotesSigal, TextSignal, canvasDimentsion } from "../signals"
|
import { ImagesSignal, NotesSigal, canvasDimentsion } from "../signals"
|
||||||
import { NoteCard } from "./NoteCard"
|
import { NoteCard } from "./NoteCard"
|
||||||
import notes from "../signals/notes"
|
import notes from "../signals/notes"
|
||||||
import { MiniMap } from "./MiniMap"
|
import { MiniMap } from "./MiniMap"
|
||||||
@ -7,8 +7,6 @@ import { ImageCard } from "./ImageCard"
|
|||||||
import images from "../signals/images"
|
import images from "../signals/images"
|
||||||
import { CardSelector } from "./cardSelector/CardSelector"
|
import { CardSelector } from "./cardSelector/CardSelector"
|
||||||
import { isTheme } from "../utils/isTheme"
|
import { isTheme } from "../utils/isTheme"
|
||||||
import { TextItem } from "./TextItem"
|
|
||||||
import texts from "../signals/texts"
|
|
||||||
|
|
||||||
export default function InfiniteCanvas() {
|
export default function InfiniteCanvas() {
|
||||||
const containerRef = useRef<HTMLDivElement>(null)
|
const containerRef = useRef<HTMLDivElement>(null)
|
||||||
@ -30,7 +28,6 @@ export default function InfiniteCanvas() {
|
|||||||
window.addEventListener("resize", updateDimensions)
|
window.addEventListener("resize", updateDimensions)
|
||||||
notes.loadLocalStorage()
|
notes.loadLocalStorage()
|
||||||
images.loadLocalStorage()
|
images.loadLocalStorage()
|
||||||
texts.loadLocalStorage()
|
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("resize", updateDimensions)
|
window.removeEventListener("resize", updateDimensions)
|
||||||
@ -67,14 +64,6 @@ export default function InfiniteCanvas() {
|
|||||||
<ImageCard key={itemKey} data={item} />
|
<ImageCard key={itemKey} data={item} />
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{Object.keys(TextSignal.default.texts.value).map((itemKey: string) => {
|
|
||||||
const item = TextSignal.default.texts.value[itemKey]
|
|
||||||
return (
|
|
||||||
<TextItem key={itemKey} data={item} />
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -3,7 +3,6 @@ import notes, { NoteCardType } from "../signals/notes"
|
|||||||
import { canvasDimentsion } from "../signals"
|
import { canvasDimentsion } from "../signals"
|
||||||
import { LayerEnum } from "../utils/enums"
|
import { LayerEnum } from "../utils/enums"
|
||||||
import images, { ImageCardType } from "../signals/images"
|
import images, { ImageCardType } from "../signals/images"
|
||||||
import texts from "../signals/texts"
|
|
||||||
|
|
||||||
const _MAP_OFFSET = 20
|
const _MAP_OFFSET = 20
|
||||||
const _MAP_SCALE_FACTOR = 10
|
const _MAP_SCALE_FACTOR = 10
|
||||||
@ -96,35 +95,6 @@ export function MiniMap() {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
||||||
{Object.keys(texts.texts.value).map((textKey: textCardType['id']) => {
|
|
||||||
const text = texts.texts.value[textKey]
|
|
||||||
const el = useRef(null)
|
|
||||||
|
|
||||||
function _handleItemClick(_e: MouseEvent) {
|
|
||||||
window.scrollTo({
|
|
||||||
left: text.position.x - ((viewportWidth / 2) - (text.dimensions.w / 2)),
|
|
||||||
top: text.position.y - ((viewportHeight / 2) - (text.dimensions.h / 2)),
|
|
||||||
behavior: 'smooth'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div ref={el} className={"bg-indigo-500 hover:bg-blue-500 cursor-pointer"}
|
|
||||||
onclick={_handleItemClick}
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
width: `${text.dimensions.w / _MAP_SCALE_FACTOR}px`,
|
|
||||||
height: `${text.dimensions.h / _MAP_SCALE_FACTOR}px`,
|
|
||||||
top: `${(text.position.y / _MAP_SCALE_FACTOR)}px`,
|
|
||||||
left: `${(text.position.x / _MAP_SCALE_FACTOR)}px`,
|
|
||||||
border: '1px solid #222',
|
|
||||||
borderRadius: '2px',
|
|
||||||
zIndex: `${LayerEnum.MINIMAP + 1}`
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
)
|
|
||||||
})}
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
className={'absolute bg-blue-200 bg-opacity-10 border dark:border-blue-800 border-blue-500 bg-blue-500 rounded'}
|
className={'absolute bg-blue-200 bg-opacity-10 border dark:border-blue-800 border-blue-500 bg-blue-500 rounded'}
|
||||||
style={{
|
style={{
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
import { signal, useRef } from "kaioken"
|
|
||||||
import { TextSignal, focusedItem } from "../signals"
|
|
||||||
import { useDebounce } from "../utils/useDebounce"
|
|
||||||
import texts, { TextCardType } from "../signals/texts"
|
|
||||||
import { LayerEnum } from "../utils/enums"
|
|
||||||
import { isTheme } from "../utils/isTheme"
|
|
||||||
|
|
||||||
namespace TextItem {
|
|
||||||
export interface TextCardProps {
|
|
||||||
key: TextCardType['id']
|
|
||||||
data: TextCardType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) {
|
|
||||||
const saved = signal(true)
|
|
||||||
const pressed = signal(false)
|
|
||||||
const newX = useRef(0)
|
|
||||||
const newY = useRef(0)
|
|
||||||
const offsetX = useRef(0)
|
|
||||||
const offsetY = useRef(0)
|
|
||||||
const initialResizeX = useRef(0)
|
|
||||||
const initialResizeY = useRef(0)
|
|
||||||
|
|
||||||
const { debounce } = useDebounce()
|
|
||||||
|
|
||||||
function updateLocalStorage(time?: number) {
|
|
||||||
debounce(() => {
|
|
||||||
localStorage.setItem("texts", JSON.stringify(texts.texts.value))
|
|
||||||
}, time)
|
|
||||||
}
|
|
||||||
|
|
||||||
function _handleMouseMove(e: MouseEvent) {
|
|
||||||
e.preventDefault()
|
|
||||||
if (!pressed.value) return
|
|
||||||
|
|
||||||
newX.current = e.pageX - offsetX.current
|
|
||||||
newY.current = e.pageY - offsetY.current
|
|
||||||
const newPos = { x: newX.current, y: newY.current }
|
|
||||||
|
|
||||||
TextSignal.default.updateTextProperty(itemKey, 'position', newPos)
|
|
||||||
updateLocalStorage()
|
|
||||||
}
|
|
||||||
|
|
||||||
function _handleMouseUp(e: MouseEvent) {
|
|
||||||
e.preventDefault()
|
|
||||||
pressed.value = false
|
|
||||||
window.removeEventListener('mousemove', _handleMouseMove)
|
|
||||||
window.removeEventListener('mouseup', _handleMouseUp)
|
|
||||||
}
|
|
||||||
|
|
||||||
function _handleMouseDown(e: MouseEvent) {
|
|
||||||
e.preventDefault()
|
|
||||||
offsetX.current = e.offsetX
|
|
||||||
offsetY.current = e.offsetY
|
|
||||||
pressed.value = true
|
|
||||||
window.addEventListener('mousemove', _handleMouseMove)
|
|
||||||
window.addEventListener('mouseup', _handleMouseUp)
|
|
||||||
}
|
|
||||||
|
|
||||||
function _handleResizeMove(e: MouseEvent) {
|
|
||||||
const { pageX, pageY } = e
|
|
||||||
const [newX, newY] = [initialResizeX.current - pageX, initialResizeY.current - pageY]
|
|
||||||
|
|
||||||
const newW = -newX + item.dimensions.w
|
|
||||||
const newH = -newY + item.dimensions.h
|
|
||||||
const newDim = { w: newW, h: newH }
|
|
||||||
|
|
||||||
TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDim)
|
|
||||||
TextSignal.default.texts.notify()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function _handleResizeMouseDown(e: MouseEvent) {
|
|
||||||
initialResizeX.current = e.pageX
|
|
||||||
initialResizeY.current = e.pageY
|
|
||||||
pressed.value = true
|
|
||||||
window.addEventListener('mousemove', _handleResizeMove)
|
|
||||||
window.addEventListener('mouseup', _handleResizeMouseUp)
|
|
||||||
}
|
|
||||||
|
|
||||||
function _handleResizeMouseUp() {
|
|
||||||
pressed.value = false
|
|
||||||
updateLocalStorage()
|
|
||||||
window.removeEventListener('mousemove', _handleResizeMove)
|
|
||||||
window.removeEventListener('mouseup', _handleResizeMouseUp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
onmousedown={_handleMouseDown}
|
|
||||||
className="select-none transition flex flex-col justify-stretch rounded border border-[#3c3c3c] absolute border-dashed"
|
|
||||||
style={{
|
|
||||||
zIndex: `${focusedItem.value == itemKey ? LayerEnum.CARD_ELEVATED : LayerEnum.CARD}`,
|
|
||||||
width: `${item.dimensions.w}px`,
|
|
||||||
height: `${item.dimensions.h + 100}px`,
|
|
||||||
top: `${item.position.y}px`,
|
|
||||||
left: `${item.position.x}px`,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className={'relative w-full h-full'}>
|
|
||||||
<p className={'w-full h-full'}>{item.contents}</p>
|
|
||||||
</div>
|
|
||||||
</div >
|
|
||||||
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +1,9 @@
|
|||||||
import { TextSignal } from "../../signals";
|
|
||||||
import texts from "../../signals/texts";
|
|
||||||
import { updateLocalStorage } from "../../utils/localStorage";
|
|
||||||
import { defaultClassName } from "./utils";
|
import { defaultClassName } from "./utils";
|
||||||
|
|
||||||
export function TextButton() {
|
export function TextButton() {
|
||||||
|
|
||||||
function _handleClick(e: MouseEvent) {
|
|
||||||
TextSignal.default.addText({
|
|
||||||
type: "text",
|
|
||||||
title: "New Note",
|
|
||||||
contents: "todo: fill me",
|
|
||||||
position: {
|
|
||||||
x: e.pageX - 100,
|
|
||||||
y: e.pageY + (window.innerHeight / 2) - 100
|
|
||||||
},
|
|
||||||
dimensions: {
|
|
||||||
w: 200,
|
|
||||||
h: 100
|
|
||||||
}
|
|
||||||
})
|
|
||||||
updateLocalStorage("text", texts.texts.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
onclick={_handleClick}
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
|
@ -6,4 +6,3 @@ export const canvasDimentsion = signal({ width: 3000, height: 3000 })
|
|||||||
|
|
||||||
export * as NotesSigal from "./notes"
|
export * as NotesSigal from "./notes"
|
||||||
export * as ImagesSignal from "./images"
|
export * as ImagesSignal from "./images"
|
||||||
export * as TextSignal from "./texts"
|
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
import { signal } from "kaioken"
|
|
||||||
import { Card } from "../types"
|
|
||||||
import { focusedItem } from "."
|
|
||||||
|
|
||||||
export type TextCardType = Card<"text">
|
|
||||||
|
|
||||||
const texts = signal<Record<TextCardType["id"], TextCardType>>({})
|
|
||||||
|
|
||||||
function loadLocalStorage() {
|
|
||||||
texts.value = JSON.parse(localStorage.getItem("texts") ?? "{}")
|
|
||||||
}
|
|
||||||
|
|
||||||
function addText(data: Omit<TextCardType, "id">) {
|
|
||||||
const newCard = {
|
|
||||||
...data,
|
|
||||||
id: crypto.randomUUID(),
|
|
||||||
}
|
|
||||||
texts.value[newCard.id] = newCard
|
|
||||||
texts.notify()
|
|
||||||
focusedItem.value = newCard.id
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeText(id: TextCardType["id"]) {
|
|
||||||
delete texts.value[id]
|
|
||||||
texts.notify()
|
|
||||||
}
|
|
||||||
function updateTextProperty<K extends keyof TextCardType>(
|
|
||||||
id: TextCardType["id"],
|
|
||||||
property: K,
|
|
||||||
data: TextCardType[K]
|
|
||||||
) {
|
|
||||||
const newData = {
|
|
||||||
...texts.value[id],
|
|
||||||
[property]: data,
|
|
||||||
}
|
|
||||||
texts.value[id] = newData
|
|
||||||
texts.notify()
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
texts,
|
|
||||||
addText,
|
|
||||||
removeText,
|
|
||||||
updateTextProperty,
|
|
||||||
loadLocalStorage,
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
export type CardTypes = "note" | "image" | "text"
|
export type CardTypes = "note" | "image"
|
||||||
export type positionCoords = { x: number; y: number }
|
export type positionCoords = { x: number; y: number }
|
||||||
export type dimensionCoords = { w: number; h: number }
|
export type dimensionCoords = { w: number; h: number }
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import { CardTypes } from "../types"
|
|
||||||
|
|
||||||
export function updateLocalStorage(
|
export function updateLocalStorage(
|
||||||
location: CardTypes,
|
location: "notes" | "images",
|
||||||
collection: unknown[] | Record<string, unknown>
|
collection: unknown[] | Record<string, unknown>
|
||||||
) {
|
) {
|
||||||
localStorage.setItem(location, JSON.stringify(collection))
|
localStorage.setItem(location, JSON.stringify(collection))
|
||||||
|
Loading…
Reference in New Issue
Block a user