fkbuilder
v1.1.40
Published
基于 Node.js + Paper.js 的程序化视频生成库,支持多轨道多场景、丰富动画效果、转场特效和并行渲染
Maintainers
Readme
FKbuilder - 程序化视频生成库
基于 Node.js + Paper.js 的纯 JavaScript 视频制作库,提供简洁的 API 和强大的功能。
🧭 简介
FKbuilder 是一个面向开发者的程序化视频生成库,通过“轨道-场景-元素”的层次化架构与时间线驱动的 API,帮助你用代码构建具有动画、转场、文本特效、图形与图表的高质量视频。
- 面向工程化的工作流:用 JavaScript 组装素材与逻辑,精准控制时间与动画。
- 丰富的元素生态:文本、图片、视频、形状、音频、字幕、SVG、JSON、代码块、ECharts 图表等。
- 强大的动画系统:预设动画、关键帧动画、变换动画以及每帧更新的持续动画(onFrame)。
- 高性能渲染:基于 Paper.js 的 2D 渲染,支持并行渲染与上下文变量传递。
- 易于集成:简单的 API 设计,适用于生成教程视频、数据可视化短片、产品演示、自动化内容生产等场景。
✨ 核心特性
- 🎬 多轨道多场景 - 灵活的轨道和场景管理系统,支持复杂的视频结构
- 🎨 丰富的元素类型 - 文本、图片、视频、形状、音频、字幕、示波器、SVG、JSON 等
- ✨ 强大的动画系统 - 预设动画、关键帧动画、变换动画、onFrame 持续动画
- 🎯 精确的时间控制 - 灵活的时间线管理和元素时间控制
- 🚀 高性能渲染 - 基于 Paper.js 的 2D 渲染引擎,支持实例化
- 🎭 丰富的转场效果 - 支持 gl-transitions 转场库(20+ 种转场效果)
- 📝 文本特效 - 渐变、阴影、发光、描边、文字拆分动画
- 📹 视频导出 - 支持 MP4 格式导出,支持管道模式和文件模式
- ⚡ 持续动画支持 - 通过 onFrame 回调实现每帧更新的持续动画效果
- 🔧 组件化设计 - 可复用的组件系统,支持相对坐标和时间控制
- ⚙️ 并行渲染 - 支持 Worker Threads 并行渲染,大幅提升渲染性能
- 🔗 上下文关联 - 在并行渲染中自动传递上下文变量,支持闭包变量
📦 安装
通过 npm 安装
npm install fkbuilder
# 或
yarn add fkbuilder
# 或
pnpm add fkbuilder本地开发安装
git clone <repository-url>
cd FKbuilder
npm install🔧 系统要求
- Node.js >= 16.0.0
- FFmpeg(用于视频编码)
安装 FFmpeg
macOS:
brew install ffmpegUbuntu/Debian:
sudo apt-get install ffmpegWindows: 下载并安装 FFmpeg,确保添加到系统 PATH。
🚀 快速开始
基础示例
ESM 模块(推荐):
import { VideoBuilder } from 'fkbuilder';CommonJS 模块:
const { VideoBuilder } = require('fkbuilder');完整示例:
import { VideoBuilder } from 'fkbuilder';
// 创建视频构建器
const builder = new VideoBuilder({
width: 1920,
height: 1080,
fps: 30,
});
// 创建轨道
const track = builder.createTrack({ zIndex: 1 });
// 创建场景
const scene = track.createScene({ duration: 5 })
.addBackground({ color: '#1a1a2e' })
.addText({
text: 'Hello, World!',
x: '50%',
y: '50%',
fontSize: 80,
color: '#ffffff',
textAlign: 'center',
duration: 5,
startTime: 0,
animations: ['fadeIn'],
});
// 渲染视频(自动 build 和 export)
await builder.render('./output/video.mp4');📚 核心概念
VideoBuilder(视频构建器)
视频构建器是创建视频的入口,管理所有轨道和场景。
const builder = new VideoBuilder({
width: 1920, // 视频宽度
height: 1080, // 视频高度
fps: 30, // 帧率
});主要方法:
createTrack(config)- 创建轨道render(outputPath, options)- 渲染视频(自动 build 和 export)export(outputPath, options)- 导出视频build()- 构建 VideoMaker 对象initialize()- 初始化(预加载资源)
Track(轨道)
轨道用于组织场景,支持多个轨道叠加。
// 创建轨道
const track = builder.createTrack({
zIndex: 1, // 层级(数字越大越在上层)
name: '主轨道' // 轨道名称(可选)
});
// 添加组件到轨道
track.addComponent(component);Scene(场景)
场景是视频的基本单元,包含多个元素。
// 创建场景
const scene = track.createScene({
duration: 5, // 场景时长(秒)
startTime: 0, // 开始时间(可选,不指定则自动计算)
});
// 添加组件到场景
scene.addComponent(component);Component(组件)
组件是可复用的元素容器,有自己的宽高和时间控制。组件内的元素使用相对坐标(相对于组件)。
import { Component } from 'fkbuilder';
// 创建组件
const cardComponent = new Component({
name: 'Card',
width: 400, // 组件宽度
height: 300, // 组件高度
x: '50%', // 组件位置(相对于父容器)
y: '50%',
anchor: [0.5, 0.5], // 锚点
startTime: 0, // 开始时间(相对于父容器)
duration: 5, // 持续时间
zIndex: 10,
});
// 在组件内添加元素(使用相对坐标)
cardComponent
.addBackground({ color: '#2e3b3c' })
.addRect({
x: '50%', // 相对于组件中心
y: '50%',
width: '80%', // 相对于组件宽度
height: '60%', // 相对于组件高度
fillColor: '#5acbed',
})
.addText({
text: '卡片标题',
x: '50%',
y: '30%',
fontSize: 36,
color: '#ffffff',
});
// 添加到场景或轨道
scene.addComponent(cardComponent);
// 或
track.addComponent(cardComponent);🎨 元素类型
文本元素
scene.addText({
text: 'Hello',
x: '50%', // 支持百分比和像素值
y: '50%',
fontSize: 72,
fontFamily: 'Arial',
color: '#ffffff',
textAlign: 'center',
duration: 5,
startTime: 0,
// 文本效果
textShadow: true,
textShadowColor: '#000000',
textShadowBlur: 20,
gradient: true,
gradientColors: ['#FF6B6B', '#4ECDC4'],
gradientDirection: 'horizontal',
textGlow: true,
textGlowColor: '#FFFFFF',
textGlowBlur: 30,
stroke: true,
strokeColor: '#000000',
strokeWidth: 2,
// 文字拆分动画
split: 'letter', // 'letter', 'word', 'line' 或 null
splitDelay: 0.1,
// 动画
animations: ['fadeIn', 'bigIn'],
// onFrame 持续动画
onFrame: (element, progress, time) => {
// 每帧更新
},
});图片元素
scene.addImage({
src: './path/to/image.jpg',
x: '50%',
y: '50%',
width: 800,
height: 600,
anchor: [0.5, 0.5],
fit: 'cover', // 'cover', 'contain', 'fill', 'none'
duration: 5,
startTime: 0,
animations: ['zoomIn'],
borderRadius: 20,
shadowBlur: 30,
shadowColor: '#000000',
});视频元素
scene.addVideo({
src: './path/to/video.mp4',
x: '50%',
y: '50%',
width: 1920,
height: 1080,
anchor: [0.5, 0.5],
fit: 'cover',
duration: 10,
startTime: 0,
animations: ['fadeIn'],
});形状元素
// 矩形
scene.addRect({
x: '50%',
y: '50%',
width: 400,
height: 300,
bgcolor: '#4a90e2',
borderRadius: 20,
anchor: [0.5, 0.5],
duration: 5,
startTime: 0,
animations: ['fadeIn'],
});
// 圆形
scene.addCircle({
x: '50%',
y: '50%',
radius: 100,
fillColor: '#ff6b6b',
strokeColor: '#ffffff',
strokeWidth: 3,
anchor: [0.5, 0.5],
duration: 5,
startTime: 0,
animations: ['bounce'],
});
// 路径
scene.addPath({
points: [[0, 0], [100, 50], [200, 0]],
closed: true,
fillColor: '#4ECDC4',
strokeColor: '#ffffff',
strokeWidth: 2,
duration: 5,
startTime: 0,
});音频元素
scene.addAudio({
src: './path/to/audio.mp3',
startTime: 0,
duration: 10,
volume: 1.0,
fadeIn: 1, // 淡入时长(秒)
fadeOut: 1, // 淡出时长(秒)
});字幕元素
scene.addSubtitle({
text: '这是一段字幕文本,会根据时长自动分割',
fontSize: 48,
color: '#ffffff',
position: 'center', // 'center', 'top', 'bottom'
duration: 10,
startTime: 0,
maxLength: 20, // 每段最大字符数
// 支持所有文本效果
textShadow: true,
gradient: true,
animations: ['fadeIn'],
});LRC 歌词字幕
scene.addLRC({
lrcPath: './path/to/lyrics.lrc',
fontSize: 48,
color: '#ffffff',
position: 'bottom',
// 支持所有文本效果
textShadow: true,
animations: ['fadeIn'],
});示波器元素
scene.addOscilloscope({
audioPath: './path/to/audio.mp3',
x: '50%',
y: '50%',
width: 1600,
height: 200,
waveColor: '#4ECDC4',
backgroundColor: 'rgba(0, 0, 0, 0.3)',
style: 'line', // 'line', 'bars', 'particles', 'blob', 'circle', 'spectrum' 等
lineWidth: 3,
mirror: true, // 是否镜像显示
duration: 10,
startTime: 0,
animations: ['fadeIn'],
});SVG 元素
scene.addSVG({
src: './path/to/image.svg',
x: '50%',
y: '50%',
width: 800,
height: 600,
duration: 5,
startTime: 0,
animations: ['fadeIn'],
});JSON 元素(Paper.js 路径)
scene.addJSON({
json: {
type: 'Path',
pathData: 'M 0,0 L 100,100',
fillColor: '#4ECDC4',
},
x: '50%',
y: '50%',
duration: 5,
startTime: 0,
});ECharts 元素
将 ECharts 图表作为视频中的可视化元素进行渲染。图表动画与视频时间线同步:在元素的第一帧渲染时启动动画,不会在初始化阶段提前播放。
- 用途:在场景中展示柱状图、折线图、饼图等数据可视化。
- 依赖:需要安装
echarts。 - 关键参数:
option:ECharts 配置对象(与浏览器一致)。renderer:渲染方式,'canvas'|'svg',默认'canvas'。theme:ECharts 主题名称或对象。backgroundColor:元素背景色(可与option.backgroundColor配合)。x,y,width,height,anchor:定位与尺寸,单位与其他元素一致。startTime,duration:时间线控制,决定元素何时出现与持续时长。onFrame:每帧回调,可在时间线上通过setOption动态更新数据。
const option = {
animation: true,
animationDuration: 2000,
title: { text: 'ECharts 示例', textStyle: { color: '#fff' } },
tooltip: {},
xAxis: { data: ['A','B','C','D','E','F'], axisLine: { lineStyle: { color: '#aaa' } }, axisLabel: { color: '#ddd' } },
yAxis: { axisLine: { lineStyle: { color: '#aaa' } }, axisLabel: { color: '#ddd' }, splitLine: { lineStyle: { color: '#333' } } },
series: [{ type: 'bar', data: [5, 20, 36, 10, 10, 20], itemStyle: { color: '#00d9ff' } }]
};
scene.addECharts({
option,
x: '50%',
y: '55%',
width: 900,
height: 500,
backgroundColor: '#8fafeeff',
anchor: [0.5, 0.5],
startTime: 0,
duration: 6
});代码元素(Code)
用于展示带语法高亮的代码块,支持逐行、逐词、逐字的打字动画,行号、光标、自动滚动以及底部滚动留白。
scene.addCode({
code: `function hello() {\n const msg = 'Hello'\n return msg\n}`,
language: 'javascript',
theme: 'dark',
x: '50%',
y: '55%',
width: 700,
height: 300,
anchor: [0.5, 0.5],
startTime: 0,
duration: 6,
fontSize: 24,
showLineNumbers: true,
showBorder: true,
split: 'line', // 打字模式:'line', 'word', 'letter'
splitDelay: 0.1,
borderRadius: 12,
padding: 20
})
scene.addCode({
code: `const items = [1,2,3,4]\nfor (let i = 0; i < 40; i++) {\n console.log(items[i % items.length])\n}`,
language: 'javascript',
theme: 'dark',
x: '50%',
y: '55%',
width: 800,
height: 260,
anchor: [0.5, 0.5],
startTime: 0,
duration: 8,
fontSize: 22,
showLineNumbers: true,
showBorder: true,
borderRadius: 10,
padding: 18,
paddingBottom: 26,
cursor: true,
cursorColor: '#00d9ff',
cursorWidth: 2,
split: 'letter',
splitDelay: 0.06,
splitDuration: 0.2,
autoScroll: true,
scrollPaddingBottom: 24
})常用选项说明:
language代码语言标识,例如javascript、python、javatheme主题,例如dark、monokai、draculashowLineNumbers是否显示行号showBorder、borderRadius是否显示边框与圆角split打字模式:line(逐行)、word(逐词)、letter(逐字);配合splitDelay、splitDurationcursor、cursorColor、cursorWidth光标样式autoScroll自动滚动使最新内容可见paddingBottom布局上的底部内边距scrollPaddingBottom打字滚动过程的底部留白
🎭 转场效果
// 添加转场效果
// 注意:不需要指定 fromScene 和 toScene,系统会根据 startTime 自动找到对应的场景
track.addTransition({
name: 'CrossZoom', // 转场效果名称
duration: 1, // 转场时长(秒)
startTime: scene2StartTime, // 转场结束时间(目标场景开始的时间)
});
// 使用示例:
let currentTime = 0;
const sceneDuration = 4;
const transitionDuration = 1;
// 场景1
const scene1 = track.createScene({
duration: sceneDuration,
startTime: currentTime,
});
currentTime += sceneDuration;
// 场景2(与场景1重叠,重叠部分用于转场)
const scene2StartTime = currentTime - transitionDuration;
const scene2 = track.createScene({
duration: sceneDuration,
startTime: scene2StartTime,
});
// 添加转场(从场景1转到场景2)
track.addTransition({
name: 'CrossZoom',
duration: transitionDuration,
startTime: scene2StartTime, // 转场结束时间 = 场景2开始时间
});常用转场效果:
fade- 淡入淡出CrossZoom- 交叉缩放CircleCrop- 圆形裁剪LinearBlur- 线性模糊Swirl- 漩涡Directional- 方向擦除Bounce- 弹跳Dreamy- 梦幻Radial- 径向GridFlip- 网格翻转Mosaic- 马赛克PolkaDotsCurtain- 圆点窗帘ZoomInCircles- 圆形缩放directional-left/right/up/down- 方向性转场(别名)
支持所有 gl-transitions 转场效果。
✨ 动画系统
预设动画
// 使用预设动画名称
animations: ['fadeIn', 'bigIn', 'bounceIn', 'slideInLeft', 'rotate', 'scale']自定义动画
import { TransformAnimation, KeyframeAnimation } from 'fkbuilder';
// 变换动画
const transform = new TransformAnimation({
duration: 1.5,
delay: 0,
from: { scaleX: 0.5, scaleY: 0.5, rotation: 0, opacity: 0 },
to: { scaleX: 1, scaleY: 1, rotation: 360, opacity: 1 },
easing: 'ease-out',
});
// 关键帧动画
const keyframe = new KeyframeAnimation({
duration: 2,
keyframes: [
{ time: 0, value: { x: 0, y: 0 } },
{ time: 0.5, value: { x: 100, y: 50 } },
{ time: 1, value: { x: 200, y: 0 } },
],
property: 'position',
easing: 'ease-in-out',
});
// 添加到元素
element.addAnimation(transform);
element.addAnimation(keyframe);onFrame 持续动画
onFrame 回调函数可以在每一帧更新元素,实现持续动画效果(如旋转、脉冲、闪烁等):
import { withContext } from 'fkbuilder';
// 持续旋转的圆形
const rotationSpeed = 3;
const onFrame = withContext((element, progress, time) => {
element.rotation += rotationSpeed;
const pulse = 1 + Math.sin(time * 4) * 0.2;
if (element.config) {
element.config.scaleX = pulse;
element.config.scaleY = pulse;
}
}, { rotationSpeed });
scene.addCircle({
x: '50%',
y: '50%',
radius: 100,
fillColor: '#4ECDC4',
duration: 10,
startTime: 0,
onFrame: onFrame,
});上下文关联(并行渲染支持):
在并行渲染中,闭包变量会丢失。使用 withContext 可以自动关联上下文变量:
import { withContext } from 'fkbuilder';
const rotationSpeed = 3;
const phaseOffset = 0.5;
// 使用 withContext 自动关联上下文
const onFrame = withContext((element, progress, time) => {
element.rotation += rotationSpeed;
const pulse = 1 + Math.sin(time * 4 + phaseOffset) * 0.2;
if (element.config) {
element.config.scaleX = pulse;
element.config.scaleY = pulse;
}
}, { rotationSpeed, phaseOffset }); // ES6 简写语法
element.onFrame = onFrame;⚡ 并行渲染
FKbuilder 支持 Worker Threads 并行渲染,大幅提升渲染性能。
await builder.render(outputPath, {
parallel: true, // 启用并行渲染
usePipe: true, // 使用管道模式(推荐,内存占用低)
maxWorkers: 4, // Worker 数量(默认根据 CPU 核心数)
});渲染模式:
- 串行渲染 (
parallel: false) - 单线程渲染,支持所有功能 - 并行渲染 (
parallel: true) - 多线程渲染,支持大部分功能- 管道模式 (
usePipe: true) - 实时写入 FFmpeg,内存占用低(推荐) - 文件模式 (
usePipe: false) - 先保存帧文件,再编码,适合调试
- 管道模式 (
并行渲染特性:
- ✅ 支持所有元素类型
- ✅ 支持动画和转场效果
- ✅ 支持
onFrame持续动画(需使用withContext) - ✅ 支持组件
- ✅ 支持字体注册
- ✅ 自动处理转场帧(主线程预处理)
🎯 预设动画列表
fadeIn- 淡入fadeOut- 淡出zoomIn- 放大进入zoomOut- 放大退出bigIn- 放大进入bigOut- 放大退出bounceIn- 弹跳进入bounceOut- 弹跳退出slideInLeft- 从左滑入slideInRight- 从右滑入slideInUp- 从上滑入slideInDown- 从下滑入slideInTop- 从顶部滑入slideInBottom- 从底部滑入slideOutLeft- 向左滑出slideOutRight- 向右滑出slideOutUp- 向上滑出slideOutDown- 向下滑出fadeInUp- 淡入上移fadeInDown- 淡入下移rotate- 旋转scale- 缩放bounce- 弹跳
🎬 转场效果列表
支持所有 gl-transitions 转场效果,包括:
fade- 淡入淡出CrossZoom- 交叉缩放CircleCrop- 圆形裁剪LinearBlur- 线性模糊Swirl- 漩涡Directional- 方向擦除Bounce- 弹跳Dreamy- 梦幻Radial- 径向GridFlip- 网格翻转Mosaic- 马赛克PolkaDotsCurtain- 圆点窗帘ZoomInCircles- 圆形缩放directional-left/right/up/down- 方向性转场(别名)
更多转场效果请参考 gl-transitions。
📖 完整示例
多轨道多场景示例
import { VideoBuilder } from 'fkbuilder';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
async function createVideo() {
const builder = new VideoBuilder({
width: 1920,
height: 1080,
fps: 30,
});
// 轨道1:主内容
const track1 = builder.createTrack({ zIndex: 1 });
let currentTime = 0;
const sceneDuration = 4;
const transitionDuration = 1;
// 场景1
const scene1 = track1.createScene({
duration: sceneDuration,
startTime: currentTime,
})
.addBackground({ color: '#1a1a2e' })
.addText({
text: '场景 1',
x: '50%',
y: '50%',
fontSize: 100,
color: '#ffffff',
textAlign: 'center',
duration: sceneDuration,
startTime: 0,
animations: ['fadeIn'],
});
currentTime += sceneDuration;
// 场景2
const scene2StartTime = currentTime - transitionDuration;
const scene2 = track1.createScene({
duration: sceneDuration,
startTime: scene2StartTime,
})
.addBackground({ color: '#2d3436' })
.addText({
text: '场景 2',
x: '50%',
y: '50%',
fontSize: 100,
color: '#ffffff',
textAlign: 'center',
duration: sceneDuration,
startTime: 0,
animations: ['fadeIn'],
});
// 添加转场(从场景1转到场景2)
track1.addTransition({
name: 'CrossZoom',
duration: transitionDuration,
startTime: scene2StartTime, // 转场结束时间 = 场景2开始时间
});
// 轨道2:叠加层
const track2 = builder.createTrack({ zIndex: 2 });
const overlay = track2.createScene({ duration: 8, startTime: 0 })
.addText({
text: '顶部标题',
x: '50%',
y: '10%',
fontSize: 48,
color: '#f39c12',
textAlign: 'center',
duration: 8,
startTime: 0,
});
// 渲染视频
const outputPath = path.join(__dirname, 'output/video.mp4');
await builder.render(outputPath, {
parallel: true,
usePipe: true,
maxWorkers: 4,
});
}
createVideo().catch(console.error);组件使用示例
import { VideoBuilder, Component } from 'fkbuilder';
const builder = new VideoBuilder({
width: 1920,
height: 1080,
fps: 30,
});
const track = builder.createTrack({ zIndex: 1 });
// 创建一个可复用的卡片组件
const cardComponent = new Component({
name: 'Card',
width: 400,
height: 300,
x: '50%',
y: '50%',
anchor: [0.5, 0.5],
startTime: 0,
duration: 5,
});
// 在组件内添加元素(使用相对坐标)
cardComponent
.addBackground({ color: '#2e3b3c' })
.addRect({
x: '50%', // 相对于组件中心
y: '50%',
width: '90%', // 相对于组件宽度
height: '85%', // 相对于组件高度
fillColor: '#5acbed',
borderRadius: 20,
})
.addText({
text: '卡片标题',
x: '50%',
y: '30%',
fontSize: 36,
color: '#ffffff',
textAlign: 'center',
});
// 在场景中使用组件
const scene = track.createScene({ duration: 5, startTime: 0 });
scene.addBackground({ color: '#1a1a2e' });
scene.addComponent(cardComponent);
// 可以复用组件,改变位置和时间
const scene2 = track.createScene({ duration: 5, startTime: 5 });
scene2.addBackground({ color: '#1a1a2e' });
scene2.addComponent({
...cardComponent,
x: '25%', // 不同的位置
y: '50%',
});
await builder.render('./output/video.mp4');onFrame 持续动画示例
import { VideoBuilder, withContext } from 'fkbuilder';
const builder = new VideoBuilder({
width: 1920,
height: 1080,
fps: 60,
});
const track = builder.createTrack({ zIndex: 1 });
const scene = track.createScene({ duration: 10, startTime: 0 });
scene.addBackground({ color: '#0a0a0a' });
// 持续旋转的圆形
const rotationSpeed = 3;
const onFrameRotate = withContext((element, progress, time) => {
element.rotation += rotationSpeed;
}, { rotationSpeed });
scene.addCircle({
x: '30%',
y: '50%',
radius: 100,
fillColor: '#4ECDC4',
duration: 10,
startTime: 0,
onFrame: onFrameRotate,
});
// 脉冲动画
const pulseSpeed = 4;
const pulseAmplitude = 0.2;
const onFramePulse = withContext((element, progress, time) => {
const pulse = 1 + Math.sin(time * pulseSpeed) * pulseAmplitude;
if (element.config) {
element.config.scaleX = pulse;
element.config.scaleY = pulse;
}
}, { pulseSpeed, pulseAmplitude });
scene.addCircle({
x: '70%',
y: '50%',
radius: 100,
fillColor: '#FF6B6B',
duration: 10,
startTime: 0,
onFrame: onFramePulse,
});
await builder.render('./output/video.mp4', {
parallel: true,
usePipe: true,
});文字拆分动画示例
scene.addText({
text: 'FKbuilder',
x: '50%',
y: '50%',
fontSize: 120,
color: '#ffffff',
textAlign: 'center',
duration: 5,
startTime: 0,
split: 'letter', // 逐字拆分
splitDelay: 0.1, // 每个字符延迟 0.1 秒
animations: ['fadeIn'], // 每个字符的动画
textShadow: true,
stroke: true,
strokeColor: '#000000',
strokeWidth: 2,
});文本效果示例
scene.addText({
text: '渐变文字',
x: '50%',
y: '50%',
fontSize: 100,
textAlign: 'center',
duration: 5,
startTime: 0,
// 渐变效果
gradient: true,
gradientColors: ['#FF6B6B', '#4ECDC4', '#45B7D1'],
gradientDirection: 'horizontal', // 'horizontal', 'vertical', 'diagonal'
// 阴影效果
textShadow: true,
textShadowColor: '#000000',
textShadowBlur: 20,
textShadowOffsetX: 5,
textShadowOffsetY: 5,
// 发光效果
textGlow: true,
textGlowColor: '#FFFFFF',
textGlowBlur: 30,
textGlowIntensity: 1,
// 描边效果
stroke: true,
strokeColor: '#000000',
strokeWidth: 3,
strokeStyle: 'solid', // 'solid', 'dashed', 'dotted'
});🔧 单位系统
FKbuilder 支持多种单位,方便响应式设计:
- 百分比 (
%) - 相对于父容器 - 视口单位 (
vw,vh) - 相对于视频尺寸 - 响应式像素 (
rpx) - 类似小程序 rpx,750rpx = 100% width - 像素 (
px) - 绝对像素值
element.addText({
x: '50%', // 水平居中
y: '30vh', // 距离顶部 30% 视频高度
width: '80vw', // 宽度为 80% 视频宽度
fontSize: '5rpx', // 响应式字体大小
});📁 项目结构
FKbuilder/
├── src/
│ ├── core/ # 核心类(VideoMaker, Renderer, VideoExporter)
│ ├── elements/ # 元素类(Text, Image, Video, Shape 等)
│ ├── layers/ # 图层类
│ ├── animations/ # 动画类
│ ├── builder/ # 构建器类(VideoBuilder, Track, Scene, Component, Transition)
│ ├── utils/ # 工具函数
│ ├── workers/ # Worker 线程(并行渲染)
│ └── types/ # 类型定义
├── examples/ # 使用示例
├── assets/ # 资源文件
├── output/ # 输出目录
└── docs/ # 文档📝 示例文件
查看 examples/ 目录获取更多示例:
cool-video.js- 酷炫视频示例cool-video-with-context.js- 上下文关联示例test-component.js- 组件使用示例demo-video.js- 完整功能演示project-intro-video.js- 项目简介视频示例test-worker-parallel-rendering.js- 并行渲染性能测试
运行示例:
node examples/cool-video.js
node examples/test-component.js
node examples/demo-video.js🚀 性能优化
并行渲染
对于长视频(>100 帧),建议使用并行渲染:
await builder.render(outputPath, {
parallel: true,
usePipe: true,
maxWorkers: 4, // 根据 CPU 核心数调整
});管道模式
管道模式可以大幅降低内存占用,推荐使用:
await builder.render(outputPath, {
usePipe: true, // 使用管道模式(默认)
});📄 API 参考
VideoBuilder
const builder = new VideoBuilder(config);
builder.createTrack(config);
builder.render(outputPath, options);
builder.export(outputPath, options);
builder.build();
builder.initialize();Track
const track = builder.createTrack(config);
track.createScene(config);
track.addTransition(config);
track.addComponent(component);Scene
const scene = track.createScene(config);
scene.addBackground(config);
scene.addText(config);
scene.addImage(config);
scene.addVideo(config);
scene.addRect(config);
scene.addCircle(config);
scene.addPath(config);
scene.addSVG(config);
scene.addJSON(config);
scene.addAudio(config);
scene.addSubtitle(config);
scene.addOscilloscope(config);
scene.addComponent(component);Component
const component = new Component(config);
component.addBackground(config);
component.addText(config);
component.addImage(config);
// ... 支持所有元素类型工具函数
import { withContext, autoContext, smartContext } from 'fkbuilder';
// 上下文关联(用于并行渲染)
const onFrame = withContext((element, progress, time) => {
// 使用上下文变量
}, { variable1, variable2 });📄 许可证
MIT
🤝 贡献
欢迎提交 Issue 和 Pull Request!
