|
|
@@ -2,7 +2,7 @@
|
|
|
<div
|
|
|
v-loading.lock="loading"
|
|
|
element-loading-background="rgba(0, 0, 0, 0.8)"
|
|
|
- class="c-designer"
|
|
|
+ class="l-flex--col c-designer"
|
|
|
@contextmenu.prevent
|
|
|
>
|
|
|
<audio
|
|
|
@@ -13,113 +13,96 @@
|
|
|
@ended="onAudioEnded"
|
|
|
@error="onAudioError"
|
|
|
/>
|
|
|
- <div class="c-designer__side c-side">
|
|
|
- <div class="c-side__tool">
|
|
|
- <div
|
|
|
- class="c-side__item"
|
|
|
- :class="{ active: tabIndex === 0 }"
|
|
|
- @click="tabIndex = 0"
|
|
|
- >
|
|
|
- 工具栏
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-if="hasWidgets"
|
|
|
- class="c-side__item"
|
|
|
- :class="{ active: tabIndex === 1 }"
|
|
|
- @click="tabIndex = 1"
|
|
|
- >
|
|
|
- 图层
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <div class="l-flex__none l-flex--row c-designer__header">
|
|
|
+ <i
|
|
|
+ class="c-designer__shortcut el-icon-arrow-left u-bold u-pointer"
|
|
|
+ @click="onBack"
|
|
|
+ />
|
|
|
+ <span class="c-designer__name u-bold u-ellipsis">{{ program.name }}</span>
|
|
|
+ <span>{{ program.resolutionRatio }}</span>
|
|
|
+ <div class="l-flex__fill c-sibling-item" />
|
|
|
<div
|
|
|
- v-show="tabIndex === 0"
|
|
|
- class="c-side__content"
|
|
|
- @dragstart="widgetOnDragStart"
|
|
|
- @dragend="widgetOnDragEnd"
|
|
|
+ v-if="hasNext"
|
|
|
+ class="l-flex--row center c-sibling-item c-designer__shortcut u-pointer"
|
|
|
+ @click="switchBgm"
|
|
|
>
|
|
|
- <div
|
|
|
- v-for="cfg in widgetConfigs"
|
|
|
- :key="cfg.key"
|
|
|
- :data-type="cfg.type"
|
|
|
- class="c-widget"
|
|
|
- draggable
|
|
|
- >
|
|
|
- <span class="c-widget__icon">
|
|
|
- <i :class="cfg.icon" />
|
|
|
- </span>
|
|
|
- <span class="c-widget__text u-ellipsis">{{ cfg.label }}</span>
|
|
|
- </div>
|
|
|
+ <i class="o-next" />
|
|
|
</div>
|
|
|
<div
|
|
|
- v-show="tabIndex === 1"
|
|
|
- class="c-side__content"
|
|
|
+ v-if="hasAudio"
|
|
|
+ class="l-flex--row center c-sibling-item c-designer__shortcut u-pointer"
|
|
|
+ @click="toggleMute"
|
|
|
>
|
|
|
- <div
|
|
|
- v-for="(layer, index) in layers"
|
|
|
- :key="layer.id"
|
|
|
- class="c-widget"
|
|
|
- :class="{ active: layer.id === selectedWidgetId }"
|
|
|
- @mousedown="onLayerClick($event, index)"
|
|
|
- >
|
|
|
- <span class="c-widget__icon">
|
|
|
- <i :class="layer.icon" />
|
|
|
- </span>
|
|
|
- <span
|
|
|
- class="c-widget__text"
|
|
|
- :title="layer.name"
|
|
|
- >
|
|
|
- {{ layer.name }}
|
|
|
- </span>
|
|
|
- </div>
|
|
|
+ <volume :muted="muted" />
|
|
|
</div>
|
|
|
+ <button
|
|
|
+ v-if="hasWidgets"
|
|
|
+ class="c-sibling-item o-button mini"
|
|
|
+ @click="onClear"
|
|
|
+ >
|
|
|
+ <i class="o-button__icon el-icon-delete" />
|
|
|
+ 清空
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ class="c-sibling-item o-button mini"
|
|
|
+ @click="onSave"
|
|
|
+ >
|
|
|
+ <i class="o-button__icon iconfont iconsave" />
|
|
|
+ 保存
|
|
|
+ </button>
|
|
|
</div>
|
|
|
- <div class="c-designer__main">
|
|
|
- <div class="l-flex--row c-designer__tool">
|
|
|
- <i
|
|
|
- class="c-designer__btn el-icon-arrow-left u-bold"
|
|
|
- @click="onBack"
|
|
|
- />
|
|
|
- <div class="l-flex--row">
|
|
|
- <span class="c-sibling-item c-designer__name u-bold u-ellipsis">{{ program.name }}</span>
|
|
|
- <span class="c-sibling-item c-designer__ratio">{{ program.resolutionRatio }}</span>
|
|
|
+ <div class="l-flex__fill l-flex">
|
|
|
+ <div class="c-designer__side left c-side">
|
|
|
+ <div class="c-side__tool">
|
|
|
+ <div class="c-side__item">
|
|
|
+ 组件
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <el-tooltip
|
|
|
- key="save"
|
|
|
- class="c-designer__btn"
|
|
|
- content="保存"
|
|
|
- >
|
|
|
- <i
|
|
|
- class="iconfont iconsave"
|
|
|
- @click="onSave"
|
|
|
- />
|
|
|
- </el-tooltip>
|
|
|
- <el-tooltip
|
|
|
- v-if="hasWidgets"
|
|
|
- key="del"
|
|
|
- class="c-designer__btn"
|
|
|
- content="清空"
|
|
|
- >
|
|
|
- <i
|
|
|
- class="iconfont iconlajitong"
|
|
|
- @click="onClear"
|
|
|
- />
|
|
|
- </el-tooltip>
|
|
|
- <el-tooltip
|
|
|
- key="scale"
|
|
|
- class="c-designer__btn"
|
|
|
- content="缩放"
|
|
|
- :hide-after="2000"
|
|
|
+ <el-scrollbar
|
|
|
+ class="c-side__scrollbar"
|
|
|
+ native
|
|
|
>
|
|
|
- <div
|
|
|
- class="o-scale-slider"
|
|
|
- @click="toScale"
|
|
|
- >
|
|
|
+ <div class="c-side__content mini">
|
|
|
<div
|
|
|
- class="l-flex--row o-scale-slider__wrapper"
|
|
|
- :class="{ expand: dragScale }"
|
|
|
+ v-for="(widget, index) in layers"
|
|
|
+ ref="widgetElements"
|
|
|
+ :key="widget.id"
|
|
|
+ class="o-layer"
|
|
|
+ :class="{ active: widget.id === selectedWidgetId }"
|
|
|
+ @mousedown="onLayerClick($event, index)"
|
|
|
>
|
|
|
+ <widget-shortcut
|
|
|
+ class="dark"
|
|
|
+ :widget="widget"
|
|
|
+ @view="onViewAsset"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="node"
|
|
|
+ ref="rootElement"
|
|
|
+ key="root"
|
|
|
+ class="o-layer"
|
|
|
+ :class="{ active: !selectedWidgetId }"
|
|
|
+ @click="onRootClick"
|
|
|
+ >
|
|
|
+ <widget-shortcut
|
|
|
+ class="dark"
|
|
|
+ :widget="node"
|
|
|
+ :custom-style="backgroundStyles"
|
|
|
+ source-key="bgm"
|
|
|
+ background
|
|
|
+ @view="onViewAsset"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </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 o-scale-slider__wrapper">
|
|
|
<i
|
|
|
- class="el-icon-zoom-out"
|
|
|
+ class="el-icon-zoom-out u-pointer"
|
|
|
@click="scaleDown"
|
|
|
/>
|
|
|
<el-slider
|
|
|
@@ -127,109 +110,99 @@
|
|
|
class="o-scale-slider__slider"
|
|
|
:min="minScale"
|
|
|
:max="maxScale"
|
|
|
- @change="toScale"
|
|
|
/>
|
|
|
<i
|
|
|
- class="el-icon-zoom-in"
|
|
|
+ class="el-icon-zoom-in u-pointer"
|
|
|
@click="scaleUp"
|
|
|
/>
|
|
|
</div>
|
|
|
- <svg-icon
|
|
|
- v-if="dragScale"
|
|
|
- icon-class="exit-fullscreen"
|
|
|
- @click.stop="hideScale"
|
|
|
- />
|
|
|
- <svg-icon
|
|
|
- v-else
|
|
|
- icon-class="fullscreen"
|
|
|
- />
|
|
|
</div>
|
|
|
- </el-tooltip>
|
|
|
- <el-tooltip
|
|
|
- v-if="hasAudio"
|
|
|
- key="audio"
|
|
|
- class="c-designer__btn"
|
|
|
- content="音效"
|
|
|
- >
|
|
|
- <div @click="toggleMute">
|
|
|
- <volume :muted="muted" />
|
|
|
- </div>
|
|
|
- </el-tooltip>
|
|
|
- <el-tooltip
|
|
|
- v-if="hasNext"
|
|
|
- key="toggle-audio"
|
|
|
- class="c-designer__btn"
|
|
|
- content="切歌"
|
|
|
- >
|
|
|
- <div @click="switchBgm">
|
|
|
- <i class="o-next" />
|
|
|
+ <div
|
|
|
+ class="l-flex__none l-flex--row"
|
|
|
+ @dragstart="widgetOnDragStart"
|
|
|
+ @dragend="widgetOnDragEnd"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ v-for="cfg in widgetConfigs"
|
|
|
+ :key="cfg.key"
|
|
|
+ :data-type="cfg.type"
|
|
|
+ class="o-widget-cfg"
|
|
|
+ draggable
|
|
|
+ >
|
|
|
+ <span class="o-widget-cfg__icon">
|
|
|
+ <i :class="cfg.icon" />
|
|
|
+ </span>
|
|
|
+ <span class="o-widget-cfg__text">{{ cfg.label }}</span>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </el-tooltip>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- ref="wrapper"
|
|
|
- class="c-designer__content"
|
|
|
- @mousedown="onScreenClick"
|
|
|
- >
|
|
|
+ </div>
|
|
|
<div
|
|
|
- class="c-designer__wrapper"
|
|
|
- :style="wrapperStyles"
|
|
|
+ ref="wrapper"
|
|
|
+ class="c-designer__content"
|
|
|
+ @mousedown="onRootClick"
|
|
|
>
|
|
|
<div
|
|
|
- ref="canvas"
|
|
|
- class="c-designer__canvas"
|
|
|
- :style="[transformStyles, styles]"
|
|
|
- @dragover.prevent
|
|
|
- @drop.prevent="widgetOnDrop"
|
|
|
+ class="c-designer__wrapper"
|
|
|
+ :style="wrapperStyles"
|
|
|
>
|
|
|
<div
|
|
|
- class="c-designer__background has-bg"
|
|
|
- :style="backgroundStyles"
|
|
|
- />
|
|
|
- <div
|
|
|
- v-show="grid"
|
|
|
- class="c-designer__grid"
|
|
|
- />
|
|
|
- <widget
|
|
|
- v-for="(item, index) in widgets"
|
|
|
- :key="item.id"
|
|
|
- ref="widgets"
|
|
|
- :scale="100 / scale"
|
|
|
- :node="item"
|
|
|
- :root="node"
|
|
|
- @focus="onWidgetFocus(index)"
|
|
|
- @blur="onWidgetBlur"
|
|
|
- @menu="onWidgetMenu($event, index)"
|
|
|
- />
|
|
|
+ ref="canvas"
|
|
|
+ class="c-designer__canvas"
|
|
|
+ :style="[transformStyles, styles]"
|
|
|
+ @dragover.prevent
|
|
|
+ @drop.prevent="widgetOnDrop"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="c-designer__background has-bg"
|
|
|
+ :style="backgroundStyles"
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ v-show="grid"
|
|
|
+ class="c-designer__grid"
|
|
|
+ />
|
|
|
+ <widget
|
|
|
+ v-for="(item, index) in widgets"
|
|
|
+ :key="item.id"
|
|
|
+ ref="widgets"
|
|
|
+ :scale="100 / scale"
|
|
|
+ :node="item"
|
|
|
+ :root="node"
|
|
|
+ @focus="onWidgetFocus(index)"
|
|
|
+ @blur="onWidgetBlur"
|
|
|
+ @menu="onWidgetMenu($event, index)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <div class="c-designer__side large c-side">
|
|
|
- <div class="c-side__tool">
|
|
|
+ <div class="c-designer__side right c-side">
|
|
|
+ <div class="c-side__tool">
|
|
|
+ <div
|
|
|
+ v-for="(tab, index) in dynamicOptions"
|
|
|
+ :key="index"
|
|
|
+ class="c-side__item u-pointer"
|
|
|
+ :class="{ active: optionIndex === index }"
|
|
|
+ @click="optionIndex = index"
|
|
|
+ >
|
|
|
+ {{ tab.label }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<div
|
|
|
v-for="(tab, index) in dynamicOptions"
|
|
|
+ v-show="optionIndex === index"
|
|
|
:key="index"
|
|
|
- class="c-side__item"
|
|
|
+ class="c-side__scrollbar c-side__content u-overflow-y--auto"
|
|
|
:class="{ active: optionIndex === index }"
|
|
|
- @click="optionIndex = index"
|
|
|
- >{{ tab.label }}</div>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- v-for="(tab, index) in dynamicOptions"
|
|
|
- v-show="optionIndex === index"
|
|
|
- :key="index"
|
|
|
- class="c-side__content"
|
|
|
- :class="{ active: optionIndex === index }"
|
|
|
- >
|
|
|
- <dynamic-item
|
|
|
- v-for="item in tab.list"
|
|
|
- :key="item.key"
|
|
|
- :root="node"
|
|
|
- :node="widget"
|
|
|
- :attr="item"
|
|
|
- @choose="onEditData"
|
|
|
- />
|
|
|
+ >
|
|
|
+ <dynamic-item
|
|
|
+ v-for="item in tab.list"
|
|
|
+ :key="item.key"
|
|
|
+ :root="node"
|
|
|
+ :node="widget"
|
|
|
+ :attr="item"
|
|
|
+ @choose="onEditData"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<content-menu
|
|
|
@@ -245,14 +218,14 @@
|
|
|
<el-dialog
|
|
|
:visible.sync="showAssets"
|
|
|
:title="assetDialogType"
|
|
|
- custom-class="c-dialog"
|
|
|
+ custom-class="c-dialog large"
|
|
|
:close-on-click-modal="false"
|
|
|
:before-close="onCloseAssetsDialog"
|
|
|
>
|
|
|
<draggable
|
|
|
v-if="showAssets"
|
|
|
v-model="sources"
|
|
|
- class="c-grid"
|
|
|
+ class="c-info-grid mini"
|
|
|
:class="{ dragging }"
|
|
|
animation="300"
|
|
|
@start="onSourceDragStart"
|
|
|
@@ -345,12 +318,14 @@
|
|
|
</grid-table>
|
|
|
</template>
|
|
|
</confirm-dialog>
|
|
|
- <preview-dialog ref="previewDialog" />
|
|
|
+ <preview-dialog
|
|
|
+ ref="previewDialog"
|
|
|
+ @close="onClosePreview"
|
|
|
+ />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import Draggable from 'vuedraggable'
|
|
|
import domToImage from 'dom-to-image'
|
|
|
import { updateProgram } from '@/api/program'
|
|
|
import {
|
|
|
@@ -365,13 +340,13 @@ import {
|
|
|
widgets,
|
|
|
normalize,
|
|
|
getOptions,
|
|
|
- getIcon,
|
|
|
copy,
|
|
|
fix,
|
|
|
getDuration,
|
|
|
toJSON
|
|
|
} from './core/utils'
|
|
|
import mixin from './mixin'
|
|
|
+import Draggable from 'vuedraggable'
|
|
|
import Widget from './core/widget/Widget.vue'
|
|
|
import ContentMenu from './core/components/ContentMenu.vue'
|
|
|
import DynamicItem from './core/components/DynamicItem.vue'
|
|
|
@@ -379,8 +354,8 @@ import DynamicItem from './core/components/DynamicItem.vue'
|
|
|
export default {
|
|
|
name: 'BigScreenDesigner',
|
|
|
components: {
|
|
|
- Widget,
|
|
|
Draggable,
|
|
|
+ Widget,
|
|
|
ContentMenu,
|
|
|
DynamicItem
|
|
|
},
|
|
|
@@ -389,8 +364,7 @@ export default {
|
|
|
return {
|
|
|
loading: false,
|
|
|
snapping: false,
|
|
|
- padding: 10,
|
|
|
- tabIndex: 0,
|
|
|
+ padding: 16,
|
|
|
optionIndex: 0,
|
|
|
widgetConfigs: widgets,
|
|
|
grid: false,
|
|
|
@@ -424,16 +398,7 @@ export default {
|
|
|
return []
|
|
|
},
|
|
|
layers () {
|
|
|
- const layers = []
|
|
|
- for (let i = this.widgets.length - 1; i >= 0; i--) {
|
|
|
- const { id, type, layerName } = this.widgets[i]
|
|
|
- layers.push({
|
|
|
- id: id,
|
|
|
- icon: getIcon(type),
|
|
|
- name: layerName
|
|
|
- })
|
|
|
- }
|
|
|
- return layers
|
|
|
+ return this.widgets.slice().reverse()
|
|
|
},
|
|
|
assetType () {
|
|
|
if (this.widgetAttr?.type === 'data') {
|
|
|
@@ -450,14 +415,14 @@ export default {
|
|
|
case AssetType.AUDIO:
|
|
|
return '音频'
|
|
|
default:
|
|
|
- return '数据'
|
|
|
+ return '媒资'
|
|
|
}
|
|
|
},
|
|
|
assetDialogTitle () {
|
|
|
return `请选择${this.assetDialogType}`
|
|
|
},
|
|
|
selectedWidgetId () {
|
|
|
- return this.widget.id
|
|
|
+ return this.widget?.id
|
|
|
},
|
|
|
wrapperStyles () {
|
|
|
return this.node ? {
|
|
|
@@ -477,6 +442,15 @@ export default {
|
|
|
id && this.$refs.widgets[this.$refs.widgets.findIndex(w => w.node.id === id)]?.$refs.draggable.setActive(true)
|
|
|
}
|
|
|
this.optionIndex = 0
|
|
|
+ },
|
|
|
+ widget () {
|
|
|
+ this.node && setTimeout(() => {
|
|
|
+ if (this.selectedWidgetIndex === -1) {
|
|
|
+ this.$refs.rootElement.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
|
+ } else {
|
|
|
+ this.$refs.widgetElements.find(element => element.classList.contains('active')).scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
@@ -485,7 +459,6 @@ export default {
|
|
|
'清空后所有数据将丢失',
|
|
|
'清空画布'
|
|
|
).then(() => {
|
|
|
- this.tabIndex = 0
|
|
|
this.selectedWidgetIndex = -1
|
|
|
const { width, height } = this.node
|
|
|
this.initCanvas({ width, height })
|
|
|
@@ -493,6 +466,7 @@ export default {
|
|
|
},
|
|
|
widgetOnDragStart (evt) {
|
|
|
evt.dataTransfer.setData('type', evt.target.dataset.type)
|
|
|
+ console.log(evt.dataTransfer)
|
|
|
this.dragging = true
|
|
|
},
|
|
|
widgetOnDragEnd () {
|
|
|
@@ -532,7 +506,7 @@ export default {
|
|
|
this.selectedWidgetIndex = this.widgets.length - 1 - index
|
|
|
this.onRightClick(evt)
|
|
|
},
|
|
|
- onScreenClick () {
|
|
|
+ onRootClick () {
|
|
|
this.selectedWidgetIndex = -1
|
|
|
},
|
|
|
onRightClick (evt) {
|
|
|
@@ -646,16 +620,7 @@ export default {
|
|
|
if (thumbnail) {
|
|
|
asset.thumbnailUrl = getThumbnailUrl(thumbnail)
|
|
|
} else {
|
|
|
- switch (type) {
|
|
|
- case AssetType.VIDEO:
|
|
|
- asset.icon = 'video-bg'
|
|
|
- break
|
|
|
- case AssetType.AUDIO:
|
|
|
- asset.icon = 'audio-bg'
|
|
|
- break
|
|
|
- default:
|
|
|
- break
|
|
|
- }
|
|
|
+ asset.icon = `${type === AssetType.VIDEO ? 'video' : 'audio'}-bg`
|
|
|
}
|
|
|
return asset
|
|
|
},
|
|
|
@@ -685,7 +650,7 @@ export default {
|
|
|
}
|
|
|
if (data.thumbnail) {
|
|
|
source.thumbnailUrl = getThumbnailUrl(data.thumbnail)
|
|
|
- } else if (data.type === AssetType.IMAGE) {
|
|
|
+ } else if (source.type === AssetType.IMAGE) {
|
|
|
source.thumbnailUrl = getThumbnailUrl(data.keyName)
|
|
|
} else {
|
|
|
switch (source.type) {
|
|
|
@@ -728,8 +693,15 @@ export default {
|
|
|
this.onViewAsset({ type: type || this.widgetAttr.options.type, url: keyName })
|
|
|
},
|
|
|
onViewAsset (asset) {
|
|
|
+ this.$muted = this.muted
|
|
|
+ if (!this.muted) {
|
|
|
+ this.muted = true
|
|
|
+ }
|
|
|
this.$refs.previewDialog.show(asset)
|
|
|
},
|
|
|
+ onClosePreview () {
|
|
|
+ this.muted = this.$muted
|
|
|
+ },
|
|
|
onDelAsset (index) {
|
|
|
this.$confirm(
|
|
|
'移除该数据?',
|
|
|
@@ -744,12 +716,6 @@ export default {
|
|
|
onSourceDragEnd () {
|
|
|
this.dragging = false
|
|
|
},
|
|
|
- toScale () {
|
|
|
- this.dragScale = true
|
|
|
- },
|
|
|
- hideScale () {
|
|
|
- this.dragScale = false
|
|
|
- },
|
|
|
scaleDown () {
|
|
|
this.scale = Math.max(this.scale - 10, this.minScale)
|
|
|
},
|
|
|
@@ -840,19 +806,64 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-$drak: #242a30;
|
|
|
+$theme: #181b23;
|
|
|
+$dark: #121418;
|
|
|
+$light: #1f232e;
|
|
|
+$hover: lighten($theme, 10%);
|
|
|
+$active: darken($theme, 5%);
|
|
|
+$border: #242835;
|
|
|
|
|
|
.c-designer {
|
|
|
- display: flex;
|
|
|
height: 100%;
|
|
|
+ min-width: 1080px;
|
|
|
+ min-height: 600px;
|
|
|
+ background-color: $theme;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ &__header {
|
|
|
+ height: 53px;
|
|
|
+ padding-left: 10px;
|
|
|
+ color: $info;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 1;
|
|
|
+ border-bottom: 1px solid $border;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__shortcut {
|
|
|
+ display: inline-flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 36px;
|
|
|
+ height: 36px;
|
|
|
+ font-size: 18px;
|
|
|
+ border-radius: 50%;
|
|
|
+ transition: background-color 0.4s;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: $hover;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:active {
|
|
|
+ background-color: $active;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &__name {
|
|
|
+ max-width: 400px;
|
|
|
+ padding: 0 $spacing 0 6px;
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
|
|
|
&__side {
|
|
|
flex: none;
|
|
|
- width: 180px;
|
|
|
min-height: 0;
|
|
|
|
|
|
- &.large {
|
|
|
- width: 240px;
|
|
|
+ &.left {
|
|
|
+ width: 144px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.right {
|
|
|
+ width: 196px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -867,48 +878,16 @@ $drak: #242a30;
|
|
|
&__content {
|
|
|
flex: 1 0 0;
|
|
|
position: relative;
|
|
|
- padding: 10px;
|
|
|
+ padding: 16px;
|
|
|
overflow: auto;
|
|
|
- background: url("~@/assets/dot.png") repeat;
|
|
|
+ background: $dark url("~@/assets/dot.png") 0 0 / 16px 16px repeat;
|
|
|
}
|
|
|
|
|
|
&__tool {
|
|
|
- flex: 0 0 40px;
|
|
|
- color: $gray--dark;
|
|
|
- background-color: $drak;
|
|
|
- }
|
|
|
-
|
|
|
- &__name {
|
|
|
- max-width: 400px;
|
|
|
- font-size: 18px;
|
|
|
- line-height: 1;
|
|
|
- }
|
|
|
-
|
|
|
- &__ratio {
|
|
|
- font-size: 12px;
|
|
|
- line-height: 1;
|
|
|
- }
|
|
|
-
|
|
|
- &__btn {
|
|
|
- display: inline-flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
- width: 55px;
|
|
|
- height: 100%;
|
|
|
- color: $gray;
|
|
|
- cursor: pointer;
|
|
|
-
|
|
|
- &:hover {
|
|
|
- background-color: #191d22;
|
|
|
- }
|
|
|
-
|
|
|
- &:active {
|
|
|
- background-color: darken(#191d22, 5%);
|
|
|
- }
|
|
|
-
|
|
|
- &.iconlajitong {
|
|
|
- font-size: 20px;
|
|
|
- }
|
|
|
+ flex: 0 0 60px;
|
|
|
+ color: $info;
|
|
|
+ border-left: 1px solid $border;
|
|
|
+ border-right: 1px solid $border;
|
|
|
}
|
|
|
|
|
|
&__wrapper {
|
|
|
@@ -920,17 +899,6 @@ $drak: #242a30;
|
|
|
position: relative;
|
|
|
background-color: #000;
|
|
|
overflow: visible;
|
|
|
-
|
|
|
- &::before {
|
|
|
- content: "";
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- background-color: currentColor;
|
|
|
- z-index: -1;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
&__background {
|
|
|
@@ -939,6 +907,7 @@ $drak: #242a30;
|
|
|
left: 0;
|
|
|
right: 0;
|
|
|
bottom: 0;
|
|
|
+ background-color: currentColor;
|
|
|
z-index: -1;
|
|
|
}
|
|
|
|
|
|
@@ -957,90 +926,95 @@ $drak: #242a30;
|
|
|
.c-side {
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- background-color: $drak;
|
|
|
|
|
|
&__tool {
|
|
|
flex: none;
|
|
|
display: flex;
|
|
|
+ border-bottom: 1px solid $border;
|
|
|
+ background-color: $light;
|
|
|
}
|
|
|
|
|
|
&__item {
|
|
|
flex: 1 0 0;
|
|
|
- color: #909399;
|
|
|
- font-size: 14px;
|
|
|
+ color: #5b6275;
|
|
|
+ font-size: 16px;
|
|
|
text-align: center;
|
|
|
- line-height: 40px;
|
|
|
- background-color: #242f3b;
|
|
|
+ line-height: 60px;
|
|
|
user-select: none;
|
|
|
- cursor: pointer;
|
|
|
|
|
|
&.active {
|
|
|
- color: #409eff;
|
|
|
- background-color: #31455d;
|
|
|
+ color: $blue;
|
|
|
+ background-color: $theme;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
&__content {
|
|
|
- flex: 1 0 0;
|
|
|
- min-height: 0;
|
|
|
- padding: 15px;
|
|
|
- overflow-y: auto;
|
|
|
-
|
|
|
- &::-webkit-scrollbar {
|
|
|
- width: 4px;
|
|
|
- height: 4px;
|
|
|
- }
|
|
|
+ padding: 10px 16px;
|
|
|
|
|
|
- &::-webkit-scrollbar-track-piece {
|
|
|
- background-color: #29405c;
|
|
|
- }
|
|
|
-
|
|
|
- &::-webkit-scrollbar-track {
|
|
|
- box-shadow: 1px 1px 5px rgba(116, 148, 170, 0.5) inset;
|
|
|
+ &.mini {
|
|
|
+ padding: 10px;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- &::-webkit-scrollbar-thumb {
|
|
|
- min-height: 20px;
|
|
|
- background-clip: content-box;
|
|
|
- box-shadow: 0 0 0 5px rgba(116, 148, 170, 0.5) inset;
|
|
|
- }
|
|
|
+ &__scrollbar {
|
|
|
+ flex: 1 0 0;
|
|
|
+ min-height: 10px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.c-widget {
|
|
|
- display: flex;
|
|
|
+.o-widget-cfg {
|
|
|
+ display: inline-flex;
|
|
|
+ flex-direction: column;
|
|
|
align-items: center;
|
|
|
position: relative;
|
|
|
- width: 100%;
|
|
|
- height: 48px;
|
|
|
- margin-bottom: 1px;
|
|
|
- padding: 0 6px;
|
|
|
- color: #bfcbd9;
|
|
|
- font-size: 12px;
|
|
|
user-select: none;
|
|
|
cursor: pointer;
|
|
|
|
|
|
+ & + & {
|
|
|
+ margin-left: 32px;
|
|
|
+ }
|
|
|
+
|
|
|
&.active {
|
|
|
background-color: #31455d;
|
|
|
}
|
|
|
|
|
|
&__icon {
|
|
|
flex: none;
|
|
|
- display: inline-block;
|
|
|
- margin-right: 10px;
|
|
|
- width: 52px;
|
|
|
- height: 30px;
|
|
|
- color: #409eff;
|
|
|
- font-size: 16px;
|
|
|
- line-height: 30px;
|
|
|
- text-align: center;
|
|
|
- border: 1px solid #3a4659;
|
|
|
- background-color: #282a30;
|
|
|
+ display: inline-flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ color: #fff;
|
|
|
+ font-size: 22px;
|
|
|
+ border-radius: $radius;
|
|
|
+ background-color: $blue;
|
|
|
}
|
|
|
|
|
|
&__text {
|
|
|
- flex: 1 1 auto;
|
|
|
- min-width: 0;
|
|
|
+ margin-top: 6px;
|
|
|
+ color: #9fa5b8;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.o-layer {
|
|
|
+ color: $gray--dark;
|
|
|
+ user-select: none;
|
|
|
+ border-radius: $radius;
|
|
|
+ background-color: #252d42;
|
|
|
+ overflow: hidden;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ & + & {
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ color: #fff;
|
|
|
+ outline: 2px solid $blue;
|
|
|
+ background-color: $blue;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -1095,17 +1069,6 @@ $drak: #242a30;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.o-image {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- background-position: center;
|
|
|
- background-size: contain;
|
|
|
- background-repeat: no-repeat;
|
|
|
-}
|
|
|
-
|
|
|
.o-scale-slider {
|
|
|
justify-content: flex-start;
|
|
|
min-width: 48px;
|
|
|
@@ -1114,13 +1077,9 @@ $drak: #242a30;
|
|
|
font-size: 20px;
|
|
|
|
|
|
&__wrapper {
|
|
|
- width: 0;
|
|
|
+ width: 184px;
|
|
|
transition: width 0.1s;
|
|
|
overflow: hidden;
|
|
|
-
|
|
|
- &.expand {
|
|
|
- width: 184px;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
&__slider {
|