Skip to content

Commit

Permalink
feat: paint alpha input
Browse files Browse the repository at this point in the history
  • Loading branch information
F-star committed Nov 22, 2024
1 parent 334756f commit f592710
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export const ElementsInfoCards: FC = () => {
<NumAttrInput
{...item}
key={item.key}
onBlur={(newVal) => {
onChange={(newVal) => {
execCommand(item.key, newVal);
}}
/>
Expand All @@ -120,7 +120,7 @@ export const ElementsInfoCards: FC = () => {
<NumAttrInput
{...item}
key={item.key}
onBlur={(newVal) => {
onChange={(newVal) => {
execCommand(item.key, newVal);
}}
/>
Expand All @@ -131,7 +131,7 @@ export const ElementsInfoCards: FC = () => {
<NumAttrInput
{...item}
key={item.key}
onBlur={(newVal) => {
onChange={(newVal) => {
execCommand(item.key, newVal);
}}
/>
Expand All @@ -143,7 +143,7 @@ export const ElementsInfoCards: FC = () => {
<NumAttrInput
{...item}
key={item.key}
onBlur={(newVal) => {
onChange={(newVal) => {
execCommand(item.key, newVal);
}}
/>
Expand All @@ -159,7 +159,7 @@ const NumAttrInput: FC<{
min?: number;
max?: number;
value: string | number;
onBlur: (newValue: number) => void;
onChange: (newValue: number) => void;
suffixValue?: string;
uiType: string;
}> = (props) => {
Expand All @@ -170,7 +170,7 @@ const NumAttrInput: FC<{
value={props.value}
min={props.min}
max={props.max}
onBlur={props.onBlur}
onChange={props.onChange}
/>
);
} else {
Expand All @@ -180,7 +180,7 @@ const NumAttrInput: FC<{
value={props.value}
min={props.min}
max={props.max}
onBlur={props.onBlur}
onChange={props.onChange}
suffixValue={props.suffixValue}
/>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const LayerInfoCard: FC = () => {
value={opacity}
min={0}
max={1}
onBlur={recordOpacityChange}
onChange={recordOpacityChange}
/>
</div>
</BaseCard>
Expand Down
16 changes: 16 additions & 0 deletions packages/suika/src/components/Cards/PaintCard/PaintCard.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@
justify-content: space-between;
align-items: center;
margin: 0 8px;

.fill-item-left {
display: flex;
align-items: center;

.suika-custom-ruler-input-box {
margin-right: 0;
}

.paint-card-alpha-input {
width: 45px;
margin-left: 0;
padding-left: 4px;
}
}

.color-block {
margin: 8px 4px 8px 7px;
width: 16px;
Expand Down
80 changes: 51 additions & 29 deletions packages/suika/src/components/Cards/PaintCard/PaintCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { type FC, useState } from 'react';

import { PaintPicker } from '../../ColorPicker/PaintPicker';
import { ColorHexInput } from '../../input/ColorHexInput';
import { PercentInput } from '../../input/PercentInput';
import { BaseCard } from '../BaseCard';

const isNearWhite = (rgba: IRGBA, threshold = 85) => {
Expand Down Expand Up @@ -112,37 +113,58 @@ export const PaintCard: FC<IProps> = ({
if (paint.type === PaintType.Solid) {
return (
<div className="fill-item" key={index}>
<ColorHexInput
prefix={
<div
className="color-block"
style={{
backgroundColor: parseRGBAStr(paint.attrs),
boxShadow: isNearWhite(paint.attrs)
? '0 0 0 1px rgba(0,0,0,0.1) inset'
: undefined,
}}
onMouseDown={() => {
setActiveIndex(index);
}}
/>
}
value={parseRGBToHex(paint.attrs)}
onBlur={(newHex) => {
const rgb = parseHexToRGB(newHex);
<div className="fill-item-left">
<ColorHexInput
prefix={
<div
className="color-block"
style={{
backgroundColor: parseRGBAStr(paint.attrs),
boxShadow: isNearWhite(paint.attrs)
? '0 0 0 1px rgba(0,0,0,0.1) inset'
: undefined,
}}
onMouseDown={() => {
setActiveIndex(index);
}}
/>
}
value={parseRGBToHex(paint.attrs)}
onChange={(newHex) => {
const rgb = parseHexToRGB(newHex);

if (rgb) {
const newSolidPaint: PaintSolid = {
type: PaintType.Solid,
attrs: {
...rgb,
a: paint.attrs.a,
if (rgb) {
const newSolidPaint: PaintSolid = {
type: PaintType.Solid,
attrs: {
...rgb,
a: paint.attrs.a,
},
};
onChangeComplete(newSolidPaint, index);
}
}}
/>
{/* alpha input */}
<PercentInput
classNames={['paint-card-alpha-input']}
value={paint.attrs.a}
min={0}
max={1}
onChange={(val) => {
onChangeComplete(
{
...paint,
attrs: {
...paint.attrs,
a: val,
},
},
};
onChangeComplete(newSolidPaint, index);
}
}}
/>
index,
);
}}
/>
</div>
<IconButton onClick={() => onDelete(index)}>
<RemoveOutlined />
</IconButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export const StrokeCard: FC = () => {
}
value={strokeWidth}
min={0}
onBlur={updateStrokeWidth}
onChange={updateStrokeWidth}
/>
</div>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
border-radius: 4px;
background-color: #fff;

box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.08), 0px 10px 24px rgba(0, 0, 0, 0.18),
0px 2px 5px rgba(0, 0, 0, 0.15), 0px 2px 14px rgba(0, 0, 0, 0.15),
0px 0px 0px 0.5px rgba(0, 0, 0, 0.2);
// box-shadow: 0px 0px 1px rgba(0, 0, 0, 0.08), 0px 10px 24px rgba(0, 0, 0, 0.18),
// 0px 2px 5px rgba(0, 0, 0, 0.15), 0px 2px 14px rgba(0, 0, 0, 0.15),
// 0px 0px 0px 0.5px rgba(0, 0, 0, 0.2);

.sketch-picker {
box-shadow: none !important;
Expand Down
6 changes: 3 additions & 3 deletions packages/suika/src/components/input/ColorHexInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import CustomRuleInput from './CustomRuleInput';

interface IProps {
value: string;
onBlur: (newValue: string) => void;
onChange: (newValue: string) => void;
prefix?: React.ReactNode;
}

export const ColorHexInput: FC<IProps> = ({ value, onBlur, prefix }) => {
export const ColorHexInput: FC<IProps> = ({ value, onChange, prefix }) => {
const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
Expand All @@ -31,7 +31,7 @@ export const ColorHexInput: FC<IProps> = ({ value, onBlur, prefix }) => {
return str;
}}
value={value}
onBlur={(newVal) => onBlur(newVal)}
onChange={(newVal) => onChange(newVal)}
/>
);
};
18 changes: 9 additions & 9 deletions packages/suika/src/components/input/CustomRuleInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
import './style.scss';

import classNames from 'classnames';
import React, { type FC, useEffect, useRef } from 'react';

interface ICustomRuleInputProps {
parser: (newValue: string, preValue: string | number) => string | false;
value: string | number;
onBlur: (newValue: string) => void;
onChange: (newValue: string) => void;
prefix?: React.ReactNode;
classNames?: string[];
}

const CustomRuleInput: FC<ICustomRuleInputProps> = ({
value,
onBlur,
parser,
prefix,
}) => {
const CustomRuleInput: FC<ICustomRuleInputProps> = (props) => {
const { value, onChange, parser, prefix } = props;
const inputRef = useRef<HTMLInputElement>(null);
const isActive = useRef(false);

Expand All @@ -25,7 +23,9 @@ const CustomRuleInput: FC<ICustomRuleInputProps> = ({
}, [value]);

return (
<div className="suika-custom-ruler-input-box">
<div
className={classNames('suika-custom-ruler-input-box', props.classNames)}
>
{prefix && <div className="suika-custom-input-prefix">{prefix}</div>}
<input
ref={inputRef}
Expand All @@ -52,7 +52,7 @@ const CustomRuleInput: FC<ICustomRuleInputProps> = ({
const newValue = parser(str, value);
if (newValue !== false) {
e.target.value = String(newValue);
onBlur(newValue);
onChange(newValue);
} else {
e.target.value = String(value);
}
Expand Down
25 changes: 15 additions & 10 deletions packages/suika/src/components/input/NumberInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,24 @@ interface INumberInputProps {
value: string | number;
min?: number;
max?: number;
onBlur: (newValue: number) => void;
onChange: (newValue: number) => void;
prefix?: React.ReactNode;
/** suffix string after input value, such like ° => 12.34° */
suffixValue?: string;
classNames?: string[];
}

const NumberInput: FC<INumberInputProps> = ({
value,
min = -Infinity,
max = Infinity,
onBlur,
prefix,
suffixValue = '',
}) => {
const NumberInput: FC<INumberInputProps> = (props) => {
const {
value,
min = -Infinity,
max = Infinity,
onChange,
prefix,
suffixValue = '',
classNames,
} = props;

const inputRef = useRef<HTMLInputElement>(null);

useEffect(() => {
Expand Down Expand Up @@ -52,7 +56,8 @@ const NumberInput: FC<INumberInputProps> = ({
}
}}
value={isNumberStr(String(value)) ? value + suffixValue : value}
onBlur={(newVal) => onBlur(Number(newVal))}
classNames={classNames}
onChange={(newVal) => onChange(Number(newVal))}
/>
);
};
Expand Down
8 changes: 5 additions & 3 deletions packages/suika/src/components/input/PercentInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ interface Props {
value: string | number;
min?: number;
max?: number;
onBlur: (value: number) => void;
onChange: (value: number) => void;
classNames?: string[];
}

export const PercentInput: FC<Props> = (props) => {
const value =
typeof props.value === 'number'
? Number((props.value * 100).toFixed(2))
: props.value;
const onBlur = (value: number) => props.onBlur(value / 100);
const onChange = (value: number) => props.onChange(value / 100);

const min = props.min === undefined ? undefined : props.min * 100;
const max = props.max === undefined ? undefined : props.max * 100;
Expand All @@ -26,8 +27,9 @@ export const PercentInput: FC<Props> = (props) => {
min={min}
max={max}
suffixValue="%"
onBlur={onBlur}
onChange={onChange}
prefix={props.prefix}
classNames={props.classNames}
/>
);
};

0 comments on commit f592710

Please sign in to comment.