expo-duooomi-app/components/ParallelogramShadow.tsx

71 lines
2.1 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 } from 'react'
import { Path, Skia } from '@shopify/react-native-skia'
export type ParallelogramShadowProps = {
width: number
height: number
skewOffset: number
padding: number
/** 平行四边形主体的高度(即底边所在的 y不传则等于 height */
baseHeight?: number
/** 阴影整体偏移量,默认 2 像素 */
offset?: number
/** 阴影颜色,默认 #323232 */
color?: string
/** 阴影线粗细,默认 3 像素 */
strokeWidth?: number
}
/**
* 通用平行四边形按钮/卡片的底部 + 右侧硬阴影
*
* 约定:
* - 与主体外侧的黑色描边紧贴
* - 整体向右下偏移 offset 像素
*/
const ParallelogramShadow = memo<ParallelogramShadowProps>(function ParallelogramShadow({
width,
height,
skewOffset,
padding,
baseHeight,
offset = 2,
color = '#323232',
strokeWidth = 3,
}) {
const skiaColor = Skia.Color(color)
const h = baseHeight ?? height
// 只有在提供 baseHeight即有额外画布空间时才再往外多挪 1 像素,避免压住原始边框又不被裁剪
const extraOffsetY = baseHeight ? 1 : 0
return (
<>
{/* 底部阴影线 */}
<Path
path={Skia.Path.Make()
// 当有 baseHeight 时:相对于主体底边再向下挪 1px否则保持在 canvas 内部
.moveTo(padding + offset, h - padding + offset + extraOffsetY)
.lineTo(width - skewOffset - padding + offset, h - padding + offset + extraOffsetY)}
color={skiaColor}
style="stroke"
strokeWidth={strokeWidth}
/>
{/* 右侧阴影线 */}
<Path
path={Skia.Path.Make()
// 右侧阴影:仅在垂直方向多挪 1px水平方向仍保持在 canvas 内
.moveTo(width - skewOffset - padding + offset, h - padding + offset + extraOffsetY)
.lineTo(width - padding + offset, padding + offset + extraOffsetY)}
color={skiaColor}
style="stroke"
strokeWidth={strokeWidth}
/>
</>
)
})
ParallelogramShadow.displayName = 'ParallelogramShadow'
export default ParallelogramShadow