fix: several eyeDropper fixes (#7002)

This commit is contained in:
David Luzar 2023-09-17 13:24:50 +02:00 committed by GitHub
parent 1f94f204dd
commit c1952fd6cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 51 additions and 27 deletions

View File

@ -15,9 +15,15 @@ interface ColorInputProps {
color: string;
onChange: (color: string) => void;
label: string;
eyeDropperType: "strokeColor" | "backgroundColor";
}
export const ColorInput = ({ color, onChange, label }: ColorInputProps) => {
export const ColorInput = ({
color,
onChange,
label,
eyeDropperType,
}: ColorInputProps) => {
const device = useDevice();
const [innerValue, setInnerValue] = useState(color);
const [activeSection, setActiveColorPickerSection] = useAtom(
@ -110,6 +116,7 @@ export const ColorInput = ({ color, onChange, label }: ColorInputProps) => {
: {
keepOpenOnAlt: false,
onSelect: (color) => onChange(color),
previewType: eyeDropperType,
},
)
}

View File

@ -82,7 +82,14 @@ const ColorPickerPopupContent = ({
const { container } = useExcalidrawContainer();
const { isMobile, isLandscape } = useDevice();
const colorInputJSX = (
const eyeDropperType =
type === "canvasBackground"
? undefined
: type === "elementBackground"
? "backgroundColor"
: "strokeColor";
const colorInputJSX = eyeDropperType && (
<div>
<PickerHeading>{t("colorPicker.hexCode")}</PickerHeading>
<ColorInput
@ -91,6 +98,7 @@ const ColorPickerPopupContent = ({
onChange={(color) => {
onChange(color);
}}
eyeDropperType={eyeDropperType}
/>
</div>
);
@ -140,7 +148,7 @@ const ColorPickerPopupContent = ({
alignOffset={-16}
sideOffset={20}
style={{
zIndex: 9999,
zIndex: "var(--zIndex-layerUI)",
backgroundColor: "var(--popup-bg-color)",
maxWidth: "208px",
maxHeight: window.innerHeight,
@ -152,7 +160,7 @@ const ColorPickerPopupContent = ({
"0px 7px 14px rgba(0, 0, 0, 0.05), 0px 0px 3.12708px rgba(0, 0, 0, 0.0798), 0px 0px 0.931014px rgba(0, 0, 0, 0.1702)",
}}
>
{palette ? (
{palette && eyeDropperType ? (
<Picker
palette={palette}
color={color}
@ -165,6 +173,7 @@ const ColorPickerPopupContent = ({
state = state || {
keepOpenOnAlt: true,
onSelect: onChange,
previewType: eyeDropperType,
};
state.keepOpenOnAlt = true;
return state;
@ -175,6 +184,7 @@ const ColorPickerPopupContent = ({
: {
keepOpenOnAlt: false,
onSelect: onChange,
previewType: eyeDropperType,
};
});
}}

View File

@ -4,7 +4,7 @@
position: absolute;
width: 100%;
height: 100%;
z-index: 2;
z-index: var(--zIndex-eyeDropperBackdrop);
touch-action: none;
}
@ -21,7 +21,7 @@
width: 3rem;
height: 3rem;
position: fixed;
z-index: 999999;
z-index: var(--zIndex-eyeDropperPreview);
border-radius: 1rem;
border: 1px solid var(--default-border-color);
filter: var(--theme-filter);

View File

@ -1,7 +1,7 @@
import { atom } from "jotai";
import { useEffect, useRef } from "react";
import { createPortal } from "react-dom";
import { COLOR_PALETTE, rgbToHex } from "../colors";
import { rgbToHex } from "../colors";
import { EVENT } from "../constants";
import { useUIAppState } from "../context/ui-appState";
import { mutateElement } from "../element/mutateElement";
@ -18,8 +18,8 @@ import "./EyeDropper.scss";
type EyeDropperProperties = {
keepOpenOnAlt: boolean;
swapPreviewOnAlt?: boolean;
onSelect?: (color: string, event: PointerEvent) => void;
previewType?: "strokeColor" | "backgroundColor";
onSelect: (color: string, event: PointerEvent) => void;
previewType: "strokeColor" | "backgroundColor";
};
export const activeEyeDropperAtom = atom<null | EyeDropperProperties>(null);
@ -28,13 +28,8 @@ export const EyeDropper: React.FC<{
onCancel: () => void;
onSelect: Required<EyeDropperProperties>["onSelect"];
swapPreviewOnAlt?: EyeDropperProperties["swapPreviewOnAlt"];
previewType?: EyeDropperProperties["previewType"];
}> = ({
onCancel,
onSelect,
swapPreviewOnAlt,
previewType = "backgroundColor",
}) => {
previewType: EyeDropperProperties["previewType"];
}> = ({ onCancel, onSelect, swapPreviewOnAlt, previewType }) => {
const eyeDropperContainer = useCreatePortalContainer({
className: "excalidraw-eye-dropper-backdrop",
parentSelector: ".excalidraw-eye-dropper-container",
@ -58,11 +53,27 @@ export const EyeDropper: React.FC<{
return;
}
let currentColor: string = COLOR_PALETTE.black;
let isHoldingPointerDown = false;
const ctx = app.canvas.getContext("2d")!;
const getCurrentColor = ({
clientX,
clientY,
}: {
clientX: number;
clientY: number;
}) => {
const pixel = ctx.getImageData(
(clientX - appState.offsetLeft) * window.devicePixelRatio,
(clientY - appState.offsetTop) * window.devicePixelRatio,
1,
1,
).data;
return rgbToHex(pixel[0], pixel[1], pixel[2]);
};
const mouseMoveListener = ({
clientX,
clientY,
@ -76,14 +87,7 @@ export const EyeDropper: React.FC<{
colorPreviewDiv.style.top = `${clientY + 20}px`;
colorPreviewDiv.style.left = `${clientX + 20}px`;
const pixel = ctx.getImageData(
(clientX - appState.offsetLeft) * window.devicePixelRatio,
(clientY - appState.offsetTop) * window.devicePixelRatio,
1,
1,
).data;
currentColor = rgbToHex(pixel[0], pixel[1], pixel[2]);
const currentColor = getCurrentColor({ clientX, clientY });
if (isHoldingPointerDown) {
for (const element of metaStuffRef.current.selectedElements) {
@ -125,7 +129,7 @@ export const EyeDropper: React.FC<{
event.stopImmediatePropagation();
event.preventDefault();
onSelect(currentColor, event);
onSelect(getCurrentColor(event), event);
};
const keyDownListener = (event: KeyboardEvent) => {

View File

@ -6,6 +6,8 @@
--zIndex-interactiveCanvas: 2;
--zIndex-wysiwyg: 3;
--zIndex-layerUI: 4;
--zIndex-eyeDropperBackdrop: 5;
--zIndex-eyeDropperPreview: 6;
--zIndex-modal: 1000;
--zIndex-popup: 1001;

View File

@ -507,8 +507,9 @@ export type AppProps = Merge<
* in the app, eg Manager. Factored out into a separate type to keep DRY. */
export type AppClassProperties = {
props: AppProps;
canvas: HTMLCanvasElement;
interactiveCanvas: HTMLCanvasElement | null;
/** static canvas */
canvas: HTMLCanvasElement;
focusContainer(): void;
library: Library;
imageCache: Map<