Loading packages/client/src/components/CanvasWrapper.tsx +10 −23 Original line number Diff line number Diff line Loading @@ -273,11 +273,7 @@ const CanvasInner = () => { const { config, blankOverlay, setCanvasPosition, setCursorPos } = useAppContext(); const Panel = usePanel(); const { x: templateX, y: templateY, enable: templateEnable, } = useTemplateContext(); const { enable: templateEnable } = useTemplateContext(); const PanZoom = useContext(RendererContext); const { captureCanvas, captureView, captureRegion, captureTemplateArea } = useCaptureContext(); Loading Loading @@ -475,17 +471,12 @@ const CanvasInner = () => { [canvas.current], ); const getTemplatePixel = useCallback( (x: number, y: number) => { const getTemplatePixelColor = useCallback( (clientX: number, clientY: number) => { if (!templateEnable) return; if (x < templateX || y < templateY) return; x -= templateX; y -= templateY; return TemplateCl.instance.getPixel(x, y); return TemplateCl.instance?.getPaletteColorAt(clientX, clientY); }, [templateX, templateY], [templateEnable], ); const handlePickPixel = useCallback( Loading @@ -498,19 +489,15 @@ const CanvasInner = () => { } const [x, y] = canvas.current.screenToPos(clientX, clientY); if (!isCoordInCanvas(x, y)) { const templateColor = getTemplatePixelColor(clientX, clientY); if (templateColor === undefined && !isCoordInCanvas(x, y)) { PaletteLib.setSelectedColor(undefined); showColorDeselectFeedback(clientX, clientY); return; } let pixelColor = -1; const templatePixel = getTemplatePixel(x, y); if (templatePixel) { pixelColor = PaletteLib.getColorFromHex(templatePixel.slice(1))?.id ?? -1; } let pixelColor = templateColor ?? -1; if (pixelColor === -1) { pixelColor = canvas.current.getPixel(x, y)?.color ?? -1; Loading @@ -529,7 +516,7 @@ const CanvasInner = () => { PaletteLib.getColor(pixelColor)?.hex, ); }, [canvas.current], [getTemplatePixelColor, isCoordInCanvas], ); useEffect(() => { Loading packages/client/src/components/Settings/TemplateSettings.tsx +0 −7 Original line number Diff line number Diff line Loading @@ -121,13 +121,6 @@ export const TemplateSettings = () => { <SelectItem key="SYMBOLS">Symbols</SelectItem> <SelectItem key="NUMBERS">Numbers</SelectItem> </Select> {style !== "ONE_TO_ONE" && ( <div> <b>Warning:</b> Template color picking only <br /> works with one-to-one template style </div> )} <Switch className="md:hidden" isSelected={showMobileTools} Loading packages/client/src/components/Toolbar/Palette.tsx +6 −16 Original line number Diff line number Diff line Loading @@ -337,24 +337,14 @@ export const Palette = () => { x < config.canvas.size[0] && y < config.canvas.size[1]; const getTemplatePixelColor = (x: number, y: number) => { const getTemplatePixelColor = (clientX: number, clientY: number) => { const renderer = TemplateRenderer.instance; if ( !template.enable || !renderer || template.x === undefined || template.y === undefined || x < template.x || y < template.y ) { if (!template.enable || !renderer) { return -1; } const templatePixel = renderer.getPixel(x - template.x, y - template.y); if (!templatePixel) return -1; return PaletteLib.getColorFromHex(templatePixel.slice(1))?.id ?? -1; return renderer.getPaletteColorAt(clientX, clientY) ?? -1; }; const getPickedColor = (clientX: number, clientY: number) => { Loading @@ -378,11 +368,11 @@ export const Palette = () => { return; } if (!isCoordInCanvas(x, y)) return null; const templateColor = getTemplatePixelColor(x, y); const templateColor = getTemplatePixelColor(clientX, clientY); if (templateColor !== -1) return templateColor; if (!isCoordInCanvas(x, y)) return null; const canvasColor = canvas.getPixel(x, y)?.color; if (canvasColor !== undefined && canvasColor >= 0) return canvasColor; Loading packages/client/src/lib/template.ts +19 −49 Original line number Diff line number Diff line import { type ClientConfig } from "@sc07-canvas/lib/net"; import EventEmitter from "eventemitter3"; import { rgbToHex } from "./utils"; import { WebGLUtils } from "./webgl"; export interface ITemplateState { Loading Loading @@ -196,65 +195,36 @@ export class Template extends EventEmitter<TemplateEvents> { } } getPixel(x: number, y: number): string | undefined { if (!this.context) { console.warn("[Template#getPixel] No context is available"); return undefined; } const { display: { width, height }, } = this.getDimentions(); getPaletteColorAt(clientX: number, clientY: number): number | undefined { if (!this.palettePixels) this.updatePaletteColorCounts(); const templatePixels = this.palettePixels; if (!templatePixels) return undefined; const rect = this.$wrapper.getBoundingClientRect(); const width = rect.width; const height = width * (templatePixels.height / templatePixels.width); if ( !Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0 || x < 0 || y < 0 || x >= width || y >= height clientX < rect.left || clientX >= rect.left + width || clientY < rect.top || clientY >= rect.top + height ) { return undefined; } const arr = new Uint8Array(4 * width * height); this.context.bindFramebuffer( this.context.FRAMEBUFFER, this.framebuffers.intermediate, const pixelX = Math.floor( ((clientX - rect.left) / width) * templatePixels.width, ); this.context.readPixels( 0, 0, width, height, this.context.RGBA, this.context.UNSIGNED_BYTE, arr, const pixelY = Math.floor( ((clientY - rect.top) / height) * templatePixels.height, ); this.context.bindFramebuffer( this.context.FRAMEBUFFER, this.framebuffers.main, ); const pixels = new Uint8Array(4 * width * height); const length = width * height * 4; const row = width * 4; const end = (height - 1) * row; for (let i = 0; i < length; i += row) { pixels.set(arr.subarray(i, i + row), end - i); } const [r, g, b, a] = pixels.slice( 4 * (y * width + x), 4 * (y * width + x) + 4, ); if (a === 254) return undefined; const paletteIndex = templatePixels.indexes[pixelY * templatePixels.width + pixelX]; if (paletteIndex === 254 || paletteIndex === 255) return undefined; return rgbToHex(r, g, b); return this.config.pallete.colors[paletteIndex]?.id; } getPaletteColorCounts() { Loading packages/client/src/lib/utils.ts +0 −14 Original line number Diff line number Diff line Loading @@ -21,20 +21,6 @@ export const getRenderer = (): Renderer => { Debug._getRenderer = getRenderer; export const rgbToHex = (r: number, g: number, b: number) => { function componentToHex(c: number) { const hex = c.toString(16); return hex.length === 1 ? "0" + hex : hex; } return ( "#" + componentToHex(r) + componentToHex(g) + componentToHex(b) ).toUpperCase(); }; export const oapi = createClient<RestAPI.paths>({ baseUrl: new URL("/api", window.location.origin).toString(), }); Loading Loading
packages/client/src/components/CanvasWrapper.tsx +10 −23 Original line number Diff line number Diff line Loading @@ -273,11 +273,7 @@ const CanvasInner = () => { const { config, blankOverlay, setCanvasPosition, setCursorPos } = useAppContext(); const Panel = usePanel(); const { x: templateX, y: templateY, enable: templateEnable, } = useTemplateContext(); const { enable: templateEnable } = useTemplateContext(); const PanZoom = useContext(RendererContext); const { captureCanvas, captureView, captureRegion, captureTemplateArea } = useCaptureContext(); Loading Loading @@ -475,17 +471,12 @@ const CanvasInner = () => { [canvas.current], ); const getTemplatePixel = useCallback( (x: number, y: number) => { const getTemplatePixelColor = useCallback( (clientX: number, clientY: number) => { if (!templateEnable) return; if (x < templateX || y < templateY) return; x -= templateX; y -= templateY; return TemplateCl.instance.getPixel(x, y); return TemplateCl.instance?.getPaletteColorAt(clientX, clientY); }, [templateX, templateY], [templateEnable], ); const handlePickPixel = useCallback( Loading @@ -498,19 +489,15 @@ const CanvasInner = () => { } const [x, y] = canvas.current.screenToPos(clientX, clientY); if (!isCoordInCanvas(x, y)) { const templateColor = getTemplatePixelColor(clientX, clientY); if (templateColor === undefined && !isCoordInCanvas(x, y)) { PaletteLib.setSelectedColor(undefined); showColorDeselectFeedback(clientX, clientY); return; } let pixelColor = -1; const templatePixel = getTemplatePixel(x, y); if (templatePixel) { pixelColor = PaletteLib.getColorFromHex(templatePixel.slice(1))?.id ?? -1; } let pixelColor = templateColor ?? -1; if (pixelColor === -1) { pixelColor = canvas.current.getPixel(x, y)?.color ?? -1; Loading @@ -529,7 +516,7 @@ const CanvasInner = () => { PaletteLib.getColor(pixelColor)?.hex, ); }, [canvas.current], [getTemplatePixelColor, isCoordInCanvas], ); useEffect(() => { Loading
packages/client/src/components/Settings/TemplateSettings.tsx +0 −7 Original line number Diff line number Diff line Loading @@ -121,13 +121,6 @@ export const TemplateSettings = () => { <SelectItem key="SYMBOLS">Symbols</SelectItem> <SelectItem key="NUMBERS">Numbers</SelectItem> </Select> {style !== "ONE_TO_ONE" && ( <div> <b>Warning:</b> Template color picking only <br /> works with one-to-one template style </div> )} <Switch className="md:hidden" isSelected={showMobileTools} Loading
packages/client/src/components/Toolbar/Palette.tsx +6 −16 Original line number Diff line number Diff line Loading @@ -337,24 +337,14 @@ export const Palette = () => { x < config.canvas.size[0] && y < config.canvas.size[1]; const getTemplatePixelColor = (x: number, y: number) => { const getTemplatePixelColor = (clientX: number, clientY: number) => { const renderer = TemplateRenderer.instance; if ( !template.enable || !renderer || template.x === undefined || template.y === undefined || x < template.x || y < template.y ) { if (!template.enable || !renderer) { return -1; } const templatePixel = renderer.getPixel(x - template.x, y - template.y); if (!templatePixel) return -1; return PaletteLib.getColorFromHex(templatePixel.slice(1))?.id ?? -1; return renderer.getPaletteColorAt(clientX, clientY) ?? -1; }; const getPickedColor = (clientX: number, clientY: number) => { Loading @@ -378,11 +368,11 @@ export const Palette = () => { return; } if (!isCoordInCanvas(x, y)) return null; const templateColor = getTemplatePixelColor(x, y); const templateColor = getTemplatePixelColor(clientX, clientY); if (templateColor !== -1) return templateColor; if (!isCoordInCanvas(x, y)) return null; const canvasColor = canvas.getPixel(x, y)?.color; if (canvasColor !== undefined && canvasColor >= 0) return canvasColor; Loading
packages/client/src/lib/template.ts +19 −49 Original line number Diff line number Diff line import { type ClientConfig } from "@sc07-canvas/lib/net"; import EventEmitter from "eventemitter3"; import { rgbToHex } from "./utils"; import { WebGLUtils } from "./webgl"; export interface ITemplateState { Loading Loading @@ -196,65 +195,36 @@ export class Template extends EventEmitter<TemplateEvents> { } } getPixel(x: number, y: number): string | undefined { if (!this.context) { console.warn("[Template#getPixel] No context is available"); return undefined; } const { display: { width, height }, } = this.getDimentions(); getPaletteColorAt(clientX: number, clientY: number): number | undefined { if (!this.palettePixels) this.updatePaletteColorCounts(); const templatePixels = this.palettePixels; if (!templatePixels) return undefined; const rect = this.$wrapper.getBoundingClientRect(); const width = rect.width; const height = width * (templatePixels.height / templatePixels.width); if ( !Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0 || x < 0 || y < 0 || x >= width || y >= height clientX < rect.left || clientX >= rect.left + width || clientY < rect.top || clientY >= rect.top + height ) { return undefined; } const arr = new Uint8Array(4 * width * height); this.context.bindFramebuffer( this.context.FRAMEBUFFER, this.framebuffers.intermediate, const pixelX = Math.floor( ((clientX - rect.left) / width) * templatePixels.width, ); this.context.readPixels( 0, 0, width, height, this.context.RGBA, this.context.UNSIGNED_BYTE, arr, const pixelY = Math.floor( ((clientY - rect.top) / height) * templatePixels.height, ); this.context.bindFramebuffer( this.context.FRAMEBUFFER, this.framebuffers.main, ); const pixels = new Uint8Array(4 * width * height); const length = width * height * 4; const row = width * 4; const end = (height - 1) * row; for (let i = 0; i < length; i += row) { pixels.set(arr.subarray(i, i + row), end - i); } const [r, g, b, a] = pixels.slice( 4 * (y * width + x), 4 * (y * width + x) + 4, ); if (a === 254) return undefined; const paletteIndex = templatePixels.indexes[pixelY * templatePixels.width + pixelX]; if (paletteIndex === 254 || paletteIndex === 255) return undefined; return rgbToHex(r, g, b); return this.config.pallete.colors[paletteIndex]?.id; } getPaletteColorCounts() { Loading
packages/client/src/lib/utils.ts +0 −14 Original line number Diff line number Diff line Loading @@ -21,20 +21,6 @@ export const getRenderer = (): Renderer => { Debug._getRenderer = getRenderer; export const rgbToHex = (r: number, g: number, b: number) => { function componentToHex(c: number) { const hex = c.toString(16); return hex.length === 1 ? "0" + hex : hex; } return ( "#" + componentToHex(r) + componentToHex(g) + componentToHex(b) ).toUpperCase(); }; export const oapi = createClient<RestAPI.paths>({ baseUrl: new URL("/api", window.location.origin).toString(), }); Loading