Compute

compute 代表着一个衍生状态。衍生状态可以通过一个纯函数来计算出一个新的状态。

通过compute计算衍生状态#

通过compute()方法来建立一个计算节点,计算节点需要一个唯一的id,并且可以设置get 和 set的纯函数。

get函数中可以通过get方法获取atom节点或者其他compute节点的数据。这里通过get函数获取ColorAtom中的配置的颜色,并计算相反的颜色, 让文字的展示颜色可以快速的根据背景颜色进行变化。

const ColorAtom = atom({
id: 'color',
defaultValue: 'rgba(255,255,255,1)',
});
const ContrastColor= compute({
id: 'contrast-color',
get: ({ get }) => {
const color = get(ColorAtom);
const rgba = color.replace(/[rgba\(\)]/g, '').split(',');
const colorContrast = `rgba(${[
...rgba
.slice(0, 3)
.map(item => (255 - Number(item))),
rgba[3],
].join(',')})`
return colorContrast;
},
});

AtomBgControlSample

The fallback content to display on prerendering
import React from 'react';
import {
atom,
compute,
RdxContext,
useRdxSetter,
useRdxState,
useRdxValue,
} from '@alife/rdx';
import { SketchPicker } from 'react-color';
const ColorAtom = atom({
id: 'color',
defaultValue: 'rgba(255,255,255,1)',
});
const ContrastColor = compute({
id: 'contrast-color',
get: ({ get }) => {
const color = get(ColorAtom);
const rgba = color.replace(/[rgba\(\)]/g, '').split(',');
const colorContrast = `rgba(${[
...rgba.slice(0, 3).map((item) => 255 - Number(item)),
rgba[3],
].join(',')})`;
return colorContrast;
},
});
const HighLightColor = compute({
id: 'highlight-color',
get: ({ get }) => {
const color = get(ColorAtom);
const rgba = color.replace(/[rgba?\(\)]/g, '').split(',');
// https://juejin.im/post/6844903960487149582
return 0.213 * Number(rgba[0]) +
0.715 * Number(rgba[1]) +
0.072 * Number(rgba[2]) >
255 / 2
? 'rgba(0,0,0,1)'
: 'rgba(255,255,255,1)';
},
});
export const AtomBgControlSample = () => {
return (
<RdxContext>
<div style={{ display: 'flex' }}>
<Canvas />
<ColorEditor />
</div>
</RdxContext>
);
};
const Canvas = () => {
const color = useRdxValue(ColorAtom);
const contrastColor = useRdxValue(ContrastColor);
const highlightColor = useRdxValue(HighLightColor);
return (
<div>
<div style={{ position: 'relative' }}>
<div
style={{
width: 435,
height: 435,
background: color,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
border: '1px solid grey',
}}
>
<h3 style={{ color: contrastColor }}>反转颜色</h3>
<h3 style={{ color: highlightColor }}>根据明暗</h3>
</div>
<div style={{ position: 'absolute', top: 10, left: 10 }}>
<ThemeEditor />
</div>
</div>
</div>
);
};
const ThemeEditor = () => {
const setColor = useRdxSetter(ColorAtom);
const dataSource = ['rgba(255,255,255, 1)', 'rgba(0,0,0, 1)'];
return (
<div>
<div style={{ display: 'flex' }}>
{dataSource.map((item) => (
<div
onClick={() => {
setColor(item);
}}
style={{
marginLeft: 12,
border: '1px solid grey',
background: item,
width: 32,
height: 32,
borderRadius: '50%',
}}
></div>
))}
</div>
<div style={{ color: 'orange' }}>点击我可以切换画布颜色哦!!</div>
</div>
);
};
const ColorEditor = () => {
const [color, setColor] = useRdxState(ColorAtom);
return (
<SketchPicker
color={color}
onChange={(v) => {
const { a, r, g, b } = v.rgb;
setColor(`rgba(${r},${g},${b},${a}`);
}}
/>
);
};