expo-duooomi-app/components/ParallelogramShape.tsx

116 lines
3.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { memo, useMemo } from 'react'
import { Canvas, Group, Path, Skia } from '@shopify/react-native-skia'
import ParallelogramShadow from './ParallelogramShadow'
export type ParallelogramShapeProps = {
/** 宽度 */
width: number
/** 高度 */
height: number
/** 填充颜色 */
fillColor?: string
/** 描边颜色,默认 #323232 */
strokeColor?: string
/** 描边宽度,默认 3 */
strokeWidth?: number
/** 内边距,默认 2 */
padding?: number
/** 倾斜偏移量,默认 8统一所有平行四边形的倾斜角度 */
skewOffset?: number
/** 是否显示阴影,默认 true */
showShadow?: boolean
/** 阴影颜色,默认 #323232 */
shadowColor?: string
/** 阴影偏移量,默认 2 */
shadowOffset?: number
/** 阴影线粗细,默认 3 */
shadowStrokeWidth?: number
/** 平行四边形主体的高度(用于阴影计算),不传则等于 height */
baseHeight?: number
/** Canvas 样式 */
canvasStyle?: any
/** 子元素(内容,放在 Canvas 外部) */
children?: React.ReactNode
/** 在 Canvas 内渲染的自定义内容Skia 组件) */
renderContent?: () => React.ReactNode
}
/**
* 通用平行四边形形状组件
*
* 统一特性:
* - 所有平行四边形的倾斜角度一致skewOffset = 8
* - 所有平行四边形都有右侧阴影和下侧阴影
* - 统一的描边样式(黑色,宽度 3
*/
const ParallelogramShape = memo<ParallelogramShapeProps>(function ParallelogramShape({
width,
height,
fillColor = '#FFFFFF',
strokeColor = '#323232',
strokeWidth = 3,
padding = 2,
skewOffset = 8,
showShadow = true,
shadowColor = '#323232',
shadowOffset = 2,
shadowStrokeWidth = 3,
baseHeight,
canvasStyle,
children,
renderContent,
}) {
// 创建平行四边形路径
const parallelogramPath = useMemo(() => {
const path = Skia.Path.Make()
path.moveTo(skewOffset + padding, padding)
path.lineTo(width - padding, padding)
path.lineTo(width - skewOffset - padding, height - padding)
path.lineTo(padding, height - padding)
path.close()
return path
}, [width, height, skewOffset, padding])
const skiaFillColor = Skia.Color(fillColor)
const skiaStrokeColor = Skia.Color(strokeColor)
return (
<>
<Canvas style={[{ position: 'absolute', inset: 0 }, canvasStyle]}>
{/* 填充 - 平行四边形主体 */}
<Path path={parallelogramPath} color={skiaFillColor} />
{/* 描边 - 平行四边形边框 */}
<Path
path={parallelogramPath}
color={skiaStrokeColor}
style="stroke"
strokeWidth={strokeWidth}
/>
{/* 阴影 - 右侧和下侧硬阴影 */}
{showShadow && (
<ParallelogramShadow
width={width}
height={height}
baseHeight={baseHeight}
padding={padding}
skewOffset={skewOffset}
offset={shadowOffset}
color={shadowColor}
strokeWidth={shadowStrokeWidth}
/>
)}
{/* 自定义内容(在 Canvas 内渲染) */}
{renderContent && renderContent()}
</Canvas>
{/* 内容区域(在 Canvas 外部) */}
{children}
</>
)
})
ParallelogramShape.displayName = 'ParallelogramShape'
export default ParallelogramShape