We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/chrishayuk/chuk-mcp-remotion'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
{/* chuk-motion/src/chuk_motion/components/overlays/TrueFocus/template.tsx.j2 */}
import React, { useMemo } from 'react';
import { AbsoluteFill, useCurrentFrame, interpolate, spring, useVideoConfig } from 'remotion';
interface TrueFocusProps {
text: string;
fontSize?: 'xl' | '2xl' | '3xl' | '4xl';
fontWeight?: 'bold' | 'extrabold' | 'black';
textColor?: string;
frameColor?: string;
glowColor?: string;
blurAmount?: number;
wordDuration?: number;
position?: 'center' | 'top' | 'bottom';
startFrame?: number;
durationInFrames?: number;
}
export const TrueFocus: React.FC<TrueFocusProps> = ({
text = 'True Focus',
fontSize = '3xl',
fontWeight = 'black',
textColor = '[[ colors.text.on_dark ]]',
frameColor = '[[ colors.primary[0] ]]',
glowColor = '[[ colors.primary[0] ]]',
blurAmount = 5,
wordDuration = 30, // frames per word
position = 'center',
startFrame = 0,
durationInFrames = 150,
}) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// Split text into words - MUST be called before any conditional returns
const words = useMemo(() => text.split(' '), [text]);
const wordCount = words.length;
const relativeFrame = frame - startFrame;
// Don't render if outside time range - AFTER all hooks
if (frame < startFrame || frame >= startFrame + durationInFrames) {
return null;
}
// Calculate which word is currently focused
const cycleProgress = (relativeFrame / wordDuration) % wordCount;
const currentWordIndex = Math.floor(cycleProgress);
// Smooth transition progress for frame animation
const transitionProgress = cycleProgress - currentWordIndex;
const smoothTransition = spring({
frame: transitionProgress * fps / 2, // Adjust for smooth spring
fps,
config: {
damping: [[ motion.default_spring.config.damping ]],
stiffness: [[ motion.default_spring.config.stiffness ]],
mass: [[ motion.default_spring.config.mass ]],
},
});
// Overall fade in
const fadeIn = interpolate(relativeFrame, [0, 20], [0, 1], {
extrapolateRight: 'clamp',
});
// Position styles
const positionStyles = {
center: { justifyContent: 'center', alignItems: 'center' },
top: { justifyContent: 'center', alignItems: 'flex-start', paddingTop: '[[ spacing.spacing['3xl'] ]]' },
bottom: { justifyContent: 'center', alignItems: 'flex-end', paddingBottom: '[[ spacing.spacing['3xl'] ]]' },
};
// Font size mapping
const fontSizeMap = {
'xl': parseInt('[[ typography.font_sizes[typography.default_resolution].xl ]]'),
'2xl': parseInt('[[ typography.font_sizes[typography.default_resolution]['2xl'] ]]'),
'3xl': parseInt('[[ typography.font_sizes[typography.default_resolution]['3xl'] ]]'),
'4xl': parseInt('[[ typography.font_sizes[typography.default_resolution]['4xl'] ]]'),
};
const fontWeightMap = {
'bold': '[[ typography.font_weights.bold ]]',
'extrabold': '[[ typography.font_weights.extrabold ]]',
'black': '[[ typography.font_weights.black ]]',
};
return (
<AbsoluteFill
style={{
opacity: fadeIn,
display: 'flex',
...positionStyles[position],
pointerEvents: 'none',
}}
>
<div
style={{
position: 'relative',
display: 'flex',
flexDirection: 'row',
gap: '[[ spacing.spacing.lg ]]',
flexWrap: 'wrap',
justifyContent: 'center',
alignItems: 'center',
padding: '[[ spacing.spacing.xl ]]',
}}
>
{words.map((word, index) => {
// Calculate blur for this word
const isFocused = index === currentWordIndex;
const blur = isFocused ? 0 : blurAmount;
// Calculate frame position and size for focused word
// Frame appears around the focused word with animated corners
const isFrameTarget = index === currentWordIndex;
return (
<div
key={index}
style={{
position: 'relative',
fontSize: fontSizeMap[fontSize],
fontWeight: fontWeightMap[fontWeight],
fontFamily: "'[[ "', '".join(typography.primary_font.fonts) ]]'",
color: textColor,
filter: `blur(${blur}px)`,
transition: `filter 0.3s ease`,
letterSpacing: '[[ typography.letter_spacing.tight ]]',
lineHeight: '[[ typography.line_heights.tight ]]',
}}
>
{word}
{/* Animated frame with corner brackets */}
{isFrameTarget && (
<div
style={{
position: 'absolute',
inset: `-[[ spacing.spacing.sm ]]`,
pointerEvents: 'none',
opacity: smoothTransition,
}}
>
{/* Top-left corner */}
<div
style={{
position: 'absolute',
top: 0,
left: 0,
width: '[[ spacing.spacing.lg ]]',
height: '[[ spacing.spacing.lg ]]',
borderTop: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderLeft: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderRadius: '[[ spacing.border_radius.xs ]]',
filter: `drop-shadow(0 0 [[ spacing.spacing.xs ]] ${glowColor})`,
}}
/>
{/* Top-right corner */}
<div
style={{
position: 'absolute',
top: 0,
right: 0,
width: '[[ spacing.spacing.lg ]]',
height: '[[ spacing.spacing.lg ]]',
borderTop: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderRight: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderRadius: '[[ spacing.border_radius.xs ]]',
filter: `drop-shadow(0 0 [[ spacing.spacing.xs ]] ${glowColor})`,
}}
/>
{/* Bottom-left corner */}
<div
style={{
position: 'absolute',
bottom: 0,
left: 0,
width: '[[ spacing.spacing.lg ]]',
height: '[[ spacing.spacing.lg ]]',
borderBottom: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderLeft: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderRadius: '[[ spacing.border_radius.xs ]]',
filter: `drop-shadow(0 0 [[ spacing.spacing.xs ]] ${glowColor})`,
}}
/>
{/* Bottom-right corner */}
<div
style={{
position: 'absolute',
bottom: 0,
right: 0,
width: '[[ spacing.spacing.lg ]]',
height: '[[ spacing.spacing.lg ]]',
borderBottom: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderRight: `[[ spacing.border_width.thick ]] solid ${frameColor}`,
borderRadius: '[[ spacing.border_radius.xs ]]',
filter: `drop-shadow(0 0 [[ spacing.spacing.xs ]] ${glowColor})`,
}}
/>
</div>
)}
</div>
);
})}
</div>
</AbsoluteFill>
);
};