Răsfoiți Sursa

feat(program design): component preview switch

Casper Dai 3 ani în urmă
părinte
comite
3a59eeecd4

+ 26 - 13
src/views/screen/material/program/ast/Designer.vue

@@ -15,21 +15,21 @@
     />
     <div class="l-flex__none l-flex--row c-designer__header">
       <i
-        class="c-sibling-item c-designer__shortcut el-icon-arrow-left o-icon o-icon--hover u-pointer"
+        class="l-flex__none c-sibling-item c-designer__shortcut el-icon-arrow-left o-icon o-icon--hover u-pointer"
         @click="onBack"
       />
-      <span class="c-sibling-item near u-font-size--md u-bold">{{ program.name }}</span>
-      <span class="c-sibling-item near u-font-size--xs">{{ program.resolutionRatio }}</span>
+      <span class="l-flex__self c-sibling-item near u-font-size--md u-bold u-ellipsis">{{ program.name }}</span>
+      <span class="l-flex__none c-sibling-item near u-font-size--xs">{{ program.resolutionRatio }}</span>
       <div
         v-if="hasAudio"
-        class="c-sibling-item c-designer__shortcut o-icon o-icon--hover u-pointer"
+        class="l-flex__none c-sibling-item c-designer__shortcut o-icon o-icon--hover u-pointer"
         @click="toggleMute"
       >
         <volume :muted="muted" />
       </div>
       <div
         v-if="hasNext"
-        class="c-sibling-item c-designer__shortcut o-icon o-icon--hover u-pointer"
+        class="l-flex__none c-sibling-item c-designer__shortcut o-icon o-icon--hover u-pointer"
         @click="switchBgm"
       >
         <i class="o-next" />
@@ -37,14 +37,14 @@
       <div class="l-flex__fill c-sibling-item" />
       <button
         v-if="hasWidgets"
-        class="c-sibling-item o-button o-button--sm"
+        class="l-flex__none c-sibling-item o-button o-button--sm"
         @click="onClear"
       >
         <i class="o-button__icon el-icon-delete" />
         清空
       </button>
       <button
-        class="c-sibling-item o-button o-button--sm"
+        class="l-flex__none c-sibling-item o-button o-button--sm"
         @click="onSave"
       >
         <i class="o-button__icon iconfont iconsave" />
@@ -98,8 +98,8 @@
         </el-scrollbar>
       </div>
       <div class="c-designer__main">
-        <div class="l-flex--row c-designer__tool">
-          <div class="o-scale-slider">
+        <div class="l-flex--row c-designer__tool has-padding--h">
+          <div class="l-flex__none c-sibling-item farther o-scale-slider">
             <div class="l-flex--row o-scale-slider__wrapper">
               <i
                 class="el-icon-zoom-out u-pointer"
@@ -118,7 +118,7 @@
             </div>
           </div>
           <div
-            class="l-flex__none l-flex--row"
+            class="l-flex__none l-flex--row c-sibling-item"
             @dragstart="widgetOnDragStart"
             @dragend="widgetOnDragEnd"
           >
@@ -135,6 +135,20 @@
               <span class="c-sibling-item--v nearer o-widget-cfg__text u-font-size--xs">{{ cfg.label }}</span>
             </div>
           </div>
+          <el-checkbox
+            v-model="preview"
+            class="c-sibling-item farthest"
+          >
+            组件预览
+          </el-checkbox>
+          <el-tooltip
+            class="c-sibling-item near"
+            effect="dark"
+            placement="top"
+            content="渲染过多过大的图片、视频或直播等会造成页面卡顿,此时可关闭预览"
+          >
+            <i class="el-icon-question" />
+          </el-tooltip>
         </div>
         <div
           ref="wrapper"
