Commit c5de000f authored by lipengcheng 's avatar lipengcheng

x

parent 396049ae
...@@ -11,7 +11,7 @@ charset = utf-8 ...@@ -11,7 +11,7 @@ charset = utf-8
indent_style = space indent_style = space
#缩进数量可选整数值2 or 4,或者tab #缩进数量可选整数值2 or 4,或者tab
indent_size = 2 indent_size = 4
#换行符的格式 换行符,lf、cr和crlf #换行符的格式 换行符,lf、cr和crlf
end_of_line = lf end_of_line = lf
...@@ -23,4 +23,4 @@ insert_final_newline = true ...@@ -23,4 +23,4 @@ insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
[*.scss] [*.scss]
indent_size = 2 indent_size = 4
module.exports = { module.exports = {
root: true, root: true,
env: { env: {
node: true node: true
}, },
// 1: ESLint with error prevention only // 1: ESLint with error prevention only
// extends: ['plugin:vue/essential', 'eslint:recommended'], // extends: ['plugin:vue/essential', 'eslint:recommended'],
// 2: ESLint + Airbnb config // 2: ESLint + Airbnb config
// extends: ['plugin:vue/essential', '@vue/airbnb',], // extends: ['plugin:vue/essential', '@vue/airbnb',],
// 3: ESLint + Standard config // 3: ESLint + Standard config
// extends: [ 'plugin:vue/essential', '@vue/airbnb',], // extends: [ 'plugin:vue/essential', '@vue/airbnb',],
// ESLint + Prettier // ESLint + Prettier
extends: ['plugin:vue/recommended', 'eslint:recommended'], extends: ['plugin:vue/recommended', 'eslint:recommended', '@vue/prettier'],
plugins: [], plugins: [],
parserOptions: { parserOptions: {
parser: 'babel-eslint' parser: 'babel-eslint'
}, },
globals: { /**add your custom rules here
axios: false, //全局使用axios * 下面这些rules是用来设置从插件来的规范代码的规则,使用必须去掉前缀eslint-plugin-
__PROJECTPATH__: false, * 主要有如下的设置规则,可以设置字符串也可以设置数字,两者效果一致
__GATEWAYPATH__: false * "off" 或 0 - 关闭规则
}, * "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)
/**add your custom rules here * "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
* 下面这些rules是用来设置从插件来的规范代码的规则,使用必须去掉前缀eslint-plugin- */
* 主要有如下的设置规则,可以设置字符串也可以设置数字,两者效果一致 rules: {
* "off" 或 0 - 关闭规则 // 是否开启prettier校验,默认开启.可选 warn / error / off
* "warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出) // "prettier/prettier": "warn",
* "error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出) // "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
*/ 'no-console': [0, { llow: ['warn', 'error'] }],
rules: { 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
// 是否开启prettier校验,默认开启.可选 warn / error / off // indent: [
// "prettier/prettier": "warn", // 'error',
// "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", // 2,
'no-console': [0, { llow: ['warn', 'error'] }], // {
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', // SwitchCase: 1,
indent: [ // flatTernaryExpressions: true
'error', // }
2, // ],
{ // 'comma-dangle': ['error', 'never'],
SwitchCase: 1, // quotes: ['error', 'single'],
flatTernaryExpressions: true // semi: ['error', 'always'],
} // 'vue/html-indent': [
], // 'error',
'comma-dangle': ['error', 'never'], // 2,
quotes: ['error', 'single'], // {
semi: ['error', 'always'], // attribute: 1,
'vue/html-indent': [ // baseIndent: 1,
'error', // closeBracket: 0,
2, // alignAttributesVertically: true,
{ // ignores: []
attribute: 1, // }
baseIndent: 1, // ],
closeBracket: 0, // 'vue/html-self-closing': [
alignAttributesVertically: true, // 'error',
ignores: [] // {
} // html: {
], // void: 'never',
'vue/html-self-closing': [ // normal: 'never',
'error', // component: 'never'
{ // },
html: { // svg: 'never',
void: 'never', // math: 'always'
normal: 'never', // }
component: 'never' // ]
}, }
svg: 'never',
math: 'always'
}
]
}
} }
module.exports = { module.exports = {
// 不使用prettier格式化的文件填写在项目的.prettierignore文件中 // 不使用prettier格式化的文件填写在项目的.prettierignore文件中
ignorePath: ".prettierignore", // ignorePath: ".prettierignore",
// 与eslint集成(让prettier使用eslint的代码格式进行校验) // 与eslint集成(让prettier使用eslint的代码格式进行校验)
eslintIntegration: true, // eslintIntegration: true,
// 换行长度 // 换行长度
printWidth: 150, printWidth: 150,
// tab缩进大小,默认为2 // tab缩进大小,默认为2
tabWidth: 2, tabWidth: 4,
// 使用tab缩进,默认false // 使用tab缩进,默认false
useTabs: false, useTabs: false,
// 是否使用分号, 默认true // 是否使用分号, 默认true
...@@ -35,7 +35,7 @@ module.exports = { ...@@ -35,7 +35,7 @@ module.exports = {
// always 总是有括号 // always 总是有括号
arrowParens: 'always', arrowParens: 'always',
// 结尾是 \n \r \n\r auto // 结尾是 \n \r \n\r auto
endOfline: "auto", endOfLine: "auto",
// 在jsx中把'>' 是否单独放一行 // 在jsx中把'>' 是否单独放一行
jsxBracketSameLine: false, jsxBracketSameLine: false,
} }
......
...@@ -3,17 +3,17 @@ console.log('process.env:', process.env) ...@@ -3,17 +3,17 @@ console.log('process.env:', process.env)
console.log('process.env.NODE_ENV:', process.env.NODE_ENV) console.log('process.env.NODE_ENV:', process.env.NODE_ENV)
// //
switch (process.env.NODE_ENV) { switch (process.env.NODE_ENV) {
case 'development': case 'development':
baseUrl = 'http://localhost:3000/development' //开发环境url baseUrl = 'http://localhost:3000/development' //开发环境url
break break
case 'passports': // 注意这里的名字要和步骤二中设置的环境名字对应起来 case 'passports': // 注意这里的名字要和步骤二中设置的环境名字对应起来
baseUrl = 'http://localhost:3000/passports' //测试环境中的url baseUrl = 'http://localhost:3000/passports' //测试环境中的url
break break
case 'production': case 'production':
baseUrl = 'http://106.13.94.82:3000/production' //生产环境url baseUrl = 'http://106.13.94.82:3000/production' //生产环境url
break break
} }
export default baseUrl export default baseUrl
<template> <template>
<div id="app"> <div id="app">
<common-header></common-header> <common-header></common-header>
<body class="body-container"> <body class="body-container">
<side-nav></side-nav> <side-nav></side-nav>
<router-view style="flex:1;border: 1px solid #666;"></router-view> <router-view style="flex:1;border: 1px solid #666;"></router-view>
<right-panel></right-panel> <right-panel></right-panel>
</body> </body>
<modal-layer></modal-layer> <modal-layer></modal-layer>
<uploader></uploader> <uploader></uploader>
</div> </div>
</template> </template>
<script> <script>
import CommonHeader from '@/components/header/index.vue'; import CommonHeader from '@/components/header/index.vue'
export default { export default {
components: { components: {
CommonHeader, CommonHeader,
SideNav: () => import('@/components/sideNav/index.vue'), SideNav: () => import('@/components/sideNav/index.vue'),
RightPanel: () => import('@/components/rightPanel/index.vue'), RightPanel: () => import('@/components/rightPanel/index.vue'),
ModalLayer: () => import('@/components/modal/modalLayer.vue'), ModalLayer: () => import('@/components/modal/modalLayer.vue'),
Uploader: () => import('@/components/misc/uploader.vue') Uploader: () => import('@/components/misc/uploader.vue')
}, },
data() { data() {
return {}; return {}
}, },
async created() { async created() {
let result = await this.$http.get('/webapi/home/banner?type=1&category=18'); let result = await this.$http.get('/webapi/home/banner?type=1&category=18')
console.log('result:', result); console.log('result:', result)
} }
}; }
</script> </script>
<style lang="scss"> <style lang="scss">
#app { #app {
font-family: Avenir, Helvetica, Arial, sans-serif; font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
text-align: center; text-align: center;
color: #2c3e50; color: #2c3e50;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100vh; height: 100vh;
position: relative; position: relative;
} }
.body-container { .body-container {
flex: 1; flex: 1;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
overflow: hidden; overflow: hidden;
} }
</style> </style>
<template> <template>
<div class="comp-commonheader"> <div class="comp-commonheader">
<h1>LAIHUA</h1> <h1>LAIHUA</h1>
<div class="current-page"> <div class="current-page">
当前的宝 当前的宝
</div>
<tip-panel></tip-panel>
<div class="show-modal" @click="showModal">
show-modal
</div>
</div> </div>
<tip-panel></tip-panel>
<div
class="show-modal"
@click="showModal"
>
show-modal
</div>
</div>
</template> </template>
<script> <script>
export default { export default {
components: { components: {
tipPanel: () => import('@/components/header/tipPanel.vue') tipPanel: () => import('@/components/header/tipPanel.vue')
}, },
data() { data() {
return {}; return {}
}, },
created() {}, created() {},
mounted() {}, mounted() {},
methods: { methods: {
showModal() { showModal() {
this.$modal.show('selectModal'); this.$modal.show('selectModal')
}
} }
} }
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
/* @import url(); 引入css类 */ /* @import url(); 引入css类 */
.comp-commonheader { .comp-commonheader {
width: 100%; width: 100%;
height: 100px; height: 100px;
border: 1px solid pink; border: 1px solid pink;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
} }
</style> </style>
<template> <template>
<div class="comp-header-tippanel"> <div class="comp-header-tippanel">
怎么操作? 怎么操作?
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
created() {}, created() {},
mounted() {} mounted() {}
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
......
<template> <template>
<div></div> <div></div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
methods: {} methods: {}
}; }
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<template> <template>
<div> <div>
<input <input id="video-input" ref="videoInput" type="file" accept="video/mp4, video/NMP4" @change="onVideoInputChange" @click="onInputClick" />
id="video-input" </div>
ref="videoInput"
type="file"
accept="video/mp4, video/NMP4"
@change="onVideoInputChange"
@click="onInputClick"
>
</div>
</template> </template>
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex'
export default { export default {
data() { data() {
return { return {
videoInput: {} videoInput: {}
}; }
},
mounted() {
this.videoInput = this.$refs.videoInput;
},
methods: {
...mapActions({
upload: 'uploader/upload'
}),
onVideoInputChange() {
let file = this.videoInput.files[0];
console.log('turbo: onVideoInputChange -> file', file);
}, },
onInputClick() { mounted() {
const vm = this; this.videoInput = this.$refs.videoInput
window.addEventListener('focus', function h() {
vm.clearInputValue(vm.videoInput);
console.log('turbo: h -> this.videoInput', vm.videoInput);
window.removeEventListener('focus', h);
});
}, },
clearInputValue(el) { methods: {
if (el) { ...mapActions({
el.value = ''; upload: 'uploader/upload'
} }),
onVideoInputChange() {
let file = this.videoInput.files[0]
console.log('turbo: onVideoInputChange -> file', file)
},
onInputClick() {
const vm = this
window.addEventListener('focus', function h() {
vm.clearInputValue(vm.videoInput)
console.log('turbo: h -> this.videoInput', vm.videoInput)
window.removeEventListener('focus', h)
})
},
clearInputValue(el) {
if (el) {
el.value = ''
}
}
} }
} }
};
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<template> <template>
<div> <div>
complete content complete content
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
methods: {} methods: {}
}; }
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<template> <template>
<modal <modal name="completeModal" :click-to-close="false">
name="completeModal" <complete-content></complete-content>
:click-to-close="false" </modal>
>
<complete-content></complete-content>
</modal>
</template> </template>
<script> <script>
import CompleteContent from './completeContent'; import CompleteContent from './completeContent'
export default { export default {
components: { components: {
CompleteContent CompleteContent
}, },
data() { data() {
return {}; return {}
}, },
methods: {} methods: {}
}; }
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<template> <template>
<div class="modal-layer"> <div class="modal-layer">
<complete-modal></complete-modal> <complete-modal></complete-modal>
<select-modal></select-modal> <select-modal></select-modal>
</div> </div>
</template> </template>
<script> <script>
import CompleteModal from '@/components/modal/completeModal'; import CompleteModal from '@/components/modal/completeModal'
import SelectModal from '@/components/modal/selectModal'; import SelectModal from '@/components/modal/selectModal'
export default { export default {
components: { components: {
CompleteModal, CompleteModal,
SelectModal SelectModal
}, },
data() { data() {
return {}; return {}
}, },
methods: {} methods: {}
}; }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.modal-layer { .modal-layer {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
width: 0; width: 0;
height: 0; height: 0;
} }
</style> </style>
<template> <template>
<div> <div>
<div <div class="close-btn" @click="close">
class="close-btn" close
@click="close" </div>
> <div>选择视频</div>
close <ul>
<li v-for="(item, i) in items" :key="i" class="item" @click="itemClick({ item, index: i })">
{{ item.text }}
</li>
</ul>
</div> </div>
<div>选择视频</div>
<ul>
<li
v-for="(item, i) in items"
:key="i"
class="item"
@click="itemClick({ item, index: i })"
>
{{ item.text }}
</li>
</ul>
</div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
items: [{ text: '本地上传', type: 'upload' }, { text: '视频库' }, { text: '我的作品' }] items: [{ text: '本地上传', type: 'upload' }, { text: '视频库' }, { text: '我的作品' }]
}; }
},
methods: {
close() {
this.$modal.hide('selectModal');
}, },
triggerUpload() { methods: {
const el = document.getElementById('video-input'); close() {
el && el.click(); this.$modal.hide('selectModal')
}, },
itemClick({ item = {} } = {}) { triggerUpload() {
if (item.type === 'upload') { const el = document.getElementById('video-input')
this.triggerUpload(); el && el.click()
} },
itemClick({ item = {} } = {}) {
if (item.type === 'upload') {
this.triggerUpload()
}
}
} }
} }
};
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<template> <template>
<modal <modal name="selectModal" :click-to-close="false">
name="selectModal" <select-content></select-content>
:click-to-close="false" </modal>
>
<select-content></select-content>
</modal>
</template> </template>
<script> <script>
import SelectContent from './selectContent'; import SelectContent from './selectContent'
export default { export default {
components: { components: {
SelectContent SelectContent
}, },
data() { data() {
return {}; return {}
}, },
methods: {} methods: {}
}; }
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>
<template> <template>
<div class="comp-rightpanel"> <div class="comp-rightpanel">
<router-view name="panel"></router-view> <router-view name="panel"></router-view>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
created() {}, created() {},
mounted() {} mounted() {}
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
/* @import url(); 引入css类 */ /* @import url(); 引入css类 */
.comp-rightpanel { .comp-rightpanel {
width: 150px; width: 150px;
height: 100%; height: 100%;
border: 1px solid skyblue; border: 1px solid skyblue;
} }
</style> </style>
<template> <template>
<div> <div>
screenshotPanel screenshotPanel
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
created() {}, created() {},
mounted() {} mounted() {}
}; }
</script> </script>
<style></style> <style></style>
<template> <template>
<div class="comp-sidenav"> <div class="comp-sidenav">
<router-link to="/"> <router-link to="/">
Home Home
</router-link> </router-link>
<router-link to="/about"> <router-link to="/about">
About About
</router-link> </router-link>
<router-link to="/cutter"> <router-link to="/cutter">
cutter cutter
</router-link> </router-link>
<router-link to="/videoConverter"> <router-link to="/videoConverter">
转换宝 转换宝
</router-link> </router-link>
<router-link to="/screenshot"> <router-link to="/screenshot">
screenshot screenshot
</router-link> </router-link>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
created() {}, created() {},
mounted() {} mounted() {}
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
/* @import url(); 引入css类 */ /* @import url(); 引入css类 */
.comp-sidenav { .comp-sidenav {
padding: 30px; padding: 30px;
// width: 100px; // width: 100px;
border: 1px solid skyblue; border: 1px solid skyblue;
height: 100%; height: 100%;
// display: flex; // display: flex;
a { a {
font-weight: bold; font-weight: bold;
color: #2c3e50; color: #2c3e50;
display: inline-block; display: inline-block;
width: 100%; width: 100%;
padding: 10px 0; padding: 10px 0;
&.router-link-exact-active { &.router-link-exact-active {
color: #42b983; color: #42b983;
}
} }
}
} }
</style> </style>
<template> <template>
<div class="taskComplete"></div> <div class="taskComplete"></div>
</template> </template>
<script> <script>
export default { export default {
name: 'TaskComplete', name: 'TaskComplete',
components: {}, components: {},
props: {}, props: {},
data() { data() {
return {}; return {}
}, },
computed: {}, computed: {},
watch: {}, watch: {},
methods: {} methods: {}
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.taskComplete { .taskComplete {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: #fff; background-color: #fff;
border: 0px solid black; border: 0px solid black;
margin: 0px; margin: 0px;
} }
</style> </style>
<template> <template>
<div class="taskEdit"> <div class="taskEdit">
<ul> <ul>
<li <li v-for="(item, index) in taskList" :key="index">
v-for="(item, index) in taskList" <div class="info">
:key="index" <div class="cove">
> 视频封面
<div class="info"> </div>
<div class="cove"> <div>
视频封面 <div>{{ item.name }}.mp4</div>
</div> <div>时长:{{ item.duration }}</div>
<div> </div>
<div>{{ item.name }}.mp4</div> </div>
<div>时长:{{ item.duration }}</div> <div class="operationPanel">
</div> <div v-show="item.state == 0" class="wait">
</div> <div>输出格式</div>
<div class="operationPanel"> <div class="selectionFormat">
<div mp4
v-show="item.state == 0" </div>
class="wait" <div class="delete" @click="clearTask(item)">
> 删除
<div>输出格式</div> </div>
<div class="selectionFormat"> </div>
mp4 <div v-show="item.state == 1" class="active">
</div> <div class="progress">
<div <div>转换中{{ item.progress }}%</div>
class="delete" <div class="slide">
@click="clearTask(item)" <div></div>
> </div>
删除 </div>
<div class="stop" @click="stopTask(item)">
取消
</div>
</div>
</div>
</li>
</ul>
<div class="editBar">
<div class="addVideo" @click="addVideo">
添加视频
</div> </div>
</div> <div class="clearList" @click="clearAllTasks">
<div 清空列表
v-show="item.state == 1"
class="active"
>
<div class="progress">
<div>转换中{{ item.progress }}%</div>
<div class="slide">
<div></div>
</div>
</div> </div>
<div class="clearWatermark">
<div 去除水印
class="stop"
@click="stopTask(item)"
>
取消
</div> </div>
</div>
</div> </div>
</li>
</ul>
<div class="editBar">
<div
class="addVideo"
@click="addVideo"
>
添加视频
</div>
<div
class="clearList"
@click="clearAllTasks"
>
清空列表
</div>
<div class="clearWatermark">
去除水印
</div>
</div>
<div <div class="startAll" @click="startAllTasks">
class="startAll" 开始转换
@click="startAllTasks" </div>
>
开始转换
</div> </div>
</div>
</template> </template>
<script> <script>
import { start, stop, clear, checkStatus } from './webApi'; import { start, stop, clear, checkStatus } from './webApi'
export default { export default {
name: 'TaskEdit', name: 'TaskEdit',
components: {}, components: {},
props: {}, props: {},
data() { data() {
return { return {
taskList: [] taskList: []
};
},
computed: {},
watch: {},
created() {
for (let i = 1; i < 10; i++) {
this.taskList.push({
cover: '',
name: '视频片段' + i,
duration: '10:00',
state: 0,
progress: 60,
outputFormat: 'mp4'
});
}
},
methods: {
async startTask(item) {
let result = await start();
if (result) {
item.state = 1;
} else {
item.state = 2;
}
},
async stopTask(item) {
let result = await stop();
if (result) {
item.state = 0;
}
},
async clearTask(item) {
let result = await clear();
if (result) {
let index = this.taskList.indexOf(item);
if (index > -1) {
this.taskList.splice(index, 1);
} }
}
},
async checkTaskStatus() {
await checkStatus();
}, },
addVideo() { computed: {},
this.taskList.push({ watch: {},
cover: '', created() {
name: '视频片段' + (this.taskList.length + 1), for (let i = 1; i < 10; i++) {
duration: '10:00', this.taskList.push({
state: 0, cover: '',
progress: 60, name: '视频片段' + i,
outputFormat: 'mp4' duration: '10:00',
}); state: 0,
}, progress: 60,
clearAllTasks() { outputFormat: 'mp4'
this.taskList = []; })
}
}, },
startAllTasks() { methods: {
this.taskList.forEach((task) => { async startTask(item) {
task.state = 1; let result = await start()
}); if (result) {
item.state = 1
} else {
item.state = 2
}
},
async stopTask(item) {
let result = await stop()
if (result) {
item.state = 0
}
},
async clearTask(item) {
let result = await clear()
if (result) {
let index = this.taskList.indexOf(item)
if (index > -1) {
this.taskList.splice(index, 1)
}
}
},
async checkTaskStatus() {
await checkStatus()
},
addVideo() {
this.taskList.push({
cover: '',
name: '视频片段' + (this.taskList.length + 1),
duration: '10:00',
state: 0,
progress: 60,
outputFormat: 'mp4'
})
},
clearAllTasks() {
this.taskList = []
},
startAllTasks() {
this.taskList.forEach((task) => {
task.state = 1
})
}
} }
} }
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.taskEdit { .taskEdit {
width: 100%;
height: 100%;
background-color: #fff;
border: 0px solid black;
margin: 0px;
padding: 0 20px;
display: flex;
flex-direction: column;
align-items: center;
cursor: default;
overflow: hidden;
> ul {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: 1px solid black; background-color: #fff;
flex-grow: 1; border: 0px solid black;
overflow-y: auto; margin: 0px;
> li { padding: 0 20px;
padding: 5px 0; display: flex;
height: 60px; flex-direction: column;
align-items: center;
display: flex; cursor: default;
justify-content: space-between; overflow: hidden;
align-items: center; > ul {
} width: 100%;
> li:nth-of-type(odd) {
background-color: gainsboro;
}
.info {
display: flex;
align-items: center;
.cove {
width: 100px;
height: 40px;
background-color: #ccc;
line-height: 40px;
margin-right: 10px;
}
}
.operationPanel {
width: 300px;
height: 100%;
.wait {
height: 100%; height: 100%;
display: flex; border: 1px solid black;
align-items: center; flex-grow: 1;
.selectionFormat { overflow-y: auto;
height: 30px; > li {
width: 100px; padding: 5px 0;
line-height: 30px; height: 60px;
border: 1px solid black;
margin-left: 20px; display: flex;
justify-content: space-between;
align-items: center;
} }
.delete { > li:nth-of-type(odd) {
width: 60px; background-color: gainsboro;
height: 30px;
line-height: 30px;
background-color: black;
color: #fff;
margin-left: 20px;
} }
} .info {
.active { display: flex;
height: 100%; align-items: center;
width: 300px; .cove {
display: flex; width: 100px;
align-items: center; height: 40px;
.progress { background-color: #ccc;
line-height: 40px;
margin-right: 10px;
}
} }
.slide { .operationPanel {
width: 200px; width: 300px;
height: 5px;
background: gray;
> div {
width: 120px;
height: 100%; height: 100%;
background-color: black; .wait {
} height: 100%;
} display: flex;
.stop { align-items: center;
width: 60px; .selectionFormat {
height: 30px; height: 30px;
line-height: 30px; width: 100px;
background-color: black; line-height: 30px;
color: #fff; border: 1px solid black;
margin-left: 20px; margin-left: 20px;
}
.delete {
width: 60px;
height: 30px;
line-height: 30px;
background-color: black;
color: #fff;
margin-left: 20px;
}
}
.active {
height: 100%;
width: 300px;
display: flex;
align-items: center;
.progress {
}
.slide {
width: 200px;
height: 5px;
background: gray;
> div {
width: 120px;
height: 100%;
background-color: black;
}
}
.stop {
width: 60px;
height: 30px;
line-height: 30px;
background-color: black;
color: #fff;
margin-left: 20px;
}
}
} }
}
} }
}
.editBar { .editBar {
position: relative; position: relative;
height: 30px; height: 30px;
width: 100%; width: 100%;
margin: 20px 0; margin: 20px 0;
.addVideo { .addVideo {
position: absolute; position: absolute;
left: 0; left: 0;
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
border: 1px solid black; border: 1px solid black;
} }
.clearList { .clearList {
position: absolute; position: absolute;
left: 100px; left: 100px;
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
border: 1px solid black; border: 1px solid black;
}
.clearWatermark {
position: absolute;
right: 0;
height: 30px;
line-height: 30px;
border: 1px solid black;
}
} }
.clearWatermark { .startAll {
position: absolute; height: 30px;
right: 0; width: 100px;
height: 30px; background-color: black;
line-height: 30px; color: #fff;
border: 1px solid black; line-height: 30px;
} }
}
.startAll {
height: 30px;
width: 100px;
background-color: black;
color: #fff;
line-height: 30px;
}
} }
</style> </style>
async function start() { async function start() {
let result = await new Promise((resolve) => { let result = await new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
resolve(true); resolve(true)
}, 1000); }, 1000)
}); })
return result; return result
} }
async function stop() { async function stop() {
let result = await new Promise((resolve) => { let result = await new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
resolve(true); resolve(true)
}, 500); }, 500)
}); })
return result; return result
} }
async function clear() { async function clear() {
let result = await new Promise((resolve) => { let result = await new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
resolve(true); resolve(true)
}, 500); }, 500)
}); })
return result; return result
} }
async function checkStatus(fakeValue) { async function checkStatus(fakeValue) {
let result = await new Promise((resolve) => { let result = await new Promise((resolve) => {
setTimeout(() => { setTimeout(() => {
resolve(fakeValue++); resolve(fakeValue++)
}, 500); }, 500)
}); })
return result; return result
} }
export { start, stop, clear, checkStatus }; export { start, stop, clear, checkStatus }
<template> <template>
<div <div class="video-change" @click="changeVideo">
class="video-change" 替换视频
@click="changeVideo" </div>
>
替换视频
</div>
</template> </template>
<script> <script>
export default { export default {
methods: { methods: {
changeVideo() { changeVideo() {
this.$emit('changeVideo'); this.$emit('changeVideo')
}
} }
} }
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.video-change { .video-change {
width: 100px; width: 100px;
height: 30px; height: 30px;
line-height: 30px; line-height: 30px;
text-align: center; text-align: center;
border: 1px solid #dddddd; border: 1px solid #dddddd;
border-radius: 4px; border-radius: 4px;
user-select: none; user-select: none;
cursor: pointer; cursor: pointer;
} }
</style> </style>
<template> <template>
<div class="video-control"> <div class="video-control">
<div <div class="video-play-btn" @click="play()">
class="video-play-btn" 播放
@click="play()" </div>
> <div class="video-time-content">
播放 <div class="now-time">
{{ nowTime | formatTime }}
</div>
<span>/</span>
<div class="total-time">
{{ duration | formatTime }}
</div>
</div>
</div> </div>
<div class="video-time-content">
<div class="now-time">
{{ nowTime | formatTime }}
</div>
<span>/</span>
<div class="total-time">
{{ duration | formatTime }}
</div>
</div>
</div>
</template> </template>
<script> <script>
export default { export default {
filters: { filters: {
formatTime(duration) { formatTime(duration) {
if (duration <= 0) return '00:00'; if (duration <= 0) return '00:00'
if (!duration) return '--:--'; if (!duration) return '--:--'
let min = ~~(duration / 60); let min = ~~(duration / 60)
min = (min + '').length === 1 ? '0' + min : min; min = (min + '').length === 1 ? '0' + min : min
let sec = Math.floor(duration % 60); let sec = Math.floor(duration % 60)
sec = (sec + '').length === 1 ? '0' + sec : sec; sec = (sec + '').length === 1 ? '0' + sec : sec
min = min || '00'; min = min || '00'
sec = sec || '00'; sec = sec || '00'
return min + ':' + sec; return min + ':' + sec
} }
}, },
props: ['duration', 'nowTime'], // eslint-disable-line props: ['duration', 'nowTime'], // eslint-disable-line
data() { data() {
return {}; return {}
}, },
methods: { methods: {
play() { play() {
this.$emit('play'); this.$emit('play')
}
} }
} }
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.video-control { .video-control {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-self: center; align-self: center;
width: 200px; width: 200px;
user-select: none; user-select: none;
} }
.video-play-btn { .video-play-btn {
border: 1px solid #dddddd; border: 1px solid #dddddd;
width: 30px; width: 30px;
height: 30px; height: 30px;
border-radius: 100%; border-radius: 100%;
margin-right: 10px; margin-right: 10px;
cursor: pointer; cursor: pointer;
} }
.video-time-content { .video-time-content {
display: flex; display: flex;
> div, > div,
span { span {
line-height: 30px; line-height: 30px;
color: #474261; color: #474261;
} }
} }
</style> </style>
<template> <template>
<div class="video-player"> <div class="video-player">
<video <video ref="videoDom" src="https://resources.laihua.com/2020-7-27/547adf9b-73b0-4b14-bed6-6ee278a1b2b2.mp4"></video>
ref="videoDom" </div>
src="https://resources.laihua.com/2020-7-27/547adf9b-73b0-4b14-bed6-6ee278a1b2b2.mp4"
></video>
</div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
state: 'pluse', state: 'pluse',
times: 0, times: 0,
canPlay: false canPlay: false
}; }
},
mounted() {
this.$bus.on('videoPlayer.play', (data) => {
if (data.time !== undefined) {
this.currentTime(data.time);
}
if (data.play) {
this.play();
} else {
this.pause();
}
});
this.$nextTick(() => {
this.$refs.videoDom.addEventListener('canplay', this.canPlayFunc);
this.$refs.videoDom.addEventListener('ended', () => {
this.$emit('ended');
});
this.$refs.videoDom.addEventListener('timeupdate', () => {
this.$emit('timeupdate', this.$refs.videoDom.currentTime);
});
});
},
beforeDestroy() {
this.$refs.videoDom.removeEventListener('canplay');
this.$refs.videoDom.removeEventListener('ended');
this.$refs.videoDom.removeEventListener('timeupdate');
},
methods: {
canPlayFunc() {
this.canPlay = true;
let from = this.$parent.$options.name || 'videoPlayer';
this.$bus.emit(`${from}.canPlay`, this.$refs.videoDom.duration);
}, },
play() { mounted() {
if (!this.canPlay) return; this.$bus.on('videoPlayer.play', (data) => {
this.$refs.videoDom.play(); if (data.time !== undefined) {
this.currentTime(data.time)
}
if (data.play) {
this.play()
} else {
this.pause()
}
})
this.$nextTick(() => {
this.$refs.videoDom.addEventListener('canplay', this.canPlayFunc)
this.$refs.videoDom.addEventListener('ended', () => {
this.$emit('ended')
})
this.$refs.videoDom.addEventListener('timeupdate', () => {
this.$emit('timeupdate', this.$refs.videoDom.currentTime)
})
})
}, },
pause() { beforeDestroy() {
if (!this.canPlay) return; this.$refs.videoDom.removeEventListener('canplay')
this.$refs.videoDom.pause(); this.$refs.videoDom.removeEventListener('ended')
this.$refs.videoDom.removeEventListener('timeupdate')
}, },
currentTime(time) { methods: {
if (!this.canPlay) return; canPlayFunc() {
this.$refs.videoDom.currentTime = time; this.canPlay = true
let from = this.$parent.$options.name || 'videoPlayer'
this.$bus.emit(`${from}.canPlay`, this.$refs.videoDom.duration)
},
play() {
if (!this.canPlay) return
this.$refs.videoDom.play()
},
pause() {
if (!this.canPlay) return
this.$refs.videoDom.pause()
},
currentTime(time) {
if (!this.canPlay) return
this.$refs.videoDom.currentTime = time
}
} }
} }
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.video-player { .video-player {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
align-items: center; align-items: center;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: beige; background-color: beige;
video { video {
max-width: 100%; max-width: 100%;
max-height: 100%; max-height: 100%;
} }
} }
</style> </style>
<template> <template>
<div class="video-timeline"> <div class="video-timeline">
<div <div ref="sliderWidth" v-drag class="time-slider">
ref="sliderWidth" <div class="time-slider-rail"></div>
v-drag <div class="time-slider-track" :style="{ width: ((info.val - info.min) / info.max) * 100 + '%' }"></div>
class="time-slider" <div data-action="handle" class="time-slider-handle" :style="{ left: ((info.val - info.min) / info.max) * 100 + '%' }"></div>
> </div>
<div class="time-slider-rail"></div>
<div
class="time-slider-track"
:style="{ width: ((info.val - info.min) / info.max) * 100 + '%' }"
></div>
<div
data-action="handle"
class="time-slider-handle"
:style="{ left: ((info.val - info.min) / info.max) * 100 + '%' }"
></div>
</div> </div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: 'VideoTimeline', name: 'VideoTimeline',
directives: { directives: {
drag(el, binding, vnode) { drag(el, binding, vnode) {
let _this = vnode.context, let _this = vnode.context,
mousemove = null, mousemove = null,
mouseup = null, mouseup = null,
dataAction = ''; dataAction = ''
mousemove = (e) => { mousemove = (e) => {
_this.dragMove && _this.dragMove(e.pageX, dataAction, e); _this.dragMove && _this.dragMove(e.pageX, dataAction, e)
}; }
mouseup = (e) => { mouseup = (e) => {
document.removeEventListener('mousemove', mousemove); document.removeEventListener('mousemove', mousemove)
document.removeEventListener('mouseup', mouseup); document.removeEventListener('mouseup', mouseup)
_this.dragUp && _this.dragUp(e.pageX, dataAction, e); _this.dragUp && _this.dragUp(e.pageX, dataAction, e)
}; }
el.onmousedown = (e) => { el.onmousedown = (e) => {
dataAction = e.target.dataset.action; dataAction = e.target.dataset.action
if (e.which === 3 || e.which === 2) { if (e.which === 3 || e.which === 2) {
e.stopPropagation(); e.stopPropagation()
return; return
} }
document.addEventListener('mousemove', mousemove); document.addEventListener('mousemove', mousemove)
document.addEventListener('mouseup', mouseup); document.addEventListener('mouseup', mouseup)
_this.dragDown && _this.dragDown(e.pageX, dataAction, e); _this.dragDown && _this.dragDown(e.pageX, dataAction, e)
}; }
} }
},
props: {
info: {
type: Object,
required: true,
default: function() {
return { step: 0.1, min: 0, max: 10, val: 0, cut: [0, 10] };
}
}
},
data() {
return {
width: 100
};
},
methods: {
dragDown(dis, action) {
if (!action) return;
this.width = this.$refs.sliderWidth.clientWidth;
this.action = action;
this.dragHand = true;
this.mpos = {
x: dis,
v: this.info.val
};
this.$emit('changeData', { val: this.mpos.v, action: action, type: 'start' });
}, },
dragMove(pos) { props: {
if (!this.action) return; info: {
let val = 0; type: Object,
console.log(pos, '<_-------------'); required: true,
// let pre = Math.round(((pos.x - this.mpos.x) / 120 * this.item.len + this.mpos.v) / this.item.step) / (1 / this.item.step); default: function() {
// this.item.val = pre > this.item.max ? this.item.max : pre < this.item.min ? this.item.min : pre; return { step: 0.1, min: 0, max: 10, val: 0, cut: [0, 10] }
this.$emit('changeData', { val: val, action: this.action, type: 'change' }); }
}
},
data() {
return {
width: 100
}
}, },
dragUp() { methods: {
if (!this.action) return; dragDown(dis, action) {
let val = 0; if (!action) return
this.mpos = null; this.width = this.$refs.sliderWidth.clientWidth
this.dragHand = false; this.action = action
this.action = ''; this.dragHand = true
this.$emit('changeData', { val: val, action: this.action, type: 'end' }); this.mpos = {
x: dis,
v: this.info.val
}
this.$emit('changeData', { val: this.mpos.v, action: action, type: 'start' })
},
dragMove(pos) {
if (!this.action) return
let val = 0
console.log(pos, '<_-------------')
// let pre = Math.round(((pos.x - this.mpos.x) / 120 * this.item.len + this.mpos.v) / this.item.step) / (1 / this.item.step);
// this.item.val = pre > this.item.max ? this.item.max : pre < this.item.min ? this.item.min : pre;
this.$emit('changeData', { val: val, action: this.action, type: 'change' })
},
dragUp() {
if (!this.action) return
let val = 0
this.mpos = null
this.dragHand = false
this.action = ''
this.$emit('changeData', { val: val, action: this.action, type: 'end' })
}
} }
} }
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.video-timeline { .video-timeline {
width: 100%; width: 100%;
height: 50px; height: 50px;
background-color: beige; background-color: beige;
} }
.time-slider { .time-slider {
position: relative; position: relative;
height: 15px; height: 15px;
padding: 5px 0; padding: 5px 0;
width: 100%; width: 100%;
margin-right: 1px; margin-right: 1px;
-ms-touch-action: none; -ms-touch-action: none;
touch-action: none; touch-action: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
* {
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
} * {
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
.time-slider-rail { .time-slider-rail {
position: absolute; position: absolute;
width: 100%; width: 100%;
background-color: #d9ddea; background-color: #d9ddea;
height: 4px; height: 4px;
border-radius: 3px; border-radius: 3px;
} }
.time-slider-track { .time-slider-track {
position: absolute; position: absolute;
background-color: #737596; background-color: #737596;
border-radius: 3px; border-radius: 3px;
height: 4px; height: 4px;
left: 0%; left: 0%;
width: 69.1515%; width: 69.1515%;
} }
.time-slider-handle { .time-slider-handle {
position: absolute; position: absolute;
margin-left: -6px; margin-left: -6px;
margin-top: -4px; margin-top: -4px;
left: 69.1515%; left: 69.1515%;
width: 12px; width: 12px;
height: 12px; height: 12px;
background-color: #737596; background-color: #737596;
cursor: -webkit-grab; cursor: -webkit-grab;
cursor: grab; cursor: grab;
border-radius: 50%; border-radius: 50%;
-ms-touch-action: pan-x; -ms-touch-action: pan-x;
touch-action: pan-x; touch-action: pan-x;
} }
} }
</style> </style>
import Vue from 'vue'; import Vue from 'vue'
import App from './App.vue'; import App from './App.vue'
import router from './router'; import router from './router'
import store from './store'; import store from './store'
import './registerServiceWorker'; import './registerServiceWorker'
import './assets/style/index.scss'; import './assets/style/index.scss'
import axios from 'axios'; import axios from 'axios'
import VueBus from 'vue-bus'; import VueBus from 'vue-bus'
import VModal from 'vue-js-modal'; import VModal from 'vue-js-modal'
Vue.use(VueBus); Vue.use(VueBus)
Vue.use(VModal); Vue.use(VModal)
import baseURL from '../config/baseUrl.js'; import baseURL from '../config/baseUrl.js'
console.log('baseURL:', baseURL); console.log('baseURL:', baseURL)
Vue.config.productionTip = false; Vue.config.productionTip = false
Vue.prototype.$http = axios; Vue.prototype.$http = axios
new Vue({ new Vue({
router, router,
store, store,
render: (h) => h(App) render: (h) => h(App)
}).$mount('#app'); }).$mount('#app')
/* eslint-disable no-console */ /* eslint-disable no-console */
import { register } from 'register-service-worker'; import { register } from 'register-service-worker'
if (process.env.NODE_ENV === 'production') { if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, { register(`${process.env.BASE_URL}service-worker.js`, {
ready() { ready() {
console.log('App is being served from cache by a service worker.\n' + 'For more details, visit https://goo.gl/AFskqB'); console.log('App is being served from cache by a service worker.\n' + 'For more details, visit https://goo.gl/AFskqB')
}, },
registered() { registered() {
console.log('Service worker has been registered.'); console.log('Service worker has been registered.')
}, },
cached() { cached() {
console.log('Content has been cached for offline use.'); console.log('Content has been cached for offline use.')
}, },
updatefound() { updatefound() {
console.log('New content is downloading.'); console.log('New content is downloading.')
}, },
updated() { updated() {
console.log('New content is available; please refresh.'); console.log('New content is available; please refresh.')
}, },
offline() { offline() {
console.log('No internet connection found. App is running in offline mode.'); console.log('No internet connection found. App is running in offline mode.')
}, },
error(error) { error(error) {
console.error('Error during service worker registration:', error); console.error('Error during service worker registration:', error)
} }
}); })
} }
import Vue from 'vue'; import Vue from 'vue'
import VueRouter from 'vue-router'; import VueRouter from 'vue-router'
import Bao3 from '../views/bao3.vue'; import Bao3 from '../views/bao3.vue'
import Screenshot from '../views/screenshot.vue'; import Screenshot from '../views/screenshot.vue'
import screenshotPanel from '../components/rightPanel/screenshotPanel.vue'; import screenshotPanel from '../components/rightPanel/screenshotPanel.vue'
Vue.use(VueRouter); Vue.use(VueRouter)
const routes = [ const routes = [
{ {
path: '/', path: '/',
name: 'Bao3', name: 'Bao3',
component: Bao3 component: Bao3
}, },
{ {
path: '/about', path: '/about',
name: 'About', name: 'About',
// route level code-splitting // route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route // this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited. // which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}, },
{ {
path: '/cutter', path: '/cutter',
name: 'Cutter', name: 'Cutter',
component: () => import(/* webpackChunkName: "bao1" */ '../views/videoCutter.vue') component: () => import(/* webpackChunkName: "bao1" */ '../views/videoCutter.vue')
}, },
{ {
path: '/videoConverter', path: '/videoConverter',
name: 'VideoConverter', name: 'VideoConverter',
component: () => import(/* webpackChunkName: "bao2" */ '../views/videoConverter.vue') component: () => import(/* webpackChunkName: "bao2" */ '../views/videoConverter.vue')
}, },
{ {
path: '/screenshot', path: '/screenshot',
components: { components: {
default: Screenshot, default: Screenshot,
panel: screenshotPanel panel: screenshotPanel
}
} }
} ]
];
const router = new VueRouter({ const router = new VueRouter({
mode: 'history', mode: 'history',
base: process.env.BASE_URL, base: process.env.BASE_URL,
routes routes
}); })
export default router; export default router
...@@ -2,20 +2,20 @@ ...@@ -2,20 +2,20 @@
// getter调用示例:this.$store.getters['test'] // getter调用示例:this.$store.getters['test']
const state = { const state = {
_test: 1 _test: 1
}; }
const getters = { const getters = {
test: (state) => state._test test: (state) => state._test
}; }
const mutations = {}; const mutations = {}
const actions = {}; const actions = {}
export default { export default {
state, state,
getters, getters,
mutations, mutations,
actions actions
}; }
import Vue from 'vue'; import Vue from 'vue'
import Vuex from 'vuex'; import Vuex from 'vuex'
import global from './global'; import global from './global'
import moduleA from './modules/moduleA'; import moduleA from './modules/moduleA'
import uploader from './modules/uploader'; import uploader from './modules/uploader'
Vue.use(Vuex); Vue.use(Vuex)
export default new Vuex.Store({ export default new Vuex.Store({
...global, ...global,
modules: { modules: {
moduleA, moduleA,
uploader uploader
} }
}); })
...@@ -2,21 +2,21 @@ ...@@ -2,21 +2,21 @@
// getter调用示例:this.$store.getters['moduleA/moduleState'] // getter调用示例:this.$store.getters['moduleA/moduleState']
const state = { const state = {
_moduleState: 'moduleState' _moduleState: 'moduleState'
}; }
const getters = { const getters = {
moduleState: (state) => state._moduleState moduleState: (state) => state._moduleState
}; }
const mutations = {}; const mutations = {}
const actions = {}; const actions = {}
export default { export default {
namespaced: true, namespaced: true,
state, state,
getters, getters,
mutations, mutations,
actions actions
}; }
...@@ -2,26 +2,26 @@ ...@@ -2,26 +2,26 @@
// getter调用示例:this.$store.getters['moduleA/moduleState'] // getter调用示例:this.$store.getters['moduleA/moduleState']
const state = { const state = {
video: {} video: {}
}; }
const getters = { const getters = {
video: (state) => state.video video: (state) => state.video
}; }
const mutations = {}; const mutations = {}
const actions = { const actions = {
async upload(store, payload) { async upload(store, payload) {
console.log('turbo: upload -> store, payload', store, payload); console.log('turbo: upload -> store, payload', store, payload)
}, },
async storeMaterial() {} async storeMaterial() {}
}; }
export default { export default {
namespaced: true, namespaced: true,
state, state,
getters, getters,
mutations, mutations,
actions actions
}; }
<template>
<div class="page-test">
test
</div>
</template>
<script>
export default {
data() {
return {}
}
}
</script>
<style scoped lang="scss">
/* @import url(); 引入css类 */
</style>
<template> <template>
<div class="about"> <div class="about">
<h1>This is an about page</h1> <h1>This is an about page</h1>
</div> </div>
</template> </template>
<template> <template>
<div class="comp-bao2"> <div class="comp-bao2">
bao2 bao2
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
created() {}, created() {},
mounted() {} mounted() {}
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
......
<template> <template>
<div class="comp-bao2"> <div class="comp-bao2">
bao3 bao3
<!-- <img src="../assets/logo.png" alt=""> --> <!-- <img src="../assets/logo.png" alt=""> -->
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return {}; return {}
}, },
created() {}, created() {},
mounted() {} mounted() {}
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
......
<template> <template>
<div class="screenshot"> <div class="screenshot">
<div class="content"> <div class="content">
<video <video id="screenshot-video" width="400" height="300" :src="srcUrl" controls></video>
id="screenshot-video" </div>
width="400" <div class="operate-area">
height="300" <div class="play-area">
:src="srcUrl" <input id="screenshot-input" type="file" style="display:none;" @change="changeFile" />
controls <label id="select-btn">
></video> <span>选择文件</span>
</div> </label>
<div class="operate-area"> </div>
<div class="play-area"> <div class="time-area">
<input <div id="ss-time-line">
id="screenshot-input" <div class="track"></div>
type="file" </div>
style="display:none;" </div>
@change="changeFile" <div class="clip-area"></div>
>
<label id="select-btn">
<span>选择文件</span>
</label>
</div>
<div class="time-area">
<div id="ss-time-line">
<div class="track"></div>
</div> </div>
</div>
<div class="clip-area"></div>
</div> </div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: 'Screenshot', name: 'Screenshot',
data() { data() {
return { return {
srcUrl: null, srcUrl: null,
videoEle: null, videoEle: null,
current: 0, current: 0,
duration: 10 duration: 10
}; }
}, },
created() {}, created() {},
mounted() { mounted() {
let input = document.getElementById('screenshot-input'); let input = document.getElementById('screenshot-input')
let fileBtn = document.getElementById('select-btn'); let fileBtn = document.getElementById('select-btn')
fileBtn.addEventListener('click', function() { fileBtn.addEventListener('click', function() {
input.click(); input.click()
}); })
let video = document.getElementById('screenshot-video'); let video = document.getElementById('screenshot-video')
video.onerror = function(e) { video.onerror = function(e) {
console.log('onerror', e); console.log('onerror', e)
}; }
video.addEventListener('loadedmetadata', function(e) { video.addEventListener('loadedmetadata', function(e) {
console.log('loadedmetadata', e); console.log('loadedmetadata', e)
//webkitVideoDecodedByteCount //webkitVideoDecodedByteCount
if (e.target.webkitVideoDecodedByteCount < 1) { if (e.target.webkitVideoDecodedByteCount < 1) {
console.error('格式不支持'); console.error('格式不支持')
} }
}); })
//loadedmetadata //loadedmetadata
}, },
methods: { methods: {
changeFile(e) { changeFile(e) {
//console.log('changeFile', e) //console.log('changeFile', e)
if (e.target.files[0]) { if (e.target.files[0]) {
this.srcUrl = URL.createObjectURL(e.target.files[0]); this.srcUrl = URL.createObjectURL(e.target.files[0])
} }
}
} }
} }
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.screenshot { .screenshot {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.content {
height: 100%; height: 100%;
margin: 20px 30px;
background-color: lightcyan;
}
.operate-area {
background-color: aqua;
height: 200px;
display: flex; display: flex;
flex-shrink: 0; flex-direction: column;
#select-btn { .content {
background-color: bisque; height: 100%;
width: 100px;
height: 30px; margin: 20px 30px;
line-height: 30px; background-color: lightcyan;
}
.operate-area {
background-color: aqua;
height: 200px;
display: flex;
flex-shrink: 0;
#select-btn {
background-color: bisque;
width: 100px;
height: 30px;
line-height: 30px;
}
} }
}
} }
</style> </style>
<template> <template>
<div class="videoConverter"> <div class="videoConverter">
<taskEdit></taskEdit> <taskEdit></taskEdit>
</div> </div>
</template> </template>
<script> <script>
import taskEdit from '@/components/videoConverter/taskEdit'; import taskEdit from '@/components/videoConverter/taskEdit'
export default { export default {
name: 'VideoConverter', name: 'VideoConverter',
components: { taskEdit }, components: { taskEdit },
props: {}, props: {},
data() { data() {
return {}; return {}
}, },
computed: {}, computed: {},
watch: {}, watch: {},
created() {}, created() {},
methods: {} methods: {}
}; }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.videoConverter { .videoConverter {
width: 100%; width: 100%;
height: 800px; height: 800px;
background-color: #fff; background-color: #fff;
border: 0px solid black; border: 0px solid black;
margin: 0px; margin: 0px;
} }
</style> </style>
<template> <template>
<div class="video-cutter"> <div class="video-cutter">
<div class="video-content"> <div class="video-content">
<videoPlayer <videoPlayer @currentTime="changeTime" @end="playEnd" @timeupdate="timeupdate"></videoPlayer>
@currentTime="changeTime" </div>
@end="playEnd" <div class="video-btn">
@timeupdate="timeupdate" <videoChange @changeVideo="changeVideo"></videoChange>
></videoPlayer> <videoControl :duration="duration" :now-time="nowTime" @play="videoPlay"></videoControl>
<div class="video-water">
<input id="cutterRemoveWater" v-model="noWater" type="checkbox" />
<label for="cutterRemoveWater">去除ddf 水印</label>
</div>
</div>
<div class="timeline-content">
<videoTimeline :info="timelineObj"></videoTimeline>
</div>
<div></div>
</div> </div>
<div class="video-btn">
<videoChange @changeVideo="changeVideo"></videoChange>
<videoControl
:duration="duration"
:now-time="nowTime"
@play="videoPlay"
></videoControl>
<div class="video-water">
<input
id="cutterRemoveWater"
v-model="noWater"
type="checkbox"
>
<label for="cutterRemoveWater">去除水印</label>
</div>
</div>
<div class="timeline-content">
<videoTimeline :info="timelineObj"></videoTimeline>
</div>
<div></div>
</div>
</template> </template>
<script> <script>
export default { export default {
name: 'VideoCutter', name: 'VideoCutter',
components: { components: {
VideoPlayer: () => import('@/components/videoCutter/videoPlayer.vue'), VideoPlayer: () => import('@/components/videoCutter/videoPlayer.vue'),
VideoChange: () => import('@/components/videoCutter/videoChange.vue'), VideoChange: () => import('@/components/videoCutter/videoChange.vue'),
VideoControl: () => import('@/components/videoCutter/videoControl.vue'), VideoControl: () => import('@/components/videoCutter/videoControl.vue'),
VideoTimeline: () => import('@/components/videoCutter/videoTimeline.vue') VideoTimeline: () => import('@/components/videoCutter/videoTimeline.vue')
},
data() {
return {
name: '',
nowTime: 0,
duration: 0,
playing: false,
canPlay: false,
noWater: true,
timelineObj: { step: 0.1, min: 0, max: 10, val: 0 }
};
},
created() {},
mounted() {
this.$bus.on('VideoCutter.canPlay', this.canPlayFunc);
},
methods: {
changeVideo() {
console.log('todo change video, <-----lilei');
}, },
canPlayFunc(data) { data() {
this.duration = data; return {
this.timelineObj.max = this.duration; name: '',
this.canPlay = true; nowTime: 0,
}, duration: 0,
videoPlay() { playing: false,
if (!this.canPlay) return; canPlay: false,
let ob = {}; noWater: true,
if (this.playing) { timelineObj: { step: 0.1, min: 0, max: 10, val: 0 }
ob.play = false;
} else {
ob.play = true;
if (this.nowTime >= this.duration) {
ob.time = 0;
this.timelineObj.val = 0;
} }
}
this.playing = !this.playing;
this.$bus.emit('videoPlayer.play', ob);
},
changeTime(data) {
console.log(data);
}, },
playEnd() { created() {},
this.playing = false; mounted() {
this.nowTime = this.duration; this.$bus.on('VideoCutter.canPlay', this.canPlayFunc)
this.timelineObj.val = this.nowTime;
}, },
timeupdate(time) { methods: {
this.nowTime = time; changeVideo() {
this.timelineObj.val = this.nowTime; console.log('todo change video, <-----lilei')
},
canPlayFunc(data) {
this.duration = data
this.timelineObj.max = this.duration
this.canPlay = true
},
videoPlay() {
if (!this.canPlay) return
let ob = {}
if (this.playing) {
ob.play = false
} else {
ob.play = true
if (this.nowTime >= this.duration) {
ob.time = 0
this.timelineObj.val = 0
}
}
this.playing = !this.playing
this.$bus.emit('videoPlayer.play', ob)
},
changeTime(data) {
console.log(data)
},
playEnd() {
this.playing = false
this.nowTime = this.duration
this.timelineObj.val = this.nowTime
},
timeupdate(time) {
this.nowTime = time
this.timelineObj.val = this.nowTime
}
} }
} }
};
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
/* @import url(); 引入css类 */ /* @import url(); 引入css类 */
.video-cutter { .video-cutter {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.video-content { .video-content {
width: 100%; width: 100%;
height: 700px; height: 700px;
} }
.video-btn { .video-btn {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.video-water { .video-water {
display: flex; display: flex;
align-items: center; align-items: center;
input { input {
margin-right: 4px; margin-right: 4px;
} }
* { * {
cursor: pointer; cursor: pointer;
} }
} }
.timeline-content { .timeline-content {
width: 100%; width: 100%;
margin: 10px 0; margin: 10px 0;
padding: 0 20px; padding: 0 20px;
} }
</style> </style>
...@@ -2,40 +2,40 @@ ...@@ -2,40 +2,40 @@
console.log('process.env.NODE_ENV1:', process.env.NODE_ENV) console.log('process.env.NODE_ENV1:', process.env.NODE_ENV)
module.exports = { module.exports = {
// outputDir: process.env.outputDir, // outputDir: process.env.outputDir,
// assetsDir: 'static', // assetsDir: 'static',
publicPath: '/', publicPath: '/',
devServer: { devServer: {
open: true, open: true,
// host: '0.0.0.0', // host: '0.0.0.0',
port: 3018, port: 3018,
https: false, https: false,
hotOnly: false, hotOnly: false,
proxy: { proxy: {
webapi: { webapi: {
target: 'https://test2.laihua.com/', target: 'https://test2.laihua.com/',
ws: true, ws: true,
changeOrigin: true, changeOrigin: true,
pathRewrite: { '^/webapi': '/' } pathRewrite: { '^/webapi': '/' }
} }
}
},
chainWebpack: (config) => {
config.module
.rule('eslint')
.use('eslint-loader')
.loader('eslint-loader')
.tap((options) => {
// 保存自动eslint修复
options.fix = true
return options
})
},
css: {
loaderOptions: {
sass: {
prependData: '@import "@/assets/style/index.scss";'
}
}
} }
},
chainWebpack: (config) => {
config.module
.rule('eslint')
.use('eslint-loader')
.loader('eslint-loader')
.tap((options) => {
// 保存自动eslint修复
options.fix = true
return options
})
},
css: {
loaderOptions: {
sass: {
prependData: '@import "@/assets/style/index.scss";'
}
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment