import { useThree } from '@react-three/fiber' ; import React , { useEffect , useMemo } from 'react' ; import { interpolate , spring , useCurrentFrame , useVideoConfig } from 'remotion' ; import { VideoTexture } from 'three' ; import { CAMERA_DISTANCE , getPhoneLayout , PHONE_COLOR , PHONE_CURVE_SEGMENTS , PHONE_SHININESS , } from './helpers/layout' ; import { roundedRect } from './helpers/rounded-rectangle' ; import { RoundedBox } from './RoundedBox' ; export const Phone = ( { aspectRatio , videoTexture , baseScale } ) => { const frame = useCurrentFrame ( ) ; const { fps , durationInFrames } = useVideoConfig ( ) ; const layout = useMemo ( ( ) => getPhoneLayout ( aspectRatio , baseScale ) , [ aspectRatio , baseScale ] ) ; const camera = useThree ( ( state ) => state . camera ) ; useEffect ( ( ) => { camera . position . set ( 0 , 0 , CAMERA_DISTANCE ) ; camera . near = 0.2 ; camera . far = Math . max ( 5000 , CAMERA_DISTANCE * 2 ) ; camera . lookAt ( 0 , 0 , 0 ) ; } , [ camera ] ) ; useEffect ( ( ) => { if ( videoTexture ) { videoTexture . repeat . y = 1 / layout . screen . height ; videoTexture . repeat . x = 1 / layout . screen . width ; } } , [ aspectRatio , layout . screen . height , layout . screen . width , videoTexture ] ) ; const constantRotation = interpolate ( frame , [ 0 , durationInFrames ] , [ 0 , Math . PI * 6 ] ) ; const entranceAnimation = spring ( { frame , fps , config : { damping : 200 , mass : 3 , } , } ) ; const entranceRotation = interpolate ( entranceAnimation , [ 0 , 1 ] , [ - Math . PI , Math . PI ] ) ; const rotateY = entranceRotation + constantRotation ; const translateY = interpolate ( entranceAnimation , [ 0 , 1 ] , [ - 4 , 0 ] ) ; const screenGeometry = useMemo ( ( ) => { return roundedRect ( { width : layout . screen . width , height : layout . screen . height , radius : layout . screen . radius , } ) ; } , [ layout . screen . height , layout . screen . radius , layout . screen . width ] ) ; return ( < group scale = { entranceAnimation } rotation = { [ 0 , rotateY , 0 ] } position = { [ 0 , translateY , 0 ] } > < RoundedBox radius = { layout . phone . radius } depth = { layout . phone . thickness } curveSegments = { PHONE_CURVE_SEGMENTS } position = { layout . phone . position } width = { layout . phone . width } height = { layout . phone . height } > < meshPhongMaterial color = { PHONE_COLOR } shininess = { PHONE_SHININESS } / > < /RoundedBox> < mesh position = { layout . screen . position } > < shapeGeometry args = { [ screenGeometry ] } /> { videoTexture ? ( < meshBasicMaterial color = { 0xffffff } toneMapped = { false } map = { videoTexture } / > ) : null } < /mesh> < /group>); } ;