#3 型エラー対応
This commit is contained in:
@@ -17,11 +17,11 @@ type Layer = {
|
|||||||
image?: ImageItem }
|
image?: ImageItem }
|
||||||
|
|
||||||
type Line =
|
type Line =
|
||||||
| { mode: Mode.Pen | Mode.Rubber
|
| { mode: typeof Mode.Pen | typeof Mode.Rubber
|
||||||
points: number[]
|
points: number[]
|
||||||
stroke: string
|
stroke: string
|
||||||
strokeWidth: number }
|
strokeWidth: number }
|
||||||
| { mode: Mode.Paint
|
| { mode: typeof Mode.Paint
|
||||||
points: number[]
|
points: number[]
|
||||||
stroke: string,
|
stroke: string,
|
||||||
imageSrc: string }
|
imageSrc: string }
|
||||||
@@ -29,7 +29,6 @@ type Line =
|
|||||||
const Mode = {
|
const Mode = {
|
||||||
Pen: 'Pen',
|
Pen: 'Pen',
|
||||||
Rubber: 'Rubber',
|
Rubber: 'Rubber',
|
||||||
Image: 'Image',
|
|
||||||
Paint: 'Paint' } as const
|
Paint: 'Paint' } as const
|
||||||
type Mode = (typeof Mode)[keyof typeof Mode]
|
type Mode = (typeof Mode)[keyof typeof Mode]
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ const floodFill = (
|
|||||||
const start = getRGBA (data, sx, sy, W)
|
const start = getRGBA (data, sx, sy, W)
|
||||||
const visited = new Uint8Array (W * H)
|
const visited = new Uint8Array (W * H)
|
||||||
|
|
||||||
if (colourDiffMax (start, [fill.r, flil.g, fill.b, fill.a]) <= tolerance)
|
if (colourDiffMax (start, [fill.r, fill.g, fill.b, fill.a]) <= tolerance)
|
||||||
return
|
return
|
||||||
|
|
||||||
const stack: [number, number][] = [[sx, sy]]
|
const stack: [number, number][] = [[sx, sy]]
|
||||||
@@ -99,7 +98,7 @@ const getRGBA = (data: Uint8ClampedArray, x: number, y: number, w: number) => {
|
|||||||
|
|
||||||
const hexToRgba = (hex: string, alpha = 255): [number, number, number, number] => {
|
const hexToRgba = (hex: string, alpha = 255): [number, number, number, number] => {
|
||||||
const m = /^#?([0-9a-f]{6})$/i.exec (hex)
|
const m = /^#?([0-9a-f]{6})$/i.exec (hex)
|
||||||
const n = parseInt (m[1], 16)
|
const n = parseInt (m![1], 16)
|
||||||
return [(n >> 16) & 255, (n >> 8) & 255, n & 255, alpha]
|
return [(n >> 16) & 255, (n >> 8) & 255, n & 255, alpha]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,21 +109,10 @@ const isLayer = (obj: unknown): obj is Layer => (
|
|||||||
&& typeof (obj as Layer).id === 'string'
|
&& typeof (obj as Layer).id === 'string'
|
||||||
&& typeof (obj as Layer).name === 'string'
|
&& typeof (obj as Layer).name === 'string'
|
||||||
&& Array.isArray ((obj as Layer).lines)
|
&& Array.isArray ((obj as Layer).lines)
|
||||||
&& (obj as Layer).lines.every (isLine)
|
|
||||||
&& Array.isArray ((obj as Layer).history)
|
&& Array.isArray ((obj as Layer).history)
|
||||||
&& Array.isArray ((obj as Layer).future))
|
&& Array.isArray ((obj as Layer).future))
|
||||||
|
|
||||||
|
|
||||||
const isLine = (obj: unknown): obj is Line => (
|
|
||||||
typeof obj === 'object'
|
|
||||||
&& obj !== null
|
|
||||||
&& Array.isArray ((obj as Line).points)
|
|
||||||
&& (obj as Line).points.every (n => typeof n === 'number')
|
|
||||||
&& typeof (obj as Line).stroke === 'string'
|
|
||||||
&& typeof (obj as Line).strokeWidth === 'number'
|
|
||||||
&& Object.values (Mode).includes ((obj as Line).mode))
|
|
||||||
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const drawingRef = useRef (false)
|
const drawingRef = useRef (false)
|
||||||
const fileInputRef = useRef<HTMLInputElement> (null)
|
const fileInputRef = useRef<HTMLInputElement> (null)
|
||||||
@@ -143,7 +131,7 @@ export default () => {
|
|||||||
const activeLayer = layers.find (l => l.id === activeLayerId)
|
const activeLayer = layers.find (l => l.id === activeLayerId)
|
||||||
|
|
||||||
const handleMouseDown = (ev: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {
|
const handleMouseDown = (ev: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {
|
||||||
if (!(activeLayer))
|
if (!(activeLayer) || (mode !== Mode.Pen && mode !== Mode.Rubber))
|
||||||
return
|
return
|
||||||
|
|
||||||
drawingRef.current = true
|
drawingRef.current = true
|
||||||
@@ -222,7 +210,7 @@ export default () => {
|
|||||||
fileInputRef.current.value = ''
|
fileInputRef.current.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePaint = async (ev: Konva.KonvaEventObject<MouseEvent | TouchEvent>) => {
|
const handlePaint = async () => {
|
||||||
const layer = activeLayer
|
const layer = activeLayer
|
||||||
if (!(layer) || !(stageRef.current))
|
if (!(layer) || !(stageRef.current))
|
||||||
return
|
return
|
||||||
@@ -245,14 +233,13 @@ export default () => {
|
|||||||
$off.width = stageWidth
|
$off.width = stageWidth
|
||||||
$off.height = stageHeight
|
$off.height = stageHeight
|
||||||
const ctx = $off.getContext ('2d')
|
const ctx = $off.getContext ('2d')
|
||||||
ctx.drawImage (img, 0, 0, stageWidth, stageHeight)
|
ctx!.drawImage (img, 0, 0, stageWidth, stageHeight)
|
||||||
|
|
||||||
const imgData = ctx.getImageData (0, 0, stageWidth, stageHeight)
|
const imgData = ctx!.getImageData (0, 0, stageWidth, stageHeight)
|
||||||
const [r, g, b, a] = hexToRgba (colour, 255)
|
const [r, g, b, a] = hexToRgba (colour, 255)
|
||||||
floodFill (imgData, Math.floor (pos.x), Math.floor (pos.y), { r, g, b, a })
|
floodFill (imgData, Math.floor (pos.x), Math.floor (pos.y), { r, g, b, a })
|
||||||
ctx.putImageData (imgData, 0, 0)
|
ctx!.putImageData (imgData, 0, 0)
|
||||||
|
|
||||||
const prevImageSrc = layer.image?.src
|
|
||||||
const nextSrc = $off.toDataURL ('image/png')
|
const nextSrc = $off.toDataURL ('image/png')
|
||||||
|
|
||||||
updateActiveLayerHistory ([...layer.history, layer.lines])
|
updateActiveLayerHistory ([...layer.history, layer.lines])
|
||||||
@@ -347,11 +334,7 @@ export default () => {
|
|||||||
if (!(Array.isArray (parsed)))
|
if (!(Array.isArray (parsed)))
|
||||||
throw new Error
|
throw new Error
|
||||||
|
|
||||||
const restored: Layer[] = parsed.filter (isLayer).map (l => ({
|
const restored: Layer[] = parsed.filter (isLayer)
|
||||||
...l, lines: l.lines.map (s => ({
|
|
||||||
...s, mode: (Object.values (Mode).includes (s.mode)
|
|
||||||
? s.mode
|
|
||||||
: Mode.Pen) })) }))
|
|
||||||
if (restored.length === 0)
|
if (restored.length === 0)
|
||||||
throw new Error
|
throw new Error
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user