|
|
@@ -25,16 +25,15 @@
|
|
|
>
|
|
|
<div class="c-viewer__list">
|
|
|
<div
|
|
|
- v-for="(widget,index) in layers"
|
|
|
+ v-for="widget in layers"
|
|
|
ref="widgetElements"
|
|
|
- :key="index"
|
|
|
+ :key="widget.id"
|
|
|
class="c-sibling-item--v o-layer"
|
|
|
- :class="{ active: index == selectedWidgetIndex }"
|
|
|
- @click="onWidgetClick(widget,index,$event)"
|
|
|
+ :class="{ active: widget.id === selectedWidgetId }"
|
|
|
+ @click="onWidgetClick(widget, $event)"
|
|
|
>
|
|
|
<widget-shortcut
|
|
|
:widget="widget"
|
|
|
- editable
|
|
|
@view="onView"
|
|
|
/>
|
|
|
</div>
|
|
|
@@ -242,6 +241,27 @@
|
|
|
@customPaste="onCustomPaste"
|
|
|
/>
|
|
|
</div>
|
|
|
+ <div
|
|
|
+ ref="canvas"
|
|
|
+ style="position: absolute;top:0;left: 0;z-index: -1;"
|
|
|
+ class="l-flex__none"
|
|
|
+ :style="canvasStyles"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="c-viewer__canvas has-bg"
|
|
|
+ :style="[transformStyles, styles]"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="c-viewer__background has-bg"
|
|
|
+ :style="backgroundStyles"
|
|
|
+ />
|
|
|
+ <widget
|
|
|
+ v-for="item in widgets"
|
|
|
+ :key="item.id"
|
|
|
+ :node="item"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
</confirm-dialog>
|
|
|
@@ -274,6 +294,9 @@ import {
|
|
|
Toolbar
|
|
|
} from '@wangeditor/editor-for-vue'
|
|
|
import '@wangeditor/editor/dist/css/style.css'
|
|
|
+import domToImage from 'dom-to-image'
|
|
|
+import mixin2 from '@/views/screen/material/program/ast/mixin2'
|
|
|
+import Widget from '@/views/screen/material/program/ast/core/widget/WidgetViewer'
|
|
|
|
|
|
export default {
|
|
|
name: 'TemplateAssetChooseDialog',
|
|
|
@@ -281,8 +304,10 @@ export default {
|
|
|
Draggable,
|
|
|
WidgetShortcut,
|
|
|
Editor,
|
|
|
- Toolbar
|
|
|
+ Toolbar,
|
|
|
+ Widget
|
|
|
},
|
|
|
+ mixins: [mixin2],
|
|
|
props: {
|
|
|
title: {
|
|
|
type: String,
|
|
|
@@ -299,6 +324,8 @@ export default {
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
+ snapping: false,
|
|
|
+ canvasStyles: null,
|
|
|
inputValues: [],
|
|
|
lastIndex: 0,
|
|
|
types: [],
|
|
|
@@ -310,7 +337,6 @@ export default {
|
|
|
options: {},
|
|
|
isStream: false,
|
|
|
selectedWidget: null, //
|
|
|
- selectedWidgetIndex: 0,
|
|
|
program: null,
|
|
|
isMedia: true,
|
|
|
editor: null,
|
|
|
@@ -340,20 +366,17 @@ export default {
|
|
|
// return this.title || (this.types.length > 1 ? '请选择资源' : `请选择${AssetTypeInfo[this.types[0]]}`)
|
|
|
// },
|
|
|
layers () {
|
|
|
- const arr = this.program.detail.widgets.slice()
|
|
|
- .reverse()
|
|
|
- console.log('widgets', arr)
|
|
|
- return arr
|
|
|
+ return this.widgets.slice().reverse()
|
|
|
},
|
|
|
count () {
|
|
|
- if (this.program.detail) {
|
|
|
- return this.program.detail.widgets.length
|
|
|
+ if (this.node) {
|
|
|
+ return this.layers.length
|
|
|
}
|
|
|
return 0
|
|
|
},
|
|
|
- // selectedWidgetId () {
|
|
|
- // return this.selectedWidget?.id
|
|
|
- // },
|
|
|
+ selectedWidgetId () {
|
|
|
+ return this.selectedWidget?.id
|
|
|
+ },
|
|
|
hasRootAssets () {
|
|
|
if (this.node) {
|
|
|
const { backgroundImage, bgm } = this.node
|
|
|
@@ -426,7 +449,7 @@ export default {
|
|
|
},
|
|
|
watch: {
|
|
|
selectedWidget () {
|
|
|
- this.program && setTimeout(() => {
|
|
|
+ this.node && setTimeout(() => {
|
|
|
if (this.selectedWidget) {
|
|
|
this.$refs.widgetElements?.find(element => element.classList.contains('active'))
|
|
|
?.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
|
@@ -441,6 +464,60 @@ export default {
|
|
|
this.updateInputValues()
|
|
|
},
|
|
|
methods: {
|
|
|
+ checkRatio () {
|
|
|
+ if (this.canvasStyles) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const { width, height } = this.node
|
|
|
+ if (width <= 960 && height <= 540) {
|
|
|
+ this.canvasStyles = {}
|
|
|
+ } else {
|
|
|
+ const wScale = 960 / width
|
|
|
+ const hScale = 540 / height
|
|
|
+ this.scale = Math.min(wScale, hScale) * 100 | 0
|
|
|
+ if (wScale <= hScale) {
|
|
|
+ this.canvasStyles = {
|
|
|
+ width: '960px',
|
|
|
+ height: `${height * wScale}px`
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.canvasStyles = {
|
|
|
+ width: `${width * hScale}px`,
|
|
|
+ height: '540px'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ toSnap () {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.test()
|
|
|
+ }, 100)
|
|
|
+ },
|
|
|
+ async test () {
|
|
|
+ const base64 = await this.snap()
|
|
|
+ if (base64) {
|
|
|
+ const result = /^data:(.+);base64,(.+)$/.exec(base64)
|
|
|
+ console.log('base64:', result[0])
|
|
|
+ this.imageBase64 = result[0]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ snap () {
|
|
|
+ this.snapping = true
|
|
|
+ return domToImage.toJpeg(this.$refs.canvas, {
|
|
|
+ filter (node) {
|
|
|
+ const { tagName } = node
|
|
|
+ if (tagName === 'CANVAS') {
|
|
|
+ return /^data:.+;base64,.+/.test(node.toDataURL())
|
|
|
+ }
|
|
|
+ return tagName !== 'VIDEO' && tagName !== 'IFRAME'
|
|
|
+ },
|
|
|
+ width: this.node.width * this.scale / 100 | 0,
|
|
|
+ height: this.node.height * this.scale / 100 | 0,
|
|
|
+ quality: 0.1
|
|
|
+ }).finally(() => {
|
|
|
+ this.snapping = false
|
|
|
+ })
|
|
|
+ },
|
|
|
onEditorCreated (editor) {
|
|
|
this.editor = Object.seal(editor)
|
|
|
},
|
|
|
@@ -523,6 +600,14 @@ export default {
|
|
|
this.showMessage('error', '布局分辨率异常,请联系管理员')
|
|
|
return
|
|
|
}
|
|
|
+ // this.$emit('update-program',{
|
|
|
+ // id, status, name, resolutionRatio,
|
|
|
+ // detail: {
|
|
|
+ // width: Number(width),
|
|
|
+ // height: Number(height),
|
|
|
+ // ...JSON.parse(itemJsonStr)
|
|
|
+ // }
|
|
|
+ // } );
|
|
|
this.program = {
|
|
|
id, status, name, resolutionRatio,
|
|
|
detail: {
|
|
|
@@ -531,14 +616,14 @@ export default {
|
|
|
...JSON.parse(itemJsonStr)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ console.log('progam', this.program)
|
|
|
+ this.initCanvas(this.program.detail)
|
|
|
// 默认选中第一个
|
|
|
const widget = this.layers[0]
|
|
|
- this.chooseWidget(widget, 0)
|
|
|
-
|
|
|
+ this.chooseWidget(widget)
|
|
|
this.$refs.dialog.show()
|
|
|
} catch (e) {
|
|
|
- console.log(e)
|
|
|
+ console.log('catch:', e)
|
|
|
this.showMessage('error', '布局解析失败')
|
|
|
}
|
|
|
})
|
|
|
@@ -770,12 +855,28 @@ export default {
|
|
|
this.selectedWidget.sources = this.assets
|
|
|
},
|
|
|
onConfirm (done) {
|
|
|
- // if (this.choosen) {
|
|
|
- // this.choosen(this.assets)
|
|
|
- // .then(done)
|
|
|
- // } else {
|
|
|
- done()
|
|
|
- // }
|
|
|
+ // 检查资源是否都有了
|
|
|
+ // forEach()
|
|
|
+ // 输入名字
|
|
|
+ this.$prompt(
|
|
|
+ '<p class="u-color--black u-font-size--sm u-bold">请输入节目名称</p>',
|
|
|
+ '保存节目',
|
|
|
+ {
|
|
|
+ dangerouslyUseHTMLString: true,
|
|
|
+ closeOnClickModal: false,
|
|
|
+ inputValue: '模板名字',
|
|
|
+ inputPlaceholder: '请输入节目名称',
|
|
|
+ inputPattern: /^.{0,30}$/,
|
|
|
+ inputErrorMessage: '最多30个字符',
|
|
|
+ confirmButtonText: '保存',
|
|
|
+ cancelButtonText: '取消'
|
|
|
+ }
|
|
|
+ ).then(({ value }) => {
|
|
|
+ console.log('value', value)
|
|
|
+ done()
|
|
|
+ }).catch(() => {
|
|
|
+ console.log('cancel')
|
|
|
+ })
|
|
|
},
|
|
|
onSetImageDuration () {
|
|
|
const duration = this.duration
|
|
|
@@ -811,15 +912,15 @@ export default {
|
|
|
console.log('onView:', source)
|
|
|
this.$refs.previewDialog.show(source)
|
|
|
},
|
|
|
-
|
|
|
- onWidgetClick (widget, index, evt) {
|
|
|
+ onWidgetClick (widget, evt) {
|
|
|
console.log('onWidgetClick', widget)
|
|
|
evt.stopPropagation()
|
|
|
- this.chooseWidget(widget, index)
|
|
|
+ this.chooseWidget(widget)
|
|
|
},
|
|
|
- chooseWidget (widget, index) {
|
|
|
+ chooseWidget (widget) {
|
|
|
if (!this.selectedWidget || this.selectedWidget !== widget) {
|
|
|
this.selectedWidget = widget
|
|
|
+ console.log('selectedWidget:', widget)
|
|
|
if (this.selectedWidget.type === 'CText') {
|
|
|
this.isMedia = false
|
|
|
this.showText(widget)
|
|
|
@@ -828,7 +929,6 @@ export default {
|
|
|
this.showMediaChoose(widget)
|
|
|
}
|
|
|
}
|
|
|
- this.selectedWidgetIndex = index
|
|
|
}
|
|
|
|
|
|
}
|