Skip to main content

YouTube Comment Highlight

youtube-comment-highlight.tsx
import {loadFont} from '@remotion/google-fonts/Inter'; import React from 'react'; import { CanvasImage, Easing, Interactive, interpolate, useCurrentFrame, } from 'remotion'; loadFont('normal', { subsets: ['latin'], weights: ['500', '600', '700'], }); export const YouTubeCommentHighlight: React.FC = () => { const frame = useCurrentFrame(); return ( <div style={{ height: 360, perspective: 1500, perspectiveOrigin: '50% 50%', position: 'relative', width: 1120, }} > <Interactive.Div name="Container" style={{ alignContent: 'center', backfaceVisibility: 'hidden', backgroundColor: '#15161a', border: '1px solid rgba(255, 255, 255, 0.09)', borderRadius: 26, boxShadow: '0 18px 40px rgba(0, 0, 0, 0.26)', boxSizing: 'border-box', columnGap: 18, display: 'grid', gridTemplateColumns: '88px minmax(0, 1fr)', height: 300, left: 0, padding: '24px 40px', position: 'absolute', rotate: interpolate( frame, [0, 90, 180, 270], ['y -10deg', 'y 5deg', 'y -5deg', 'y 5deg'], { easing: Easing.inOut(Easing.sin), extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }, ), top: 30, transformOrigin: '50% 50%', translate: interpolate( frame, [0, 48, 131, 179], ['0px 760px', '0px 0px', '0px 0px', '0px 760px'], { easing: [ Easing.spring({ allowTail: true, damping: 14, durationRestThreshold: 0.01, mass: 0.8, overshootClamping: false, stiffness: 110, }), Easing.linear, Easing.out( Easing.spring({ damping: 14, mass: 0.8, overshootClamping: false, stiffness: 110, }), ), ], extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }, ), width: 1120, }} > <> <CanvasImage fit="cover" height={88} name="Author avatar" src="https://images.unsplash.com/photo-1500648767791-00dcc994a43e?fit=crop&w=176&h=176&q=80&fm=jpg" style={{ backgroundColor: '#2a2b31', border: '1px solid rgba(255, 255, 255, 0.12)', borderRadius: 999, boxSizing: 'border-box', display: 'block', gridColumn: 1, gridRow: 1, height: 88, width: 88, }} width={88} /> <div style={{ gridColumn: 2, gridRow: 1, minWidth: 0, }} > <div style={{ alignItems: 'baseline', display: 'flex', gap: 12, }} > <Interactive.Span name="Author handle" style={{ color: '#ffffff', fontFamily: 'Inter', fontSize: 26, fontWeight: 700, lineHeight: 1.1, }} > @alexrenders </Interactive.Span> </div> <Interactive.Div name="Comment" style={{ color: '#f4f4f5', fontFamily: 'Inter', fontSize: 32, fontWeight: 500, letterSpacing: -0.35, lineHeight: 1.3, marginTop: 8, overflowWrap: 'anywhere', }} > This breakdown made the whole process click. Would love to see how you plan the animation timing in a future video! </Interactive.Div> <div style={{ alignItems: 'center', color: '#a9abb3', display: 'flex', fontFamily: 'Inter', fontSize: 22, fontWeight: 600, gap: 22, lineHeight: 1, marginTop: 14, }} > <div style={{ alignItems: 'center', display: 'flex', gap: 8, }} > <svg aria-hidden="true" height="28" viewBox="0 0 24 24" width="28" > <path d="M7 10v11H4V10Zm2 11V10l4-7c1.4.2 2.2 1.5 1.8 2.8L14 9h4.5c1.3 0 2.3 1.2 2 2.5l-1.7 7A3.3 3.3 0 0 1 15.6 21Z" fill="none" stroke="currentColor" strokeLinejoin="round" strokeWidth="1.8" /> </svg> <Interactive.Span name="Like count">2.4K</Interactive.Span> </div> <svg aria-hidden="true" height="28" style={{rotate: '180deg'}} viewBox="0 0 24 24" width="28" > <path d="M7 10v11H4V10Zm2 11V10l4-7c1.4.2 2.2 1.5 1.8 2.8L14 9h4.5c1.3 0 2.3 1.2 2 2.5l-1.7 7A3.3 3.3 0 0 1 15.6 21Z" fill="none" stroke="currentColor" strokeLinejoin="round" strokeWidth="1.8" /> </svg> </div> </div> </> </Interactive.Div> </div> ); };