Skip to content

Commit

Permalink
Merge pull request #5 from Ashish-simpleCoder/v1
Browse files Browse the repository at this point in the history
Fix cavnas color issue
  • Loading branch information
Ashish-simpleCoder authored Mar 12, 2024
2 parents a015d95 + 91fbdf0 commit 0de2ed7
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 26 deletions.
29 changes: 16 additions & 13 deletions src/atom/canvas.atom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type CanvasAtom = {
ref: RefObject<ElementRef<'canvas'>> | { current: null }
activeClr: keyof typeof CANVAS_CLRS
opacity: number
history_index: number
history_cursor: number
canvas_path_histories: {
path: [number, number][]
color: CanvasAtom['activeClr']
Expand All @@ -31,11 +31,11 @@ export const canvasAtom = atom({
ref: { current: null },
activeClr: 'white',
opacity: 1,
history_index: (() => {
history_cursor: (() => {
try {
const paths = localStorage.getItem('canvas_path_histories')
if (paths) {
return JSON.parse(paths).length
return JSON.parse(paths).length - 1
}
} catch {
return -1
Expand All @@ -59,29 +59,31 @@ export const useCanvasAtomValue = () => useAtomValue(canvasAtom)
export const useCanvasAtomDispatch = () => useAtom(canvasAtom)[1]

export const useCanvasClrs = () => {
const [{ activeClr }, setCanvas] = useCanvasAtom()
const { activeClr } = useCanvasAtomValue()
const canvasDispatch = useCanvasAtomDispatch()

const updateCanvasClr = (clr: keyof typeof CANVAS_CLRS) => {
setCanvas((s) => {
s.activeClr = clr
return { ...s }
canvasDispatch((atom) => {
atom.activeClr = clr
return { ...atom }
})
}

return { activeClr, updateCanvasClr }
}

export const useCanvasHistoryIndex = () => {
const [{ history_index, canvas_path_histories }, setCanvas] = useCanvasAtom()
const [{ history_cursor, canvas_path_histories }] = useCanvasAtom()
const canvasDispatch = useCanvasAtomDispatch()

const setHistoryIndex = (cb: ((index: number) => number) | number) => {
setCanvas((s) => {
canvasDispatch((atom) => {
if (typeof cb == 'function') {
s.history_index = cb(s.history_index)
atom.history_cursor = cb(atom.history_cursor)
} else {
s.history_index = cb as number
atom.history_cursor = cb as number
}
return { ...s }
return { ...atom }
})
}

Expand All @@ -94,7 +96,8 @@ export const useCanvasHistoryIndex = () => {
})
}

return { history_index, setHistoryIndex, undo, redo }
return { history_cursor, setHistoryIndex, undo, redo }
}

export const getCanvasCtx = () => getDefaultStore().get(canvasAtom).ref.current?.getContext('2d')!
export const getCanvasActiveClr = () => getDefaultStore().get(canvasAtom).activeClr
12 changes: 6 additions & 6 deletions src/components/canvas-actions-container.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { FaRedo, FaUndo } from 'react-icons/fa'
import { useCanvasAtomValue, useCanvasHistoryIndex } from '../atom/canvas.atom'
import { CgRedo, CgUndo } from 'react-icons/cg'

export default function CanvasActionContainer() {
const { redo, undo, history_index } = useCanvasHistoryIndex()
const { redo, undo, history_cursor } = useCanvasHistoryIndex()
const { canvas_path_histories } = useCanvasAtomValue()

return (
Expand All @@ -12,17 +12,17 @@ export default function CanvasActionContainer() {
title='Undo -- CtrlZ'
className={'text-white disabled:text-gray-300 cursor-pointer disabled:cursor-not-allowed'}
onClick={undo}
disabled={history_index == -1}
disabled={history_cursor == -1}
>
<FaUndo />
<CgUndo />
</button>
<button
title='Redo -- Ctrl Shift Z'
className={'text-white disabled:text-gray-300 cursor-pointer disabled:cursor-not-allowed'}
onClick={redo}
disabled={history_index == canvas_path_histories.length - 1}
disabled={history_cursor == canvas_path_histories.length - 1}
>
<FaRedo />
<CgRedo />
</button>
</div>
</section>
Expand Down
8 changes: 7 additions & 1 deletion src/components/canvas.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { useEffect, useLayoutEffect } from 'react'
import { CANVAS_CLRS, getCanvasCtx, useCanvasAtomValue } from '../atom/canvas.atom'
import { CANVAS_CLRS, getCanvasCtx, useCanvasAtomDispatch, useCanvasAtomValue } from '../atom/canvas.atom'
import { useEventListener } from '../hooks/use-event-listener'
import useCanvasDrawing from '../hooks/use-canvas-drawing'

export default function Canvas() {
const { ref, activeClr, opacity } = useCanvasAtomValue()
const { startDrawing, stopDrawing, drawOnCanvas } = useCanvasDrawing()
const cavnasDispatch = useCanvasAtomDispatch()

// prettier-ignore
useEventListener(() => ref.current, 'pointerdown', (e) => {
startDrawing()
drawOnCanvas(e)
cavnasDispatch(atom=>{
atom.canvas_path_histories = atom.canvas_path_histories.slice(0,atom.history_cursor+1)
localStorage.setItem('canvas_path_histories', JSON.stringify(atom.canvas_path_histories))
return atom
})
})
useEventListener(() => ref.current, 'pointermove', drawOnCanvas)
useEventListener(() => ref.current, 'pointerup', stopDrawing)
Expand Down
16 changes: 13 additions & 3 deletions src/hooks/use-canvas-drawing.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import { flushSync } from 'react-dom'

import { CANVAS_CLRS, getCanvasCtx, useCanvasAtomDispatch, useCanvasAtomValue } from '../atom/canvas.atom'
import {
CANVAS_CLRS,
getCanvasActiveClr,
getCanvasCtx,
useCanvasAtomDispatch,
useCanvasAtomValue,
} from '../atom/canvas.atom'
import useSyncedRef from './use-synced-ref'
import useCanvasHistory from './use-canvas-history'

export default function useCanvasDrawing() {
const [isDrawing, setIsDrawing] = useState(false)
const isDrawingRef = useSyncedRef(isDrawing)
const { ref, activeClr, opacity } = useCanvasAtomValue()
const atomDispatch = useCanvasAtomDispatch()
const canvasDispatch = useCanvasAtomDispatch()

const prevPointRefRef = useRef<{ x: number; y: number; left: number; top: number } | null>(null)
const currentWorkingPathRef = useRef<Array<[number, number]>>([])
Expand All @@ -22,7 +28,7 @@ export default function useCanvasDrawing() {
setIsDrawing(false)
flushSync(() => {
if (currentWorkingPathRef.current.length > 0) {
atomDispatch((atom) => {
canvasDispatch((atom) => {
atom.canvas_path_histories.push({ color: activeClr, opacity, path: currentWorkingPathRef.current })
localStorage.setItem('canvas_path_histories', JSON.stringify(atom.canvas_path_histories))
atom.canvas_path_histories = [...atom.canvas_path_histories]
Expand Down Expand Up @@ -51,9 +57,13 @@ export default function useCanvasDrawing() {
currentWorkingPathRef.current.push([startPoint.x, startPoint.y])
moveToPathRef.current.push([currentPoint.x, currentPoint.y])

const active_canvas_clr = getCanvasActiveClr()

ctx.lineJoin = 'round'
ctx.lineCap = 'round'
ctx.lineWidth = 3
ctx.strokeStyle = active_canvas_clr
ctx.fillStyle = active_canvas_clr

ctx.beginPath()
ctx.moveTo(startPoint.x, startPoint.y)
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/use-canvas-history.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useCanvasAtomValue, useCanvasHistoryIndex } from '../atom/canvas.atom'

export default function useCanvasHistory() {
const { canvas_path_histories } = useCanvasAtomValue()
const { history_index, setHistoryIndex } = useCanvasHistoryIndex()
const { history_cursor, setHistoryIndex } = useCanvasHistoryIndex()
const [pressed_keys, setPressedKeys] = useState<string[]>([])
const [clonedCanvasPath, setClonedCanvasPath] = useState(canvas_path_histories)
const canvasPathsRef = useSyncedRef(canvas_path_histories)
Expand Down Expand Up @@ -70,10 +70,10 @@ export default function useCanvasHistory() {

useEffect(() => {
setClonedCanvasPath(() => {
const arr = canvasPathsRef.current.slice(0, history_index + 1)
const arr = canvasPathsRef.current.slice(0, history_cursor + 1)
return arr
})
}, [history_index])
}, [history_cursor])

useEffect(() => {
setHistoryIndex(canvas_path_histories.length - 1)
Expand Down

0 comments on commit 0de2ed7

Please sign in to comment.