rewrite picker color handling (#1487)

This commit is contained in:
David Luzar 2020-04-25 23:06:16 +02:00 committed by GitHub
parent a4b49ea350
commit 2c5c770e78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 25 deletions

View File

@ -7,23 +7,22 @@ import { t, getLanguage } from "../i18n";
import { isWritableElement } from "../utils"; import { isWritableElement } from "../utils";
import colors from "../colors"; import colors from "../colors";
const normalizeColor = ( function isValidColor(color: string) {
color: string, const style = new Option().style;
canvasContext: CanvasRenderingContext2D, style.color = color;
): string | null => { return !!style.color;
// Excalidraw only supports "transparent" as a valid transparent value. }
// Default canvas fill style value is `#000000`, which is also a valid
// Excalidraw color. Let's set it to another Canvas-valid but const getColor = (color: string): string | null => {
// Excalidraw-invalid value to detect successful normalizations.
if (color === "transparent") { if (color === "transparent") {
return color; return color;
} }
const defaultColor = "rgba(0,0,0,0)"; return isValidColor(color)
canvasContext.fillStyle = defaultColor; ? color
canvasContext.fillStyle = color; : isValidColor(`#${color}`)
const hexColor = canvasContext.fillStyle; ? `#${color}`
return hexColor.startsWith("#") ? hexColor : null; : null;
}; };
// This is a narrow reimplementation of the awesome react-color Twitter component // This is a narrow reimplementation of the awesome react-color Twitter component
@ -200,9 +199,6 @@ const ColorInput = React.forwardRef(
) => { ) => {
const [innerValue, setInnerValue] = React.useState(color); const [innerValue, setInnerValue] = React.useState(color);
const inputRef = React.useRef(null); const inputRef = React.useRef(null);
const canvasContext = React.useRef<CanvasRenderingContext2D>(
document.createElement("canvas").getContext("2d"),
);
React.useEffect(() => { React.useEffect(() => {
setInnerValue(color); setInnerValue(color);
@ -213,15 +209,13 @@ const ColorInput = React.forwardRef(
const changeColor = React.useCallback( const changeColor = React.useCallback(
(inputValue: string) => { (inputValue: string) => {
const value = inputValue.toLowerCase(); const value = inputValue.toLowerCase();
if (canvasContext.current) { const color = getColor(value);
const normalizedValue = normalizeColor(value, canvasContext.current); if (color) {
if (normalizedValue) { onChange(color);
onChange(normalizedValue);
}
} }
setInnerValue(value); setInnerValue(value);
}, },
[canvasContext, onChange, setInnerValue], [onChange],
); );
return ( return (
@ -233,7 +227,6 @@ const ColorInput = React.forwardRef(
aria-label={label} aria-label={label}
onChange={(event) => changeColor(event.target.value)} onChange={(event) => changeColor(event.target.value)}
value={(innerValue || "").replace(/^#/, "")} value={(innerValue || "").replace(/^#/, "")}
onPaste={(event) => changeColor(event.clipboardData.getData("text"))}
onBlur={() => setInnerValue(color)} onBlur={() => setInnerValue(color)}
ref={inputRef} ref={inputRef}
/> />

View File

@ -114,8 +114,9 @@ export function renderScene(
if (typeof sceneState.viewBackgroundColor === "string") { if (typeof sceneState.viewBackgroundColor === "string") {
const hasTransparence = const hasTransparence =
sceneState.viewBackgroundColor === "transparent" || sceneState.viewBackgroundColor === "transparent" ||
sceneState.viewBackgroundColor.length === 5 || sceneState.viewBackgroundColor.length === 5 || // #RGBA
sceneState.viewBackgroundColor.length === 9; sceneState.viewBackgroundColor.length === 9 || // #RRGGBBA
/(hsla|rgba)\(/.test(sceneState.viewBackgroundColor);
if (hasTransparence) { if (hasTransparence) {
context.clearRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight); context.clearRect(0, 0, normalizedCanvasWidth, normalizedCanvasHeight);
} }