Skip to content

Commit

Permalink
🐛 fix: 修正当 S或V 为 0 时 hue 变成 NaN 的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Apr 6, 2022
1 parent 9915f0c commit 40e3594
Show file tree
Hide file tree
Showing 23 changed files with 687 additions and 1,033 deletions.
75 changes: 75 additions & 0 deletions packages/color-picker/src/components/Alpha/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import type { FC } from 'react';
import React, { memo, useEffect, useMemo, useRef } from 'react';

import isEqual from 'lodash/isEqual';
import { concatMap, map, takeUntil } from 'rxjs/operators';

import Checkboard from '../common/Checkboard';
import { colorSelector, useStore } from '../../store';

import styles from './style.less';
import { fromEvent, Subject } from 'rxjs';

const Alpha: FC = memo(() => {
const { rgb } = useStore(colorSelector, isEqual);
const updateAlpha = useStore((s) => s.updateAlpha);

const ctnRef = useRef(null);

const mouseDown$ = useMemo(() => new Subject(), []);

const bindingStart = (e) => {
mouseDown$.next(e);
};

useEffect(() => {
mouseDown$
.pipe(
concatMap(() =>
fromEvent<MouseEvent>(window, 'mousemove').pipe(takeUntil(fromEvent(window, 'mouseup'))),
),
map((e: any) => (typeof e.pageX === 'number' ? e.pageX : e.touches[0].pageX) as number),
)
.subscribe((value) => {
const container = ctnRef.current;
const containerWidth = container.clientWidth;

const left = value - (container.getBoundingClientRect().left + window.pageXOffset);

updateAlpha(Math.round((left * 100) / containerWidth));
});
}, []);

return (
<div className={styles.wrapper}>
<div className={styles.checkboard}>
<Checkboard />
</div>
<div
className={styles.background}
style={{
background: `linear-gradient(to right, rgba(${rgb.r},${rgb.g},${rgb.b}, 0) 0%,
rgba(${rgb.r},${rgb.g},${rgb.b}, 1) 100%)`,
}}
/>
<div
className={styles.container}
ref={ctnRef}
onMouseDown={bindingStart}
onTouchMove={bindingStart}
onTouchStart={bindingStart}
>
<div
style={{
position: 'absolute',
left: `${rgb.a * 100}%`,
}}
>
<div className={styles.slider} />
</div>
</div>
</div>
);
});

export default Alpha;
39 changes: 39 additions & 0 deletions packages/color-picker/src/components/Alpha/style.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.abs {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

.wrapper {
.abs;
border-radius: 2px;
}

.checkboard {
.abs;
overflow: hidden;
border-radius: 2px;
}
.background {
.abs;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.15), inset 0 0 4px rgba(0, 0, 0, 0.25);
border-radius: 2px;
}

.container {
position: relative;
height: 100%;
margin: 0 3px;
}

.slider {
width: 4px;
height: 8px;
margin-top: 1px;
background: #fff;
border-radius: 1px;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
transform: translateX(-2px);
}
10 changes: 9 additions & 1 deletion packages/color-picker/src/components/EditableInput/index.less
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
.avx-color-fields-input {
width: 100%;
padding: 2px 3px;
color: rgba(0, 0, 0, 0.85);
font-size: 12px;
background: #f0f0f0;
border: none;
border-radius: 4px;
box-shadow: inset 0 0 0 1px #ccc;
box-shadow: inset 0 0 0 1px #ebebeb;

transition: all 100ms ease-in-out;
&:hover,
&:focus-visible {
background: #fafafa;
}
}
19 changes: 14 additions & 5 deletions packages/color-picker/src/components/EditableInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { CSSProperties, FC } from 'react';
import React from 'react';
import React, { useEffect, useState } from 'react';
import cls from 'classnames';

import './index.less';
Expand All @@ -13,14 +13,23 @@ export interface EditableInputProps {
}

const EditableInput: FC<EditableInputProps> = ({ value, style, className, onChange }) => {
const [internalValue, setValue] = useState<string | number>();

useEffect(() => {
setValue(value);
}, [value]);

const handleBlur = () => {
onChange(internalValue);
};

return (
<input
className={cls('avx-color-fields-input', className)}
value={value}
value={internalValue}
// onKeyDown={this.handleKeyDown}
// onChange={this.handleChange}
onChange={onChange}
// onBlur={this.handleBlur}
onChange={(e) => setValue(e.target.value)}
onBlur={handleBlur}
spellCheck="false"
style={style}
/>
Expand Down
97 changes: 97 additions & 0 deletions packages/color-picker/src/components/Hue/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { FC } from 'react';
import React, { memo, useEffect, useMemo, useRef } from 'react';
import reactCSS from 'reactcss';

import { fromEvent, Subject } from 'rxjs';
import { concatMap, map, takeUntil } from 'rxjs/operators';

import { useStore } from '../../store';

import './style.less';

const Hue: FC = memo(() => {
const hue = useStore((s) => s.hue);

const updateHue = useStore((s) => s.updateHue);

const ctnRef = useRef(null);

const mouseDown$ = useMemo(() => new Subject(), []);

const bindingStart = (e) => {
mouseDown$.next(e);
};

useEffect(() => {
mouseDown$
.pipe(
concatMap(() =>
fromEvent<MouseEvent>(window, 'mousemove').pipe(takeUntil(fromEvent(window, 'mouseup'))),
),
map((e: any) => (typeof e.pageX === 'number' ? e.pageX : e.touches[0].pageX) as number),
)
.subscribe((value) => {
const container = ctnRef.current;
const containerWidth = container.clientWidth;

const left = value - (container.getBoundingClientRect().left + window.pageXOffset);

const percent = (left * 100) / containerWidth;

updateHue(Math.round((percent / 100) * 360));
});
}, []);

const styles = reactCSS({
default: {
hue: {
// @ts-ignore
absolute: '0px 0px 0px 0px',
borderRadius: 2,
boxShadow: 'inset 0 0 0 1px rgba(0,0,0,.15), inset 0 0 4px rgba(0,0,0,.25)',
},
container: {
padding: '0 2px',
position: 'relative',
height: '100%',
borderRadius: 2,
},
pointer: {
position: 'absolute',
left: `${(hue / 360) * 100}%`,
},
slider: {
marginTop: '1px',
width: '4px',
borderRadius: '1px',
height: '8px',
boxShadow: '0 0 2px rgba(0, 0, 0, .6)',
background: '#fff',
transform: 'translateX(-2px)',
},
},
});

return (
<div style={styles.hue}>
<div
className={'hue-horizontal'}
// @ts-ignore
style={styles.container}
ref={ctnRef}
onMouseDown={bindingStart}
onTouchMove={bindingStart}
onTouchStart={bindingStart}
>
<div
// @ts-ignore
style={styles.pointer}
>
<div style={styles.slider} />
</div>
</div>
</div>
);
});

export default Hue;
22 changes: 22 additions & 0 deletions packages/color-picker/src/components/Hue/style.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.hue-horizontal {
background: linear-gradient(
to right,
#f00 0%,
#ff0 17%,
#0f0 33%,
#0ff 50%,
#00f 67%,
#f0f 83%,
#f00 100%
);
background: -webkit-linear-gradient(
to right,
#f00 0%,
#ff0 17%,
#0f0 33%,
#0ff 50%,
#00f 67%,
#f0f 83%,
#f00 100%
);
}
Loading

0 comments on commit 40e3594

Please sign in to comment.