@@ -432,6 +446,7 @@ export default {
   data () {
     return {
       loading: false,
+      preview: true,
       snapping: false,
       padding: 16,
       optionIndex: 0,
@@ -994,7 +1009,7 @@ $border: #242835;
 
 .c-designer {
   height: 100%;
-  min-width: 1080px;
+  min-width: 1280px;
   min-height: 600px;
   background-color: $theme;
   overflow: hidden;
@@ -1234,10 +1249,8 @@ $border: #242835;
 }
 
 .o-scale-slider {
-  justify-content: flex-start;
   min-width: 48px;
   width: auto;
-  padding: 0 $spacing;
   font-size: 20px;
 
   &__wrapper {

+ 26 - 17
src/views/screen/material/program/ast/Viewer.vue

@@ -9,22 +9,24 @@
       @ended="onAudioEnded"
       @error="onAudioError"
     />
-    <div class="l-flex__none l-flex--row c-viewer__header u-color--black">
-      <span class="c-sibling-item u-font-size--md u-bold u-ellipsis">{{ program.name }}</span>
-      <span class="c-sibling-item near u-color--info u-font-size--xs">{{ program.resolutionRatio }}</span>
-      <div
-        v-if="hasAudio"
-        class="c-sibling-item o-icon o-icon--hover u-pointer"
-        @click="toggleMute"
-      >
-        <volume :muted="muted" />
-      </div>
-      <div
-        v-if="hasNext"
-        class="c-sibling-item o-icon o-icon--hover u-pointer"
-        @click="switchBgm"
-      >
-        <i class="o-next" />
+    <div class="l-flex__none c-viewer__header u-relative u-color--black">
+      <div class="c-viewer__wrapper l-flex--row">
+        <span class="l-flex__self c-sibling-item u-font-size--md u-bold u-ellipsis">{{ program.name }}</span>
+        <span class="l-flex__none c-sibling-item near u-color--info u-font-size--xs">{{ program.resolutionRatio }}</span>
+        <div
+          v-if="hasAudio"
+          class="l-flex__none c-sibling-item o-icon o-icon--hover u-pointer"
+          @click="toggleMute"
+        >
+          <volume :muted="muted" />
+        </div>
+        <div
+          v-if="hasNext"
+          class="l-flex__none c-sibling-item o-icon o-icon--hover u-pointer"
+          @click="switchBgm"
+        >
+          <i class="o-next" />
+        </div>
       </div>
     </div>
     <div class="l-flex__none l-flex">
@@ -221,10 +223,17 @@ export default {
 .c-viewer {
   &__header {
     height: $height--md;
-    padding: 0 $padding--lg;
     line-height: 1;
   }
 
+  &__wrapper {
+    position: absolute;
+    top: 0;
+    left: $spacing;
+    right: $font-size--xl + 2 * $padding--lg;
+    height: 100%;
+  }
+
   &__asserts {
     width: 160px;
     border-right: 1px solid $border;

+ 6 - 3
src/views/screen/material/program/ast/core/widget/CImage.vue

@@ -4,7 +4,7 @@
     :class="className"
     :style="styles"
   >
-    <template v-if="!isSnapping">
+    <template v-if="canLoad && !isSnapping">
       <template v-if="isSlide">
         <transition name="slide">
           <div
@@ -68,7 +68,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   data () {
@@ -80,6 +80,9 @@ export default {
     }
   },
   computed: {
+    canLoad () {
+      return this.control.preview !== false
+    },
     isSnapping () {
       return this.control.snapping
     },
@@ -110,7 +113,7 @@ export default {
         }
     },
     isEmpty () {
-      return !this.img
+      return this.canLoad && !this.img
     },
     slideStyles () {
       return {

+ 43 - 17
src/views/screen/material/program/ast/core/widget/CLive.vue

@@ -29,10 +29,13 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   computed: {
+    canPlay () {
+      return this.control.preview !== false
+    },
     isSnapping () {
       return this.control.snapping
     },
@@ -58,8 +61,19 @@ export default {
     }
   },
   watch: {
-    url () {
-      this.play()
+    canPlay (val) {
+      if (val) {
+        this.play()
+      } else {
+        this.stop()
+      }
+    },
+    url (val) {
+      if (val) {
+        this.play()
+      } else {
+        this.stop()
+      }
     },
     isSnapping (val) {
       const player = this.$refs.player
@@ -76,7 +90,7 @@ export default {
     }
   },
   mounted () {
-    this.url && this.play()
+    this.play()
   },
   beforeDestroy () {
     if (this.hlsjs) {
@@ -84,27 +98,39 @@ export default {
     }
   },
   methods: {
-    play () {
+    stop () {
       if (this.$refs.player.canPlayType('application/vnd.apple.mpegurl')) {
-        this.$refs.player.src = this.url
+        this.$refs.player.src = ''
       } else if (isSupported) {
-        if (!this.hlsjs) {
-          this.hlsjs = new HlsJs()
-          this.hlsjs.attachMedia(this.$refs.player)
-          this.hlsjs.on(HlsJs.Events.MANIFEST_PARSED, () => {
-            this.$refs.player.play()
-          })
-          this.hlsjs.on(HlsJs.Events.ERROR, e => {
-            console.log('error', e)
-          })
+        if (this.hlsjs) {
+          this.hlsjs.destroy()
+          this.hlsjs = null
+        }
+      }
+    },
+    play () {
+      if (this.url && this.canPlay) {
+        if (this.$refs.player.canPlayType('application/vnd.apple.mpegurl')) {
+          this.$refs.player.src = this.url
+        } else if (isSupported) {
+          if (!this.hlsjs) {
+            this.hlsjs = new HlsJs()
+            this.hlsjs.attachMedia(this.$refs.player)
+            this.hlsjs.on(HlsJs.Events.MANIFEST_PARSED, () => {
+              this.$refs.player.play()
+            })
+            this.hlsjs.on(HlsJs.Events.ERROR, e => {
+              console.log('error', e)
+            })
+          }
+          this.hlsjs.loadSource(this.url)
         }
-        this.hlsjs.loadSource(this.url)
       }
     },
     getSnap () {
       const video = this.$refs.player
       const canvas = this.$refs.canvas
-      if (video && canvas) {
+      if (this.canPlay && video && canvas) {
         const cxt = canvas.getContext('2d')
         canvas.width = this.node.width
         canvas.height = this.node.height

+ 1 - 1
src/views/screen/material/program/ast/core/widget/CMarquee.vue

@@ -22,7 +22,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   computed: {

+ 5 - 2
src/views/screen/material/program/ast/core/widget/CMedia.vue

@@ -3,7 +3,7 @@
     class="c-media"
     :style="styles"
   >
-    <template v-if="source">
+    <template v-if="canLoad">
       <template v-if="canPlay">
         <video
           ref="player"
@@ -44,7 +44,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   data () {
@@ -54,6 +54,9 @@ export default {
     }
   },
   computed: {
+    canLoad () {
+      return this.control.preview !== false && !!this.source
+    },
     isSnapping () {
       return this.control.snapping
     },

+ 1 - 1
src/views/screen/material/program/ast/core/widget/CText.vue

@@ -16,7 +16,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   computed: {

+ 1 - 1
src/views/screen/material/program/ast/core/widget/CTime.vue

@@ -13,7 +13,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   data () {

+ 4 - 4
src/views/screen/material/program/ast/core/widget/CVideo.vue

@@ -33,7 +33,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   data () {
@@ -43,6 +43,9 @@ export default {
     }
   },
   computed: {
+    canPlay () {
+      return this.control.preview !== false && !this.ignore && !!this.video
+    },
     isSnapping () {
       return this.control.snapping
     },
@@ -64,9 +67,6 @@ export default {
     },
     muted () {
       return this.node.mute || this.control.muted
-    },
-    canPlay () {
-      return !this.ignore && this.video
     }
   },
   watch: {

+ 1 - 1
src/views/screen/material/program/ast/core/widget/CWeather.vue

@@ -15,7 +15,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   data () {

+ 5 - 1
src/views/screen/material/program/ast/core/widget/CWeb.vue

@@ -4,6 +4,7 @@
     :style="styles"
   >
     <iframe
+      v-if="canLoad"
       class="c-web__iframe"
       :src="node.href"
     />
@@ -19,7 +20,7 @@ export default {
   props: {
     node: {
       type: Object,
-      default: null
+      required: true
     }
   },
   computed: {
@@ -33,6 +34,9 @@ export default {
         height: `${height}px`,
         'font-size': `${Math.min(width, height) / 3 | 0}px`
       }
+    },
+    canLoad () {
+      return this.control.preview !== false && !!this.node.href
     }
   }
 }