fix: shadow
This commit is contained in:
parent
eadb745d63
commit
92578a7dce
|
|
@ -13,6 +13,7 @@ import { Canvas, Paragraph as SkiaParagraph, Path, Skia, useFonts } from '@shopi
|
|||
import ParallelogramButton from '@/components/ParallelogramButton'
|
||||
import ParallelogramGridItem from '@/components/ParallelogramGridItem'
|
||||
import BannerSection from '@/components/BannerSection'
|
||||
import ParallelogramShadow from '@/components/ParallelogramShadow'
|
||||
import { useTemplateActions } from '@/hooks/actions/use-template-actions'
|
||||
import { useTemplates } from '@/hooks/data'
|
||||
import { useFavoriteTemplates } from '@/hooks/data/use-favorite-templates'
|
||||
|
|
@ -582,26 +583,29 @@ const GooActions = observer<GooActionsProps>(function GooActions({ gooPoints, on
|
|||
onClick={onAddGoo}
|
||||
>
|
||||
<Canvas style={{ position: 'absolute', inset: 0 }}>
|
||||
{/* 白色主体 */}
|
||||
<Path
|
||||
path={Skia.Path.Make()
|
||||
.moveTo(skewOffset+padding, padding)
|
||||
.lineTo(width-padding, padding)
|
||||
.lineTo(width - skewOffset-padding, height-padding)
|
||||
.lineTo(padding, height-padding)
|
||||
.moveTo(skewOffset + padding, padding)
|
||||
.lineTo(width - padding, padding)
|
||||
.lineTo(width - skewOffset - padding, height - padding)
|
||||
.lineTo(padding, height - padding)
|
||||
.close()}
|
||||
color={Skia.Color('#FFFFFF')}
|
||||
/>
|
||||
{/* 黑色描边(适当加粗,避免底边过细) */}
|
||||
<Path
|
||||
path={Skia.Path.Make()
|
||||
.moveTo(skewOffset+padding, padding)
|
||||
.lineTo(width-padding, padding)
|
||||
.lineTo(width - skewOffset-padding, height-padding)
|
||||
.lineTo(padding, height-padding)
|
||||
.moveTo(skewOffset + padding, padding)
|
||||
.lineTo(width - padding, padding)
|
||||
.lineTo(width - skewOffset - padding, height - padding)
|
||||
.lineTo(padding, height - padding)
|
||||
.close()}
|
||||
color={Skia.Color('#000000')}
|
||||
color={Skia.Color('#323232')}
|
||||
style="stroke"
|
||||
strokeWidth={1}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
<ParallelogramShadow height={height} padding={padding} skewOffset={skewOffset} width={width} />
|
||||
</Canvas>
|
||||
<Block className="absolute inset-0 flex-row items-center gap-[4px] pl-[12px]">
|
||||
{isDev && isPolling && <Block className="ml-[4px] size-[6px] rounded-full bg-green-500" />}
|
||||
|
|
@ -624,13 +628,13 @@ const GooActions = observer<GooActionsProps>(function GooActions({ gooPoints, on
|
|||
.lineTo(addWidth - addSkewOffset - padding, addHeight - padding)
|
||||
.lineTo(padding, addHeight - padding)
|
||||
.close()}
|
||||
color={Skia.Color('#000000')}
|
||||
color={Skia.Color('#323232')}
|
||||
style="stroke"
|
||||
strokeWidth={1}
|
||||
/>
|
||||
</Canvas>
|
||||
<Block className="absolute inset-0 items-center justify-center">
|
||||
<Ionicons color="#000000" name="add" size={12} style={{ fontWeight: 'bold' }} />
|
||||
<Ionicons color="#323232" name="add" size={12} style={{ fontWeight: 'bold' }} />
|
||||
</Block>
|
||||
</Block>
|
||||
</Block>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import {
|
|||
vec,
|
||||
} from '@shopify/react-native-skia'
|
||||
import { Block } from '@share/components'
|
||||
import ParallelogramShadow from './ParallelogramShadow'
|
||||
|
||||
type MediaItem = {
|
||||
id: string
|
||||
|
|
@ -103,10 +104,14 @@ const ParallelogramGridItem = memo<Props>(function ParallelogramGridItem({
|
|||
|
||||
const labelHeight = 24
|
||||
const cardHeight = itemWidth + labelHeight
|
||||
// 预留给外部阴影的额外画布高度,避免阴影被裁剪
|
||||
const shadowMargin = 4
|
||||
|
||||
// 平行四边形路径(只裁剪内容,不拉伸内容)
|
||||
const skewOffset = 8
|
||||
const padding = 2 // 四周内缩,避免描边被裁掉
|
||||
|
||||
// 外层(黑色)边框 & 裁剪路径
|
||||
const parallelogramPath = useMemo(() => {
|
||||
const p = Skia.Path.Make()
|
||||
p.moveTo(skewOffset + padding, padding)
|
||||
|
|
@ -181,8 +186,8 @@ const ParallelogramGridItem = memo<Props>(function ParallelogramGridItem({
|
|||
height: cardHeight,
|
||||
}}
|
||||
>
|
||||
<Block style={{ width: itemWidth, height: cardHeight, position: 'relative' }}>
|
||||
<Canvas style={{ width: itemWidth, height: cardHeight, position: 'absolute' }}>
|
||||
<Block style={{ width: itemWidth, height: cardHeight + shadowMargin, position: 'relative' }}>
|
||||
<Canvas style={{ width: itemWidth, height: cardHeight + shadowMargin, position: 'absolute' }}>
|
||||
<Group clip={parallelogramPath}>
|
||||
{isVisible && displayImage && (
|
||||
<SkiaImage
|
||||
|
|
@ -215,7 +220,7 @@ const ParallelogramGridItem = memo<Props>(function ParallelogramGridItem({
|
|||
y={itemWidth}
|
||||
width={itemWidth}
|
||||
height={1}
|
||||
color="#000000"
|
||||
color="#323232"
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
@ -238,11 +243,20 @@ const ParallelogramGridItem = memo<Props>(function ParallelogramGridItem({
|
|||
)}
|
||||
</Group>
|
||||
|
||||
{/* 先画阴影,再画描边,保证描边永远在最外层 */}
|
||||
<ParallelogramShadow
|
||||
height={cardHeight + shadowMargin}
|
||||
baseHeight={cardHeight}
|
||||
padding={padding}
|
||||
skewOffset={skewOffset}
|
||||
width={itemWidth}
|
||||
/>
|
||||
|
||||
<Path
|
||||
path={parallelogramPath}
|
||||
style="stroke"
|
||||
strokeWidth={isSelected ? 3 : 2}
|
||||
color={isSelected ? '#FFE500' : '#000000'}
|
||||
strokeWidth={3}
|
||||
color={isSelected ? '#FFE500' : '#323232'}
|
||||
/>
|
||||
</Canvas>
|
||||
</Block>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
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
|
||||
|
||||
Loading…
Reference in New Issue