-
Notifications
You must be signed in to change notification settings - Fork 2
/
index.tsx
85 lines (75 loc) · 2.63 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import React, {CSSProperties} from "react";
import {calcSuperEllipsePath, getSuperEllipsePathAsDataUri, Preset} from "superellipsejs";
import useMeasure from 'react-use-measure';
export interface SuperEllipseProps {
r1?: number;
r2?: number;
p1?: number;
p2?: number;
}
interface Bounds {
readonly width: number;
readonly height: number;
}
function SuperEllipse(props: SuperEllipseProps & React.HTMLAttributes<HTMLDivElement>) {
const [ref, bounds] = useMeasure();
return <div {...props} ref={ref} style={{
...props.style,
...getMaskStyle(bounds, props)
}}>{props.children}</div>;
}
export function getMaskStyle(bounds: Bounds, props: SuperEllipseProps): CSSProperties {
const w = bounds.width;
const h = bounds.height;
const {r1 = Preset.iOS.r1, r2 = Preset.iOS.r2, p1, p2} = props;
const {dataUri} = getSuperEllipsePathAsDataUri(w, h, p1 !== undefined ? p1 : r1 * Math.min(w, h), p2 !== undefined ? p2 : r2 * Math.min(w, h));
return {
maskImage: `url("${dataUri}")`,
maskPosition: 'center',
maskRepeat: 'no-repeat',
// maskSize: 'contain',
WebkitMaskImage: `url("${dataUri}")`,
WebkitMaskPosition: 'center',
WebkitMaskRepeat: 'no-repeat',
// WebkitMaskSize: 'contain'
};
}
export interface SuperEllipseImgProps {
width: number;
height: number;
href: string;
style?: CSSProperties;
r1?: number;
r2?: number;
backgroundColor?: string;
strokeColor?: string;
strokeWidth?: number;
}
export const SuperEllipseImg = (props: SuperEllipseImgProps) => {
const w = props.width;
const h = props.height;
const {r1 = Preset.iOS.r1, r2 = Preset.iOS.r2} = props;
const {strokeWidth = 0, strokeColor = 'rgba(255,255,255,0.5)', backgroundColor} = props;
const path = calcSuperEllipsePath(w, h, r1 * Math.min(w, h), r2 * Math.min(w, h));
const id = `super-ellipse-${w}-${h}-${r1}-${r2}`;
return <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`} style={props.style}>
<defs>
<clipPath id={id}>
<path fill="#000" stroke="none" d={path}/>
</clipPath>
</defs>
<g clipPath={`url(#${id})`}>
{
backgroundColor &&
<rect width={w} height={h} fill={backgroundColor}/>
}
<image href={props.href} width={w} height={h} preserveAspectRatio="none"/>
{
strokeWidth > 0 &&
<path stroke={strokeColor} strokeWidth={strokeWidth * 2} fill="none" d={path}/>
}
</g>
</svg>
}
export {Preset}
export default SuperEllipse;