功能展示——图片选择器、图片预览、9宫格展示、图片选择器


一、项目地址

参考项目:地址

由我改造:地址

二、效果图

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

<template> <div class="page-wrapper"> <!-- 顶部标题 --> <header class="page-header"> <h1>图片生成视频</h1> </header> <!-- 主内容区 --> <main class="main-container"> <!-- 左侧操作栏 (734px) --> <section class="left-box"> <!-- 生成参数标题 --> <div class="section-title">生成参数</div> <!-- 模型选择 --> <div class="form-item"> <el-select v-model="form.model" placeholder="模型选择" class="full-width-select" popper-class="custom-dropdown"> <el-option label="通用视频模型 v1.0" value="v1"></el-option> <el-option label="动漫增强模型 v2.0" value="v2"></el-option> </el-select> </div> <!-- 提示词输入 --> <div class="form-item"> <div class="prompt-label">提示词</div> <div class="textarea-container"> <el-input type="textarea" :rows="5" placeholder="描述你想要融合的图片" v-model="form.prompt" resize="none" class="custom-textarea"></el-input> <div class="upload-trigger" @click="triggerUpload"> <i class="el-icon-link"></i> 上传图片 </div> <!-- 隐藏的文件输入 --> <input type="file" ref="fileInput" style="display: none" accept="image/*" @change="onFileChange" /> </div> </div> <!-- 比例选择 --> <div class="form-item row-flex"> <span class="label-text">比例</span> <div class="options-group"> <div class="option-pill" :class="{ active: form.ratio === &#39;vertical&#39; }" @click="form.ratio = &#39;vertical&#39;"> 竖屏 (手机) </div> <div class="option-pill" :class="{ active: form.ratio === &#39;horizontal&#39; }" @click="form.ratio = &#39;horizontal&#39;"> 横屏 (电脑) </div> </div> </div> <!-- 时长选择 --> <div class="form-item row-flex"> <span class="label-text">时长</span> <div class="options-group"> <div v-for="time in durations" :key="time.val" class="option-tag" :class="{ active: form.duration === time.val }" @click="form.duration = time.val"> {{ time.label }} </div> </div> </div> <!-- 风格选择 --> <div class="form-item"> <div class="label-text mb-10">风格选择</div> <div class="style-grid"> <div v-for="(item, index) in 4" :key="index" class="style-box" :class="{ active: form.styleIndex === index }" @click="form.styleIndex = index"> 风格{{ index + 1 }} </div> </div> </div> <!-- 是否生成拼图 --> <div class="form-item row-flex space-between"> <span class="label-text">是否生成拼图</span> <div class="select-wrapper-small"> <el-select v-model="form.gridType" size="small"> <el-option label="四宫格" value="4"></el-option> <el-option label="单张" value="1"></el-option> </el-select> </div> </div> <!-- 信息展示栏 --> <div class="info-panel"> <div class="info-row"> <span class="info-label">当前模型:</span> <span class="info-val">{{ currentModelText }}</span> </div> <div class="info-row"> <span class="info-label">预计消耗:</span> <span class="info-val">3-5 分钟</span> </div> </div> <!-- 提交次数 --> <div class="form-item row-flex space-between counter-area"> <span class="label-text">提交次数</span> <div class="custom-counter"> <button class="counter-btn" @click="handleCount(-1)" :disabled="form.count <= 1">-</button> <input type="text" class="counter-input" v-model="form.count" readonly /> <button class="counter-btn" @click="handleCount(1)">+</button> </div> </div> <!-- 底部大按钮 --> <el-button type="primary" class="submit-btn" @click="startGenerate">开始生成</el-button> </section> <!-- 右侧展示栏 --> <section class="right-box"> <!-- 图片/视频预览区 --> <div class="preview-area"> <div class="placeholder-content"> <img v-if="previewImage" :src="previewImage" alt="预览图" /> <div v-else class="placeholder-bg">点击左侧“上传图片”添加素材</div> </div> </div> <!-- 底部按钮组 --> <div class="action-buttons"> <el-button type="primary" class="btn-capcut">导出剪映</el-button> <el-button plain class="btn-download"> <i class="el-icon-download"></i> 下载 </el-button> </div> </section> </main> </div> </template> <script> export default { name: &#39;ImageToVideo&#39;, data() { return { form: { model: &#39;&#39;, prompt: &#39;&#39;, ratio: &#39;vertical&#39;, duration: &#39;25s&#39;, styleIndex: null, gridType: &#39;4&#39;, count: 1 }, durations: [{ label: &#39;10秒 (普通)&#39;, val: &#39;10s&#39; }, { label: &#39;15秒 (普通)&#39;, val: &#39;15s&#39; }, { label: &#39;25秒 (Pro普通)&#39;, val: &#39;25s&#39; }, { label: &#39;12秒 (Pro普通)&#39;, val: &#39;12s&#39; } ], previewImage: &#39;&#39; // 存储上传的图片预览 URL }; }, computed: { currentModelText() { return this.form.model === &#39;v1&#39; ? &#39;通用视频模型 v1.0&#39; : this.form.model === &#39;v2&#39; ? &#39;动漫增强模型 v2.0&#39; : &#39;未选择&#39;; } }, methods: { handleCount(step) { const newVal = this.form.count + step; if (newVal >= 1) this.form.count = newVal; }, startGenerate() { if (!this.form.model || !this.form.prompt.trim()) { this.$message.error(&#39;请填写模型和提示词!&#39;); return; } this.$message.success(`开始生成 ${this.form.count} 个视频任务`); }, triggerUpload() { this.$refs.fileInput.click(); }, onFileChange(e) { const file = e.target.files?.[0]; if (!file) return; if (!file.type.startsWith(&#39;image/&#39;)) { this.$message.warning(&#39;请选择有效的图片文件&#39;); return; } const reader = new FileReader(); reader.onload = () => { this.previewImage = reader.result; this.$message.success(&#39;图片上传成功&#39;); }; reader.readAsDataURL(file); } } }; </script> <style scoped> * { box-sizing: border-box; } .page-wrapper { background-color: #fff; color: #333; padding: 30px 16px; font-family: -apple-system, BlinkMacSystemFont, &#39;Segoe UI&#39;, Roboto, &#39;Helvetica Neue&#39;, Arial, sans-serif; width: 100%; box-sizing: border-box; } /* 头部与主容器设置最大宽度并居中 */ .page-header.main-container { width: 100%; max-width: 1468px; /* 1500 - 32 (两边16px) */ /* margin: 0 auto; */ /* 关键:水平居中,确保左右间距一致 */ } .main-container { width: 100%; max-width: 1468px; /* 1500 - 32 (两边16px) */ display: flex; justify-content: space-between; /* margin: 0 auto; */ /* 关键:水平居中,确保左右间距一致 */ } .page-header h1 { font-size: 20px; font-weight: 600; margin: 0; color: #1f2d3d; border-bottom: 1px solid #ebeef5; padding-bottom: 15px; } .main-container { display: flex; justify-content: space-between; gap: 32px; margin-top: 24px; } /* --- 左侧样式 --- */ .left-box { width: 734px; flex-shrink: 0; } .section-title { font-size: 16px; font-weight: bold; margin-bottom: 20px; color: #303133; } .form-item { margin-bottom: 24px; } .full-width-select { width: 100%; } ::v-deep .el-input__inner, ::v-deep .el-textarea__inner { background-color: #f7f8fa; border-color: transparent; border-radius: 6px; } ::v-deep .el-input__inner:focus, ::v-deep .el-textarea__inner:focus { background-color: #fff; border-color: #409eff; } .prompt-label { font-size: 14px; margin-bottom: 8px; font-weight: 500; } .textarea-container { position: relative; } .custom-textarea ::v-deep .el-textarea__inner { padding-bottom: 30px; height: 120px; } .upload-trigger { position: absolute; bottom: 10px; right: 15px; color: #909399; font-size: 13px; cursor: pointer; z-index: 10; } .upload-trigger:hover { color: #409eff; } /* Flex 行 */ .row-flex { display: flex; align-items: center; } .space-between { justify-content: space-between; } .label-text { font-size: 14px; font-weight: 500; width: 50px; flex-shrink: 0; margin-right: 10px; } .mb-10 { margin-bottom: 10px; display: block; } /* 胶囊选项组 */ .options-group { display: flex; flex-wrap: wrap; gap: 12px; } .option-pill { padding: 6px 20px; border-radius: 20px; font-size: 13px; cursor: pointer; background-color: transparent; color: #606266; border: 1px solid transparent; transition: all 0.3s; } .option-pill:hover { background-color: #f0f2f5; } .option-pill.active { background-color: #0066cc; color: #fff; box-shadow: 0 2px 6px rgba(0, 102, 204, 0.3); } .option-tag { padding: 6px 12px; border-radius: 4px; background-color: #f2f3f5; color: #606266; font-size: 12px; cursor: pointer; transition: all 0.2s; } .option-tag:hover { background-color: #e4e7ed; } .option-tag.active { background-color: #0066cc; color: white; } /* 风格网格 */ .style-grid { display: flex; gap: 12px; } .style-box { flex: 1; aspect-ratio: 1; background-color: #d9d9d9; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 12px; cursor: pointer; border: 2px solid transparent; } .style-box:hover { opacity: 0.9; } .style-box.active { border-color: #0066cc; } .select-wrapper-small { width: 120px; } /* 信息面板 */ .info-panel { background-color: #f7f8fa; border-radius: 6px; padding: 16px; margin-bottom: 24px; } .info-row { font-size: 14px; margin-bottom: 8px; display: flex; } .info-row:last-child { margin-bottom: 0; } .info-label { color: #303133; width: 80px; } .info-val { color: #909399; } /* 计数器 */ .custom-counter { display: flex; align-items: center; } .counter-btn { width: 32px; height: 32px; background-color: #f7f8fa; border: 1px solid #dcdfe6; color: #606266; cursor: pointer; outline: none; display: flex; align-items: center; justify-content: center; } .counter-btn:first-child { border-radius: 4px 0 0 4px; border-right: none; } .counter-btn:last-child { border-radius: 0 4px 4px 0; border-left: none; } .counter-btn:hover:not(:disabled) { color: #409eff; background-color: #fff; } .counter-input { width: 60px; height: 32px; text-align: center; border: 1px solid #dcdfe6; outline: none; font-size: 14px; color: #606266; } .counter-input:focus { border-color: #409eff; z-index: 1; } .submit-btn { width: 100%; height: 44px; font-size: 16px; background-color: #0066cc; border-color: #0066cc; } .submit-btn:hover { background-color: #0052a3; border-color: #0052a3; } /* --- 右侧样式 --- */ .right-box { width: 734px; flex-shrink: 0; display: flex; flex-direction: column; } .preview-area { width: 100%; flex: 1; min-height: 600px; background-color: #e6e6e6; border-radius: 8px; overflow: hidden; margin-bottom: 20px; position: relative; } .placeholder-content { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: #999; font-size: 14px; background-color: #f9f9f9; } .placeholder-content img { width: 100%; height: 100%; object-fit: cover; display: block; } .action-buttons { display: flex; justify-content: flex-end; gap: 15px; } .btn-capcut { background-color: #0066cc; border-color: #0066cc; } .btn-download { color: #0066cc; border-color: #0066cc; } .btn-download:hover { background-color: #ecf5ff; border-color: #0066cc; color: #0066cc; } </style> 为什么左右盒子的flex布局最右边的还有空
最新发布
12-21
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值