vue3+html2canvas+interact实现类似剪影的可视化拖拽时间轴轨道视频动画制作代码
代码语言:html
所属分类:多媒体
代码描述:vue3+html2canvas+interact实现类似剪影的可视化拖拽时间轴视频动画制作代码,可拖拽svg、图片、文字、及声音到轨道上,可设置元素属性及入场出场动画,可拖拽设置持续时间,最终可预览视频动画效果,导出json格式的时间轴轨道数据。
代码标签: vue3 html2canvas interact 类似 剪影 可视化 拖拽 时间轴 视频 动画 制
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>简易动画剪辑器</title> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/interact.js/1.10.17/interact.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> <style> :root { --primary-color: #4361ee; --secondary-color: #3f37c9; --background-color: #f8f9fa; --timeline-bg: #e9ecef; --track-bg: #dee2e6; --clip-bg: #4361ee; --clip-border: #3a0ca3; --text-color: #212529; --error-color: #dc3545; --track-label-width: 100px; /* Define as CSS variable for consistency */ } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--background-color); color: var(--text-color); height: 100vh; display: flex; flex-direction: column; } .app-container { display: flex; flex-direction: column; height: 100vh; overflow: hidden; } .top-bar { display: flex; justify-content: space-between; align-items: center; padding: 10px 20px; background-color: var(--primary-color); color: white; } .logo { font-size: 1.5rem; font-weight: bold; } .actions button { background-color: var(--secondary-color); color: white; border: none; border-radius: 4px; padding: 8px 15px; margin-left: 10px; cursor: pointer; transition: background-color 0.2s; } .actions button:hover { background-color: #2a0f8a; } .main-content { display: flex; flex: 1; overflow: hidden; } .elements-panel { width: 250px; background-color: white; border-right: 1px solid #ddd; padding: 15px; overflow-y: auto; } .panel-title { margin-bottom: 15px; font-size: 1.1rem; font-weight: bold; } .element-item { padding: 10px; margin-bottom: 8px; background-color: #f1f3f5; border-radius: 4px; cursor: move; transition: background-color 0.2s; user-select: none; } .element-item:hover { background-color: #e9ecef; } .element-item i { margin-right: 8px; } .preview-area { flex: 1; display: flex; flex-direction: column; position: relative; overflow: hidden; } .preview-canvas { flex: 1; background-color: #333; position: relative; overflow: hidden; } .canvas-container { width: 720px; height: 405px; background-color: #000; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); overflow: hidden; } .canvas-element { position: absolute; cursor: move; user-select: none; border: 2px solid transparent; } .canvas-element.selected { border: 2px solid #f00; } .canvas-element.text { min-width: 100px; min-height: 40px; padding: 5px; color: white; font-size: 20px; } .canvas-element.image, .canvas-element.svg { min-width: 100px; min-height: 100px; } .timeline-panel { height: 250px; background-color: var(--timeline-bg); border-top: 1px solid #ccc; display: flex; flex-direction: column; } .timeline-controls { display: flex; align-items: center; padding: 10px; border-bottom: 1px solid #ccc; } .timeline-controls button { background-color: var(--primary-color); color: white; border: none; border-radius: 4px; padding: 5px 10px; margin-right: 10px; cursor: pointer; } .timeline-controls button:hover { background-color: var(--secondary-color); } .timeline-controls .time-display { margin-left: auto; font-family: monospace; font-size: 1.1rem; } .timeline-area { flex: 1; display: flex; /* Changed from block to flex */ overflow-x: auto; position: relative; } .timeline-tracks { /* This will contain markers and all tracks */ flex: 1; display: flex; flex-direction: column; position: relative; /* Important for absolute positioning of playhead and markers */ /* min-width needs to be dynamic or large enough to accommodate totalDuration */ } .time-markers { height: 20px; background-color: #d8d8d8; position: sticky; /* Sticky to the top of timeline-tracks */ top: 0; z-index: 2; display: flex; /* Not strictly necessary, markers are absolute */ border-bottom: 1px solid #aaa; width: 100%; /* Ensure it spans full width */ } .time-marker { position: absolute; font-size: 10px; color: #333; text-align: center; border-left: 1px solid #aaa; height: 20px; display: flex; align-items: flex-end; justify-content: center; padding-bottom: 2px; /* width will be set by pixelsPerSecond or major tick logic */ } .playhead { position: absolute; top: 0; /* Covers markers and tracks */ height: 100%; width: 2px; background-color: red; z-index: 3; pointer-events: none; } .track { height: 60px; background-color: var(--track-bg); border-bottom: 1px solid #ccc; position: relative; display: flex; /* To align track-label and track-clips-area */ } .track-label { width: var(--track-label-width); min-width: var(--track-label-width); /* Prevent shrinking */ height: 100%; background-color: #d0d0d0; display: flex; align-items: center; justify-content: center; border-right: 1px solid #aaa; position: sticky; left: 0; z-index: 1; /* Above track clips but below timeline markers/playhead if they overlap */ } .track-clips-area { /* Container for clips within a track, after the label */ position: relative; /* Clips will be positioned relative to this */ height: 100%; flex-grow: 1; /* Takes up remaining space in the track */ /* Left padding of track-label-width is handled by JS logic now */ } .clip { position: absolute; height: 50px; top: 5px; background-color: var(--clip-bg); border: 1px solid var(--clip-border); border-radius: 4px; display: flex; align-items: center; justify-content: center; color: white; font-size: 12px; overflow: hidden; cursor: move; user-select: none; padding: 0 10px; box-sizing: border-box; } .clip.conflict { border: 2px solid var(--error-color); background-color: rgba(220, 53, 69, 0.7); } .clip .handle-left, .clip .handle-right { position: absolute; top: 0; width: 8px; height: 100%; background-color: rgba(0, 0, 0, 0.2); cursor: ew-resize; z-index: 1; } .clip .handle-left { left: 0; } .clip .handle-right { right: 0; } .toast-message { position: fixed; top: 20px; right: 20px; background-color: var(--error-color); color: white; padding: 10px 15px; border-radius: 4px; z-index: 1000; animation: fadeOut 3s forwards; max-width: 300px; } @keyframes fadeOut { 0% .........完整代码请登录后点击上方下载按钮下载查看
网友评论0