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 colors from "../colors";
const normalizeColor = (
color: string,
canvasContext: CanvasRenderingContext2D,
): string | null => {
// 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
// Excalidraw-invalid value to detect successful normalizations.
function isValidColor(color: string) {
const style = new Option().style;
style.color = color;
return !!style.color;
}
const getColor = (color: string): string | null => {
if (color === "transparent") {
return color;
}
const defaultColor = "rgba(0,0,0,0)";
canvasContext.fillStyle = defaultColor;
canvasContext.fillStyle = color;
const hexColor = canvasContext.fillStyle;
return hexColor.startsWith("#") ? hexColor : null;
return isValidColor(color)
? color
: isValidColor(`#${color}`)
? `#${color}`
: null;
};
// 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 inputRef = React.useRef(null);
const canvasContext = React.useRef<CanvasRenderingContext2D>(
document.createElement("canvas").getContext("2d"),
);
React.useEffect(() => {
setInnerValue(color);
@ -213,15 +209,13 @@ const ColorInput = React.forwardRef(
const changeColor = React.useCallback(
(inputValue: string) => {
const value = inputValue.toLowerCase();
if (canvasContext.current) {
const normalizedValue = normalizeColor(value, canvasContext.current);
if (normalizedValue) {
onChange(normalizedValue);
}
const color = getColor(value);
if (color) {
onChange(color);
}
setInnerValue(value);
},
[canvasContext, onChange, setInnerValue],
[onChange],
);
return (
@ -233,7 +227,6 @@ const ColorInput = React.forwardRef(
aria-label={label}
onChange={(event) => changeColor(event.target.value)}
value={(innerValue || "").replace(/^#/, "")}
onPaste={(event) => changeColor(event.clipboardData.getData("text"))}
onBlur={() => setInnerValue(color)}
ref={inputRef}
/>

View File

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