feat: 新增自定义背景图

This commit is contained in:
MTrun 2022-02-06 21:35:38 +08:00
parent 688ce50c58
commit 8fb8b9328d
18 changed files with 297 additions and 51 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

View File

@ -0,0 +1,5 @@
<template>
<div>
<Skeleton repeat="3" :show="true"/>
</div>
</template>

View File

@ -1,6 +1,7 @@
import type { App } from 'vue'
import LoadingComponent from './index.vue'
import AsyncLoading from './index.vue'
import AsyncSkeletonLoading from './Skeleton.vue'
// 正常组件
export { LoadingComponent }
@ -9,4 +10,8 @@ export { LoadingComponent }
AsyncLoading.install = (app: App): void => {
app.component('AsyncLoading', AsyncLoading)
}
export { AsyncLoading }
AsyncSkeletonLoading.install = (app: App): void => {
app.component('AsyncSkeletonLoading', AsyncSkeletonLoading)
}
export { AsyncLoading, AsyncSkeletonLoading }

View File

@ -101,7 +101,7 @@ const ionicons5 = {
PencilIcon,
// 编辑2锤子
HammerIcon,
// 预览
// 电脑
DesktopOutlineIcon,
// 下载
DownloadIcon,
@ -115,7 +115,7 @@ const ionicons5 = {
GridIcon,
// 电脑1
TvOutlineIcon,
// 浏览器
// 预览,浏览器
BrowsersOutlineIcon,
// 文档
DocumentTextIcon,

View File

@ -84,6 +84,7 @@ import {
NPopselect,
NCollapse,
NCollapseItem,
NColorPicker,
NCollapseTransition
} from 'naive-ui';
@ -172,6 +173,7 @@ const naive = create({
NPopselect,
NCollapse,
NCollapseItem,
NColorPicker,
NCollapseTransition
],
});

View File

@ -5,13 +5,10 @@ import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHi
export enum EditCanvasTypeEnum {
EDIT_LAYOUT_DOM = 'editLayoutDom',
EDIT_CONTENT_DOM = 'editContentDom',
WIDTH = 'width',
HEIGHT = 'height',
OFFSET = 'offset',
SCALE = 'scale',
USER_SCALE = 'userScale',
LOCK_SCALE = 'lockScale',
BACKGROUND = 'background'
}
// 编辑区域
@ -30,33 +27,42 @@ export type EditCanvasType = {
}
// 滤镜
export enum EditCanvasFilterEnum {
export enum EditCanvasConfigEnum {
WIDTH = 'width',
HEIGHT = 'height',
HUE_ROTATE = 'hueRotate',
SATURATE = 'saturate',
BRIGHTNESS = 'brightness',
CONTRAST = 'contrast',
UN_OPACITY = 'unOpacity',
CHART_THEME = 'chartTheme',
BACKGROUND = 'background',
BACKGROUND_IAMGE = 'backgroundImage',
SELECT_COLOR = 'selectColor'
}
export interface EditCanvasConfigType {
// 大屏宽度
[EditCanvasTypeEnum.WIDTH]: number
[EditCanvasConfigEnum.WIDTH]: number
// 大屏高度
[EditCanvasTypeEnum.HEIGHT]: number
[EditCanvasConfigEnum.HEIGHT]: number
// 色相
[EditCanvasFilterEnum.HUE_ROTATE]: number
[EditCanvasConfigEnum.HUE_ROTATE]: number
// 饱和度
[EditCanvasFilterEnum.SATURATE]: number
[EditCanvasConfigEnum.SATURATE]: number
// 亮度
[EditCanvasFilterEnum.BRIGHTNESS]: number
[EditCanvasConfigEnum.BRIGHTNESS]: number
// 对比度
[EditCanvasFilterEnum.CONTRAST]: number
[EditCanvasConfigEnum.CONTRAST]: number
// 不透明度
[EditCanvasFilterEnum.UN_OPACITY]: number
[EditCanvasConfigEnum.UN_OPACITY]: number
// 背景色
[EditCanvasTypeEnum.BACKGROUND]?: string
[EditCanvasConfigEnum.BACKGROUND]?: string
[EditCanvasConfigEnum.BACKGROUND_IAMGE]?: string | ArrayBuffer | null
// 图表主题颜色
[EditCanvasFilterEnum.CHART_THEME]: string
[EditCanvasConfigEnum.CHART_THEME]: string
// 图表主题颜色
[EditCanvasConfigEnum.SELECT_COLOR]: boolean
}
// 坐标轴信息

View File

@ -54,6 +54,9 @@ export const useChartEditStoreStore = defineStore({
unOpacity: 100,
// 默认背景色
background: undefined,
backgroundImage: undefined,
// 是否使用纯颜色
selectColor: true,
// chart 主题色
chartTheme: defaultTheme || 'dark'
},

View File

@ -1,5 +1,5 @@
import { defineAsyncComponent, AsyncComponentLoader } from 'vue'
import { AsyncLoading } from '@/components/LoadingComponent'
import { AsyncLoading, AsyncSkeletonLoading } from '@/components/LoadingComponent'
/**
* *
@ -12,3 +12,10 @@ export const loadAsyncComponent = (loader: AsyncComponentLoader<any>) =>
loadingComponent: AsyncLoading,
delay: 20,
})
export const loadSkeletonAsyncComponent = (loader: AsyncComponentLoader<any>) =>
defineAsyncComponent({
loader,
loadingComponent: AsyncSkeletonLoading,
delay: 20,
})

View File

@ -91,6 +91,7 @@ export const setDomAttribute = <K extends keyof CSSStyleDeclaration, V extends C
HTMLElement.style[key] = value
}
}
/**
* * mac
* @returns boolean
@ -98,6 +99,21 @@ export const setDomAttribute = <K extends keyof CSSStyleDeclaration, V extends C
export const isMac = () => {
return /macintosh|mac os x/i.test(navigator.userAgent)
}
/**
* * file转base64
*/
export const fileTobase64 = (file:File, callback: Function) => {
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e: ProgressEvent<FileReader>) {
if(e.target) {
let base64 = e.target.result;
callback(base64)
}
};
};
/**
* *
*/

View File

@ -34,7 +34,7 @@
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useChartEditStoreStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasFilterEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import {
chartColors,
chartColorsName,
@ -61,7 +61,7 @@ const fetchShowColors = (colors: Array<string>) => {
}
const selectTheme = (theme: string) => {
chartEditStoreStore.setCanvasConfig(EditCanvasFilterEnum.CHART_THEME, theme)
chartEditStoreStore.setCanvasConfig(EditCanvasConfigEnum.CHART_THEME, theme)
}
</script>

View File

@ -1,16 +1,218 @@
<template>
<div class="go-canvas-setting">
<n-form inline :label-width="45" size="small" label-placement="left">
<n-form-item label="宽度">
<!-- 尺寸选择 -->
<n-input-number
size="small"
v-model:value="canvasConfig.width"
:validator="validator"
@update:value="chartEditStoreStore.computedScale"
/>
</n-form-item>
<n-form-item label="高度">
<n-input-number
size="small"
v-model:value="canvasConfig.height"
:validator="validator"
@update:value="chartEditStoreStore.computedScale"
/>
</n-form-item>
</n-form>
<n-card class="upload-box">
<n-upload
v-model:file-list="uploadFileListRef"
:show-file-list="false"
:customRequest="customRequest"
:onBeforeUpload="beforeUploadHandle"
>
<n-upload-dragger>
<img
class="upload-show"
v-if="canvasConfig.backgroundImage"
:src="canvasConfig.backgroundImage"
alt="背景"
/>
<div class="upload-img" v-show="!canvasConfig.backgroundImage">
<img src="@/assets/images/canvas/noImage.png" />
<n-text class="upload-desc" depth="3">
背景图需小于 2M 格式为 png/jpg/gif 的文件
</n-text>
</div>
</n-upload-dragger>
</n-upload>
</n-card>
<n-space vertical :size="12">
<n-space>
<n-text>背景色</n-text>
<n-color-picker
style="width: 326px;"
:showPreview="true"
:swatches="[
'#232324',
'#2a2a2b',
'#313132',
'#373739',
'#757575',
'#e0e0e0',
'#eeeeee',
'#fafafa'
]"
v-model:value="canvasConfig.background"
/>
</n-space>
<n-space>
<n-text>使用颜色</n-text>
<n-switch
size="small"
v-model:value="canvasConfig.selectColor"
:loading="switchSelectColorLoading"
:round="false"
:disabled="!canvasConfig.backgroundImage"
:onUpdate="switchSelectColorHandle"
/>
</n-space>
<n-space>
<n-text>背景</n-text>
<n-button
size="small"
:disabled="!canvasConfig.backgroundImage"
@click="clearImage"
>
清除背景图
</n-button>
<n-button
size="small"
:disabled="!canvasConfig.background"
@click="clearColor"
>
清除颜色
</n-button>
</n-space>
</n-space>
<n-divider />
<!-- 主题选择 -->
<ChartTheme />
</div>
</template>
<script setup>
<script setup lang="ts">
import { ref, nextTick, onMounted } from 'vue'
import { useChartEditStoreStore } from '@/store/modules/chartEditStore/chartEditStore'
const chartEditStoreStore = useChartEditStoreStore()
import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { UploadCustomRequestOptions, UploadFileInfo } from 'naive-ui'
import { ChartTheme } from './components/ChartTheme/index'
import { fileTobase64 } from '@/utils'
const chartEditStoreStore = useChartEditStoreStore()
const canvasConfig = chartEditStoreStore.getEditCanvasConfig
const uploadFileListRef = ref()
const switchSelectColorLoading = ref(false)
//
const validator = (x: number) => x > 50
//
//@ts-ignore
const beforeUploadHandle = async ({ file }) => {
uploadFileListRef.value = []
const type = file.file.type
const size = file.file.size
if (size > 1024 * 1024 * 2) {
window['$message'].warning('图片超出 2M 限制,请重新上传!')
return false
}
if (type !== 'image/png' && type !== 'image/jpeg' && type !== 'image/gif') {
window['$message'].warning('文件格式不符合,请重新上传!')
return false
}
return true
}
//
const clearImage = () => {
chartEditStoreStore.setCanvasConfig(
EditCanvasConfigEnum.BACKGROUND_IAMGE,
undefined
)
}
//
const clearColor = () => {
chartEditStoreStore.setCanvasConfig(
EditCanvasConfigEnum.BACKGROUND,
undefined
)
}
//
const switchSelectColorHandle = () => {
switchSelectColorLoading.value = true
setTimeout(() => {
switchSelectColorLoading.value = false
}, 1000)
}
//
const customRequest = (options: UploadCustomRequestOptions) => {
const {
file,
data,
headers,
withCredentials,
action,
onFinish,
onError,
onProgress
} = options
nextTick(() => {
fileTobase64(file.file as File, (e: string | ArrayBuffer | null) => {
chartEditStoreStore.setCanvasConfig(
EditCanvasConfigEnum.BACKGROUND_IAMGE,
e
)
})
})
}
</script>
<style lang="scss" scoped>
@include go(canvas-setting) {
padding-top: 20px;
.upload-box {
cursor: pointer;
margin-bottom: 20px;
@include deep() {
.n-card__content {
padding: 0px;
overflow: hidden;
}
}
.upload-show {
display: block;
width: 326px;
height: 193px;
margin-bottom: -7px;
border-radius: 5px;
}
.upload-img {
display: flex;
flex-direction: column;
align-items: center;
width: 326px;
img {
height: 150px;
}
.upload-desc {
padding: 10px 0;
}
}
}
}
</style>

View File

@ -31,7 +31,7 @@
<n-space>
<span> 页面设置 </span>
<n-icon size="16" class="icon-position">
<BrowsersOutlineIcon />
<DesktopOutlineIcon />
</n-icon>
</n-space>
</template>
@ -72,7 +72,7 @@
<script setup lang="ts">
import { shallowRef, ref, toRefs, watch, computed, reactive } from 'vue'
import { icon } from '@/plugins'
import { loadAsyncComponent } from '@/utils'
import { loadAsyncComponent, loadSkeletonAsyncComponent } from '@/utils'
import { ContentBox } from '../ContentBox/index'
import { useChartLayoutStore } from '@/store/modules/chartLayoutStore/chartLayoutStore'
import { ChartLayoutStoreEnum } from '@/store/modules/chartLayoutStore/chartLayoutStore.d'
@ -82,17 +82,12 @@ const { getDetails } = toRefs(useChartLayoutStore())
const { setItem } = useChartLayoutStore()
const chartEditStoreStore = useChartEditStoreStore()
const { ConstructIcon, FlashIcon, BrowsersOutlineIcon } = icon.ionicons5
const { ConstructIcon, FlashIcon, DesktopOutlineIcon } = icon.ionicons5
const ContentEdit = loadAsyncComponent(() => import('../ContentEdit/index.vue'))
const CanvasPage = loadAsyncComponent(() =>
import('./components/CanvasPage/index.vue')
)
const Setting = loadAsyncComponent(() =>
import('./components/Setting/index.vue')
)
const Behind = loadAsyncComponent(() => import('./components/Behind/index.vue'))
const CanvasPage = loadSkeletonAsyncComponent(() =>import('./components/CanvasPage/index.vue'))
const Setting = loadSkeletonAsyncComponent(() =>import('./components/Setting/index.vue'))
const Behind = loadSkeletonAsyncComponent(() => import('./components/Behind/index.vue'))
const collapsed = ref<boolean>(getDetails.value)

View File

@ -9,30 +9,32 @@
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { toRefs, computed } from 'vue'
import { useChartEditStoreStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useSizeStyle } from '../../hooks/useStyle.hook'
import { mousedownHandleUnStop } from '../../hooks/useDrop.hook'
const chartEditStoreStore = useChartEditStoreStore()
const canvasConfig = ref(chartEditStoreStore.getEditCanvasConfig)
const { getEditCanvasConfig } = toRefs(chartEditStoreStore)
const size = computed(() => {
return {
w: canvasConfig.value.width,
h: canvasConfig.value.height
w: getEditCanvasConfig.value.width,
h: getEditCanvasConfig.value.height
}
})
const background = computed(() => {
const background = canvasConfig.value.background
return background ? background : '#232324'
})
const style = computed(() => {
const background = getEditCanvasConfig.value.background
const backgroundImage = getEditCanvasConfig.value.backgroundImage
const selectColor = getEditCanvasConfig.value.selectColor
const backgroundColor = background ? background : null
const computed = selectColor
? { background: backgroundColor }
: { background: `url(${backgroundImage}) no-repeat center/100% !important` }
// @ts-ignore
return { ...useSizeStyle(size.value), background: background.value }
return { ...useSizeStyle(size.value), ...computed }
})
</script>
@ -41,7 +43,7 @@ const style = computed(() => {
position: relative;
border: 1px solid;
border-radius: 15px;
@include filter-bg-color('background-color2');
background: url('@/assets/images/canvas/pageBg.png');
@include fetch-theme('box-shadow');
@include filter-border-color('hover-border-color');
@include fetch-theme-custom('border-color', 'background-color4');

View File

@ -4,7 +4,6 @@
@select="handleSelect"
:show="showDropdownRef"
:options="options"
scrollable
size="small"
placement="top-start"
style="max-height: 100vh; overflow-y: auto;"

View File

@ -19,9 +19,13 @@ export const handleDrop = async (e: DragEvent) => {
try {
loadingStart()
// 获取拖拽数据
const drayDataString = e!.dataTransfer!.getData(DragKeyEnum.DROG_KEY)
if (!drayDataString) {
loadingFinish()
return
}
const dropData: Exclude<ConfigType, ['node', 'image']> = JSON.parse(
drayDataString
)
@ -67,8 +71,8 @@ export const useMouseHandle = () => {
onClickoutside()
chartEditStore.setTargetSelectChart(item.id)
const scale = chartEditStore.getEditCanvas.scale
const width = chartEditStore.getEditCanvas.width
const height = chartEditStore.getEditCanvas.height
const width = chartEditStore.getEditCanvasConfig.width
const height = chartEditStore.getEditCanvasConfig.height
// 获取编辑区域 Dom
const editcontentDom = chartEditStore.getEditCanvas.editContentDom

View File

@ -15,13 +15,13 @@
import { reactive } from 'vue'
import { renderIcon } from '@/utils'
import { icon } from '@/plugins'
const { DesktopOutlineIcon, SendIcon } = icon.ionicons5
const { BrowsersOutlineIcon, SendIcon } = icon.ionicons5
const btnList = reactive([
{
select: true,
title: '预览',
icon: renderIcon(DesktopOutlineIcon)
icon: renderIcon(BrowsersOutlineIcon)
},
{
select: true,

View File

@ -92,7 +92,7 @@ const {
CopyIcon,
TrashIcon,
PencilIcon,
DesktopOutlineIcon,
BrowsersOutlineIcon,
DownloadIcon,
HammerIcon,
SendIcon
@ -122,7 +122,7 @@ const selectOptions = ref([
{
label: renderLang('global.r_preview'),
key: 'preview',
icon: renderIcon(DesktopOutlineIcon)
icon: renderIcon(BrowsersOutlineIcon)
},
{
label: renderLang('global.r_copy'),