generated from Klectr/KTemplate
make proportional scaling work on images
This commit is contained in:
parent
d38e349a92
commit
da40a13b83
@ -4,6 +4,7 @@ import { useDebounce } from "../utils/useDebounce"
|
|||||||
import { LayerEnum } from "../utils/enums"
|
import { LayerEnum } from "../utils/enums"
|
||||||
import images, { ImageCardType } from "../signals/images"
|
import images, { ImageCardType } from "../signals/images"
|
||||||
import { updateLocalStorage } from "../utils/localStorage"
|
import { updateLocalStorage } from "../utils/localStorage"
|
||||||
|
import { noop } from "kaioken/utils"
|
||||||
|
|
||||||
namespace ImageCard {
|
namespace ImageCard {
|
||||||
export interface ImageCardProps {
|
export interface ImageCardProps {
|
||||||
@ -13,12 +14,14 @@ namespace ImageCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps) {
|
export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps) {
|
||||||
|
const { debounce } = useDebounce()
|
||||||
const pressed = signal(false)
|
const pressed = signal(false)
|
||||||
const newX = useRef(0)
|
const newX = useRef(0)
|
||||||
const newY = useRef(0)
|
const newY = useRef(0)
|
||||||
const offsetX = useRef(0)
|
const offsetX = useRef(0)
|
||||||
const offsetY = useRef(0)
|
const offsetY = useRef(0)
|
||||||
const { debounce } = useDebounce()
|
const initialResizeX = useRef(0)
|
||||||
|
const initialResizeY = useRef(0)
|
||||||
|
|
||||||
function debounceLSUpdate(time?: number) {
|
function debounceLSUpdate(time?: number) {
|
||||||
debounce(() => {
|
debounce(() => {
|
||||||
@ -55,6 +58,35 @@ export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps
|
|||||||
window.addEventListener('mouseup', _handleMouseUp)
|
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 ratio = Math.min(newW / item.dimensions.w, newH / item.dimensions.h)
|
||||||
|
const newDim = { w: item.dimensions.w * ratio, h: item.dimensions.h * ratio }
|
||||||
|
|
||||||
|
ImagesSignal.default.updateImageProperty(itemKey, 'dimensions', newDim)
|
||||||
|
ImagesSignal.default.images.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
|
||||||
|
debounceLSUpdate()
|
||||||
|
window.removeEventListener('mousemove', _handleResizeMove)
|
||||||
|
window.removeEventListener('mouseup', _handleResizeMouseUp)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onmousedown={_handleMouseDown}
|
onmousedown={_handleMouseDown}
|
||||||
@ -65,20 +97,46 @@ export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps
|
|||||||
left: `${item.position.x}px`,
|
left: `${item.position.x}px`,
|
||||||
width: `${item.dimensions.w}px`,
|
width: `${item.dimensions.w}px`,
|
||||||
height: `${item.dimensions.h}px`,
|
height: `${item.dimensions.h}px`,
|
||||||
backgroundColor: '#181818'
|
backgroundColor: '#181818',
|
||||||
|
backgroundImage: `url(${item.contents})`,
|
||||||
|
backgroundRepeat: 'no-repeat',
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundPosition: 'center'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
<button className="flex justify-center items-center hover:bg-blue-500 w-5 h-5 text-white text-md absolute right-0 top-0" onclick={(_e: Event) => {
|
<button className="flex justify-center items-center hover:bg-blue-500 w-5 h-5 text-white text-md absolute right-0 top-0" onclick={(_e: Event) => {
|
||||||
ImagesSignal.default.removeImage(item.id)
|
ImagesSignal.default.removeImage(item.id)
|
||||||
ImagesSignal.default.images.notify()
|
ImagesSignal.default.images.notify()
|
||||||
debounceLSUpdate()
|
debounceLSUpdate()
|
||||||
}}>x</button>
|
}}>x</button>
|
||||||
<img
|
|
||||||
src={item.contents}
|
<ExpandIcon cb={_handleResizeMouseDown} />
|
||||||
alt={item.title}
|
|
||||||
/>
|
|
||||||
</div >
|
</div >
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ExpandIcon({ cb }: {
|
||||||
|
cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
onmousedown={cb}
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="#333"
|
||||||
|
stroke-width="1"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
className="cursor-[se-resize] absolute right-0 bottom-0 rotate-[225deg]"
|
||||||
|
>
|
||||||
|
<path d="M2 10v4" />
|
||||||
|
<path d="M4 8v8" />
|
||||||
|
<path d="M6 5v14" />
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { signal, useCallback, useRef } from "kaioken"
|
import { signal, useRef } from "kaioken"
|
||||||
import { NotesSigal, focusedItem } from "../signals"
|
import { NotesSigal, focusedItem } from "../signals"
|
||||||
import { useDebounce } from "../utils/useDebounce"
|
import { useDebounce } from "../utils/useDebounce"
|
||||||
import notes, { NoteCardType } from "../signals/notes"
|
import notes, { NoteCardType } from "../signals/notes"
|
||||||
@ -123,8 +123,20 @@ export function NoteCard({ key: itemKey, data: item }: NoteCard.NoteCardProps) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<ExpandIcon cb={_handleResizeMouseDown} />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ExpandIcon({ cb }: {
|
||||||
|
cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
<svg
|
<svg
|
||||||
onmousedown={_handleResizeMouseDown}
|
onmousedown={cb}
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="24"
|
width="24"
|
||||||
height="24"
|
height="24"
|
||||||
@ -140,9 +152,5 @@ export function NoteCard({ key: itemKey, data: item }: NoteCard.NoteCardProps) {
|
|||||||
<path d="M4 8v8" />
|
<path d="M4 8v8" />
|
||||||
<path d="M6 5v14" />
|
<path d="M6 5v14" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
</div>
|
|
||||||
</div >
|
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user