import React, { useMemo, useState } from 'react'; import { Dimensions, ViewProps } from 'react-native'; import { Canvas, Blur, Image as SkiaImage, useImage, Offset, Mask, RoundedRect, Shadow } from '@shopify/react-native-skia'; import useDefaultStyles, { useUserOrSystemScheme } from './Colors'; import styled from 'styled-components/native'; const Screen = Dimensions.get('screen'); const Container = styled.View<{ size: number }>` width: ${(props) => props.size}px; height: ${(props) => props.size}px; position: relative; z-index: 0; `; const BlurContainer = styled(Canvas) <{ size: number, offset: number }>` position: absolute; left: -${(props) => props.offset}px; top: -${(props) => props.offset}px; width: ${(props) => props.size}px; height: ${(props) => props.size}px; z-index: 2; `; interface Props { blurRadius?: number; opacity?: number; margin?: number; radius?: number; style?: ViewProps['style']; src: string; } const emptyAlbumLight = require('@/assets/images/empty-album-light.png'); const emptyAlbumDark = require('@/assets/images/empty-album-dark.png'); /** * This will take a cover image, and apply shadows and a really nice background * blur to the image in question. Additionally, we'll add some margin and radius * to the corners. */ function CoverImage({ blurRadius = 256, opacity = 0.85, margin = 112, radius = 12, style, src, }: Props) { const defaultStyles = useDefaultStyles(); const colorScheme = useUserOrSystemScheme(); const [hasFailed, setFailed] = useState(false); const image = useImage(src || null, () => setFailed(true)); const fallback = useImage(colorScheme === 'light' ? emptyAlbumLight : emptyAlbumDark); const { canvasSize, imageSize } = useMemo(() => { const imageSize = Screen.width - margin; const canvasSize = imageSize + blurRadius * 2; return { imageSize, canvasSize }; }, [blurRadius, margin]); return ( {src && ( <> } key="image" > )} {(!src || hasFailed) && ( } key="fallback" > )} ); } export default CoverImage;