forked from remotion-dev/remotion
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f7d1c81
commit d89d37d
Showing
12 changed files
with
479 additions
and
29 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import {AbsoluteFill, staticFile, OffthreadVideo} from 'remotion'; | ||
import {loadFont} from '@remotion/google-fonts/PlusJakartaSans'; | ||
import {Scene} from './phone/Scene'; | ||
|
||
const {fontFamily} = loadFont(); | ||
|
||
const vid1 = staticFile('/1.mov'); | ||
|
||
export const GpuTesting = () => { | ||
return ( | ||
<AbsoluteFill className="bg-gradient-to-r from-indigo-950 to-slate-50"> | ||
<h1 | ||
className="absolute bottom-0 right-0 text-7xl font-bold tracking-tight text-default logo-style p-8 bg-white/50 rounded-tl-3xl border-8 border-black" | ||
style={{ | ||
fontFamily, | ||
}} | ||
> | ||
GPU TESTING | ||
</h1> | ||
<div className="w-full flex justify-between items-center py-10 px-4 border-b-8 border-black"> | ||
<div className="flex text-xl"> | ||
<span | ||
className="mr-10 text-2xl font-extrabold" | ||
style={{ | ||
fontFamily, | ||
textShadow: '1px 1px 1px rgba(30,180,100,0.5)', | ||
}} | ||
> | ||
Blur:{' '} | ||
</span> | ||
<div className="space-x-4 flex blur-lg"> | ||
<div className="w-8 rounded h-8 bg-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-orange-500" /> | ||
</div> | ||
</div> | ||
<div className="flex text-xl"> | ||
<span | ||
className="mr-10 text-2xl font-extrabold" | ||
style={{ | ||
fontFamily, | ||
}} | ||
> | ||
Box Shadow:{' '} | ||
</span> | ||
<div className="space-x-4 flex"> | ||
<div className="w-8 rounded h-8 bg-black shadow-xl shadow-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-black shadow-xl shadow-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-black shadow-xl shadow-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-black shadow-xl shadow-orange-500" /> | ||
<div className="w-8 rounded h-8 bg-black shadow-xl shadow-orange-500" /> | ||
</div> | ||
</div> | ||
<div className="flex text-xl"> | ||
<span | ||
className="mr-10 text-2xl font-extrabold" | ||
style={{ | ||
fontFamily, | ||
textShadow: '4px 4px 2px rgba(18,30,100,0.5)', | ||
}} | ||
> | ||
Drop Shadow:{' '} | ||
</span> | ||
<div className="space-x-4 flex"> | ||
<svg | ||
className="drop-shadow-lg h-8 w-8" | ||
viewBox="0 0 84 84" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M22.0992 77L2.19922 42.5L22.0992 8H61.8992L81.7992 42.5L61.8992 77H22.0992Z" | ||
fill="#fff" | ||
/> | ||
</svg> | ||
<svg | ||
className="drop-shadow-lg h-8 w-8" | ||
viewBox="0 0 84 84" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M22.0992 77L2.19922 42.5L22.0992 8H61.8992L81.7992 42.5L61.8992 77H22.0992Z" | ||
fill="#fff" | ||
/> | ||
</svg> | ||
<svg | ||
className="drop-shadow-lg h-8 w-8" | ||
viewBox="0 0 84 84" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M22.0992 77L2.19922 42.5L22.0992 8H61.8992L81.7992 42.5L61.8992 77H22.0992Z" | ||
fill="#fff" | ||
/> | ||
</svg> | ||
<svg | ||
className="drop-shadow-lg h-8 w-8" | ||
viewBox="0 0 84 84" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M22.0992 77L2.19922 42.5L22.0992 8H61.8992L81.7992 42.5L61.8992 77H22.0992Z" | ||
fill="#fff" | ||
/> | ||
</svg> | ||
<svg | ||
className="drop-shadow-lg h-8 w-8" | ||
viewBox="0 0 84 84" | ||
xmlns="http://www.w3.org/2000/svg" | ||
> | ||
<path | ||
d="M22.0992 77L2.19922 42.5L22.0992 8H61.8992L81.7992 42.5L61.8992 77H22.0992Z" | ||
fill="#fff" | ||
/> | ||
</svg> | ||
</div> | ||
</div> | ||
</div> | ||
<OffthreadVideo src={vid1} className="h-full min-w-full object-cover" /> | ||
<Scene /> | ||
</AbsoluteFill> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import {useThree} from '@react-three/fiber'; | ||
import React, {useEffect, useMemo} from 'react'; | ||
import {interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion'; | ||
import { | ||
CAMERA_DISTANCE, | ||
getPhoneLayout, | ||
PHONE_CURVE_SEGMENTS, | ||
PHONE_SHININESS, | ||
} from './helpers/layout'; | ||
import {roundedRect} from './helpers/rounded-rectangle'; | ||
import {RoundedBox} from './RoundedBox'; | ||
|
||
export const Phone: React.FC<{ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
videoTexture: any | null; | ||
aspectRatio: number; | ||
baseScale: number; | ||
phoneColor: string; | ||
}> = ({aspectRatio, videoTexture, baseScale, phoneColor}) => { | ||
const frame = useCurrentFrame(); | ||
const {fps, durationInFrames} = useVideoConfig(); | ||
|
||
const layout = useMemo( | ||
() => getPhoneLayout(aspectRatio, baseScale), | ||
[aspectRatio, baseScale], | ||
); | ||
|
||
// Place a camera and set the distance to the object. | ||
// Then make it look at the object. | ||
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]); | ||
|
||
// Make the video fill the phone texture | ||
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]); | ||
|
||
// During the whole scene, the phone is rotating. | ||
// 2 * Math.PI is a full rotation. | ||
const constantRotation = interpolate( | ||
frame, | ||
[0, durationInFrames], | ||
[0, Math.PI * 6], | ||
); | ||
|
||
// When the composition starts, there is some extra | ||
// rotation and translation. | ||
const entranceAnimation = spring({ | ||
frame, | ||
fps, | ||
config: { | ||
damping: 200, | ||
mass: 3, | ||
}, | ||
}); | ||
|
||
// Calculate the entrance rotation, | ||
// doing one full spin | ||
const entranceRotation = interpolate( | ||
entranceAnimation, | ||
[0, 1], | ||
[-Math.PI, Math.PI], | ||
); | ||
|
||
// Calculating the total rotation of the phone | ||
const rotateY = entranceRotation + constantRotation; | ||
|
||
// Calculating the translation of the phone at the beginning. | ||
// The start position of the phone is set to 4 "units" | ||
const translateY = interpolate(entranceAnimation, [0, 1], [-4, 0]); | ||
|
||
// Calculate a rounded rectangle for the phone screen | ||
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={phoneColor} shininess={PHONE_SHININESS} /> | ||
</RoundedBox> | ||
<mesh position={layout.screen.position}> | ||
<shapeGeometry args={[screenGeometry]} /> | ||
{videoTexture ? ( | ||
<meshBasicMaterial | ||
color={0xffffff} | ||
toneMapped={false} | ||
map={videoTexture} | ||
/> | ||
) : null} | ||
</mesh> | ||
</group> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React, {useMemo} from 'react'; | ||
import {roundedRect} from './helpers/rounded-rectangle'; | ||
|
||
type Props = { | ||
width: number; | ||
height: number; | ||
radius: number; | ||
curveSegments: number; | ||
depth: number; | ||
} & Omit<JSX.IntrinsicElements['mesh'], 'args'>; | ||
|
||
export const RoundedBox: React.FC<Props> = ({ | ||
width, | ||
height, | ||
radius, | ||
curveSegments, | ||
children, | ||
depth, | ||
...otherProps | ||
}) => { | ||
const shape = useMemo( | ||
() => roundedRect({width, height, radius}), | ||
[height, radius, width] | ||
); | ||
|
||
const params = useMemo( | ||
() => ({ | ||
depth, | ||
bevelEnabled: true, | ||
bevelSize: 0, | ||
bevelThickness: 0, | ||
curveSegments, | ||
}), | ||
[curveSegments, depth] | ||
); | ||
|
||
return ( | ||
<mesh {...otherProps}> | ||
<extrudeGeometry attach="geometry" args={[shape, params]} /> | ||
{children} | ||
</mesh> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import {staticFile} from 'remotion'; | ||
import {getVideoMetadata, VideoMetadata} from '@remotion/media-utils'; | ||
import {ThreeCanvas, useVideoTexture} from '@remotion/three'; | ||
import React, {useEffect, useRef, useState} from 'react'; | ||
import {useVideoConfig, Video} from 'remotion'; | ||
import {Phone} from './Phone'; | ||
|
||
const videoStyle: React.CSSProperties = { | ||
position: 'absolute', | ||
opacity: 0, | ||
}; | ||
|
||
export const Scene: React.FC = () => { | ||
const phoneColor = 'rgba(110, 152, 191, 0.00)'; | ||
const baseScale = 1; | ||
|
||
const videoRef = useRef<HTMLVideoElement>(null); | ||
const {width, height} = useVideoConfig(); | ||
const [videoData, setVideoData] = useState<VideoMetadata | null>(null); | ||
|
||
const videoSrc = staticFile('1.mov'); | ||
|
||
useEffect(() => { | ||
getVideoMetadata(videoSrc) | ||
.then((data) => setVideoData(data)) | ||
.catch((err) => console.log(err)); | ||
}, [videoSrc]); | ||
|
||
const texture = useVideoTexture(videoRef); | ||
return ( | ||
<div className="bg-transparent w-3/4 absolute h-3/4 -right-60 bottom-0"> | ||
<Video ref={videoRef} src={videoSrc} style={videoStyle} /> | ||
{videoData ? ( | ||
<ThreeCanvas linear width={(width * 3) / 4} height={(height * 3) / 4}> | ||
<ambientLight intensity={1.5} color={0xffffff} /> | ||
<pointLight position={[10, 10, 0]} /> | ||
<Phone | ||
phoneColor={phoneColor} | ||
baseScale={baseScale} | ||
videoTexture={texture} | ||
aspectRatio={videoData.aspectRatio} | ||
/> | ||
</ThreeCanvas> | ||
) : null} | ||
</div> | ||
); | ||
}; |
Oops, something went wrong.