mirror of
https://github.com/ant-design/ant-design.git
synced 2024-12-25 16:58:00 +08:00
59ad48476b
* chore: add boime lint * fix lint * use files ignore * revert change * ignore clarity.js * fix some errors * fix some errors * fix some errors * fix some errors * add yml file * Update clarity.js Signed-off-by: afc163 <afc163@gmail.com> * add npm run lint:biome * add npm run lint:biome * fix test case * fix ts errors * fix ts errors * fix lint and add .lintstagedrc * shorten prop name * chore: update package.json * update biome.json * chore: remove stylelint * chore: useOptionalChain * fix lint * biome format * prettier all code * prettier all code * fix site test --------- Signed-off-by: afc163 <afc163@gmail.com>
128 lines
3.2 KiB
TypeScript
128 lines
3.2 KiB
TypeScript
import React from 'react';
|
|
import { HappyProvider } from '@ant-design/happy-work-theme';
|
|
import { Button, ConfigProvider, Space } from 'antd';
|
|
import type { ConfigProviderProps, GetProp } from 'antd';
|
|
|
|
type WaveConfig = GetProp<ConfigProviderProps, 'wave'>;
|
|
|
|
// Prepare effect holder
|
|
const createHolder = (node: HTMLElement) => {
|
|
const { borderWidth } = getComputedStyle(node);
|
|
const borderWidthNum = parseInt(borderWidth, 10);
|
|
|
|
const div = document.createElement('div');
|
|
div.style.position = 'absolute';
|
|
div.style.inset = `-${borderWidthNum}px`;
|
|
div.style.borderRadius = 'inherit';
|
|
div.style.background = 'transparent';
|
|
div.style.zIndex = '999';
|
|
div.style.pointerEvents = 'none';
|
|
div.style.overflow = 'hidden';
|
|
node.appendChild(div);
|
|
|
|
return div;
|
|
};
|
|
|
|
const createDot = (holder: HTMLElement, color: string, left: number, top: number, size = 0) => {
|
|
const dot = document.createElement('div');
|
|
dot.style.position = 'absolute';
|
|
dot.style.left = `${left}px`;
|
|
dot.style.top = `${top}px`;
|
|
dot.style.width = `${size}px`;
|
|
dot.style.height = `${size}px`;
|
|
dot.style.borderRadius = '50%';
|
|
dot.style.background = color;
|
|
dot.style.transform = 'translate(-50%, -50%)';
|
|
dot.style.transition = 'all 1s ease-out';
|
|
holder.appendChild(dot);
|
|
|
|
return dot;
|
|
};
|
|
|
|
// Inset Effect
|
|
const showInsetEffect: WaveConfig['showEffect'] = (node, { event, component }) => {
|
|
if (component !== 'Button') {
|
|
return;
|
|
}
|
|
|
|
const holder = createHolder(node);
|
|
|
|
const rect = holder.getBoundingClientRect();
|
|
|
|
const left = event.clientX - rect.left;
|
|
const top = event.clientY - rect.top;
|
|
|
|
const dot = createDot(holder, 'rgba(255, 255, 255, 0.65)', left, top);
|
|
|
|
// Motion
|
|
requestAnimationFrame(() => {
|
|
dot.ontransitionend = () => {
|
|
holder.remove();
|
|
};
|
|
|
|
dot.style.width = '200px';
|
|
dot.style.height = '200px';
|
|
dot.style.opacity = '0';
|
|
});
|
|
};
|
|
|
|
// Shake Effect
|
|
const showShakeEffect: WaveConfig['showEffect'] = (node, { component }) => {
|
|
if (component !== 'Button') {
|
|
return;
|
|
}
|
|
|
|
const seq = [0, -15, 15, -5, 5, 0];
|
|
const itv = 10;
|
|
|
|
let steps = 0;
|
|
|
|
function loop() {
|
|
cancelAnimationFrame((node as any).effectTimeout);
|
|
|
|
(node as any).effectTimeout = requestAnimationFrame(() => {
|
|
const currentStep = Math.floor(steps / itv);
|
|
const current = seq[currentStep];
|
|
const next = seq[currentStep + 1];
|
|
|
|
if (!next) {
|
|
node.style.transform = '';
|
|
node.style.transition = '';
|
|
return;
|
|
}
|
|
|
|
// Trans from current to next by itv
|
|
const angle = current + ((next - current) / itv) * (steps % itv);
|
|
|
|
node.style.transform = `rotate(${angle}deg)`;
|
|
node.style.transition = 'none';
|
|
|
|
steps += 1;
|
|
loop();
|
|
});
|
|
}
|
|
|
|
loop();
|
|
};
|
|
|
|
// Component
|
|
const Wrapper = ({ name, ...wave }: WaveConfig & { name: string }) => (
|
|
<ConfigProvider wave={wave}>
|
|
<Button type="primary">{name}</Button>
|
|
</ConfigProvider>
|
|
);
|
|
|
|
const App = () => (
|
|
<Space style={{ padding: 24 }} size="large">
|
|
<Wrapper name="Disabled" disabled />
|
|
<Wrapper name="Default" />
|
|
<Wrapper name="Inset" showEffect={showInsetEffect} />
|
|
<Wrapper name="Shake" showEffect={showShakeEffect} />
|
|
<HappyProvider>
|
|
<Button type="primary">Happy Work</Button>
|
|
</HappyProvider>
|
|
</Space>
|
|
);
|
|
|
|
export default App;
|