vue3实现模拟剪影多轨道视频动画设计ui代码
代码语言:html
所属分类:布局界面
代码描述:vue3实现模拟剪影多轨道视频动画设计ui代码
代码标签: vue 模拟 剪影 多轨道 视频 动画 设计 ui 代码
下面为部分代码预览,完整代码请点击下载或在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; } .actions button:disabled { background-color: #aaa; cursor: not-allowed; } .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; display: flex; /* For centering canvas-container during recording if needed */ align-items: center; justify-content: center; } .canvas-container { width: 720px; height: 405px; background-color: #000; position: absolute; /* Keeps it centered visually */ 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 button:disabled { background-color: #aaa; cursor: not-allowed; } .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 */ } .time-markers { height: 20px; background-color: #d8d8d8; position: sticky; /* Sticky to the top of timeline-tracks */ top: 0; z-index: 2; display: flex; 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; } .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; } .track-clips-area { position: relative; height: 100%; flex-grow: 1; } .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: fadeOutToast 3s forwards; max-width: 300px; } .toast-message.success { background-color: var(--primary-color); } .toast-message.info { background-color: #17a2b8; animation-duration: 5s; /* Longer for info */ } @keyframes fadeOutToast { /* Renamed to avoid conflict if any other fadeOut exists */ 0% { opacity: 1; } 80% { opacity: 1; } 100% { opacity: 0; } } .property-panel { width: 300px; background-color: white; border-left: 1px solid #ddd; padding: 15px; overflow-y: auto; } .property-group { margin-bottom: 15px; } .property-title { font-weight: bold; margin-bottom: 8px; } .property-field { margin-bottom: 10px; } .property-field label { display: block; margin-bottom: 5px; font-size: 0.9rem; } .property-field input, .property-field select { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; } .animation-select { display: flex; gap: 5px; } .animation-select select { flex: 1; } .import-export { margin-top: 20px; } .import-export textarea { width: 100%; height: 100px; margin-top: 10px; padding: 8px; border: 1px solid #ddd; border-radius: 4px; resize: vertical; } @media (max-width: 1200px) { .main-content { flex-direction: column; } .elements-panel, .property-panel { width: 100%; max-height: 200px; border: none; border-bottom: 1px solid #ddd; } .preview-area { height: 50vh; } } </style> </head> <body> <div id="app" class="app-container"> <div class="top-bar"> <div class="logo">简易动画剪辑器</div> <div class="actions"> <button @click="previewAnimation" :disabled="isRecording">预览</button> <button @click="exportVideo" :disabled="isRecording"> <i class="fas fa-video"></i> {{ isRecording ? `录制中 ${Math.round(recordingProgress * 100)}%` : '导出视频 (WEBM)' }} </button> <button @click="exportConfig" :disabled="isRecording">导.........完整代码请登录后点击上方下载按钮下载查看
网友评论0