diff --git a/core/core-frontend/src/components/data-visualization/canvas/ComponentWrapper.vue b/core/core-frontend/src/components/data-visualization/canvas/ComponentWrapper.vue
index 4631393280..7a1b32407f 100644
--- a/core/core-frontend/src/components/data-visualization/canvas/ComponentWrapper.vue
+++ b/core/core-frontend/src/components/data-visualization/canvas/ComponentWrapper.vue
@@ -13,6 +13,11 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { activeWatermarkCheckUser, removeActiveWatermark } from '@/components/watermark/watermark'
import { isMobile } from '@/utils/utils'
import { isDashboard, isMainCanvas } from '@/utils/canvasUtils'
+import {
+ isBlurBgEnabled,
+ getBlurBgStyle,
+ getComponentBackgroundStyle
+} from '@/utils/backgroundStyleUtils'
import { XpackComponent } from '@/components/plugin'
import { useAppStoreWithOut } from '@/store/modules/app'
import DePreviewPopDialog from '@/components/visualization/DePreviewPopDialog.vue'
@@ -222,43 +227,20 @@ const onMouseEnter = () => {
eventBus.emit('v-hover', config.value.id)
}
+const blurBgEnable = computed(() => {
+ return isBlurBgEnabled(config.value.commonBackground)
+})
+
+const blurBgStyle = computed(() => {
+ return getBlurBgStyle(config.value.commonBackground, deepScale.value)
+})
+
const componentBackgroundStyle = computed(() => {
if (config.value.commonBackground) {
- const {
- backdropFilterEnable,
- backdropFilter,
- backgroundColorSelect,
- backgroundColor,
- backgroundImageEnable,
- backgroundType,
- outerImage,
- innerPadding,
- borderRadius
- } = config.value.commonBackground
- let style = {
- padding: innerPadding * deepScale.value + 'px',
- borderRadius: borderRadius + 'px'
- }
- let colorRGBA = ''
- if (backgroundColorSelect && backgroundColor) {
- colorRGBA = backgroundColor
- }
- if (backgroundImageEnable) {
- if (backgroundType === 'outerImage' && typeof outerImage === 'string') {
- style['background'] = `url(${imgUrlTrans(outerImage)}) no-repeat ${colorRGBA}`
- } else {
- style['background-color'] = colorRGBA
- }
- } else {
- style['background-color'] = colorRGBA
- }
- if (config.value.component !== 'UserView') {
- style['overflow'] = 'hidden'
- }
- if (backdropFilterEnable) {
- style['backdrop-filter'] = 'blur(' + backdropFilter + 'px)'
- }
- return style
+ return getComponentBackgroundStyle(config.value.commonBackground, {
+ scale: deepScale.value,
+ isUserView: config.value.component === 'UserView'
+ })
}
return {}
})
@@ -470,6 +452,7 @@ const updateFromMobile = (e, type) => {
:id="viewDemoInnerId"
:style="componentBackgroundStyle"
>
+
{
}
}
+.blur-bg {
+ width: 100%;
+ height: 100%;
+ background-size: 100% 100% !important;
+}
+
.wrapper-edit-bar-active {
display: inherit !important;
}
diff --git a/core/core-frontend/src/components/data-visualization/canvas/Shape.vue b/core/core-frontend/src/components/data-visualization/canvas/Shape.vue
index a1ece60a22..6a63db146c 100644
--- a/core/core-frontend/src/components/data-visualization/canvas/Shape.vue
+++ b/core/core-frontend/src/components/data-visualization/canvas/Shape.vue
@@ -73,6 +73,8 @@
@click="selectCurComponent"
@mousedown="handleInnerMouseDownOnShape"
>
+
+
@@ -159,9 +161,10 @@ import Board from '@/components/de-board/Board.vue'
import { activeWatermarkCheckUser, removeActiveWatermark } from '@/components/watermark/watermark'
import { useI18n } from '@/hooks/web/useI18n'
import {
- CommonBackground,
- ShorthandMode
-} from '@/components/visualization/component-background/Types'
+ isBlurBgEnabled,
+ getBlurBgStyle,
+ getComponentBackgroundStyle
+} from '@/utils/backgroundStyleUtils'
const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut()
@@ -982,68 +985,23 @@ const padding3D = computed(() => {
}
})
+// 是否启用背景模糊,有背景图且开启了模糊
+const blurBgEnable = computed(() => {
+ return isBlurBgEnabled(element.value.commonBackground)
+})
+
+// 背景模糊层样式
+const blurBgStyle = computed(() => {
+ return getBlurBgStyle(element.value.commonBackground, scale.value)
+})
+
const componentBackgroundStyle = computed(() => {
if (element.value.commonBackground && element.value.component !== 'GroupArea') {
- const {
- backdropFilterEnable,
- backdropFilter,
- backgroundColorSelect,
- backgroundColor,
- backgroundImageEnable,
- backgroundType,
- outerImage,
- innerPadding,
- borderRadius
- } = element.value.commonBackground
- const commonBackground = element.value.commonBackground as CommonBackground
- const innerPaddingTarget = ['Group'].includes(element.value.component) ? 0 : innerPadding
- let innerPaddingStyle = innerPaddingTarget * scale.value + 'px'
- const paddingMode = commonBackground.innerPadding?.mode
- if (paddingMode === ShorthandMode.Uniform) {
- innerPaddingStyle = `${commonBackground.innerPadding?.top * scale.value}px`
- } else if (paddingMode === ShorthandMode.PerEdge) {
- innerPaddingStyle = `${commonBackground.innerPadding?.top * scale.value}px ${
- commonBackground.innerPadding?.right * scale.value
- }px ${commonBackground.innerPadding?.bottom * scale.value}px ${
- commonBackground.innerPadding?.left * scale.value
- }px`
- }
-
- let borderRadiusStyle = borderRadius + 'px'
- const borderRadiusMode = commonBackground.borderRadius?.mode
- if (borderRadiusMode === ShorthandMode.Uniform) {
- borderRadiusStyle = `${commonBackground.borderRadius?.topLeft * scale.value}px`
- } else if (borderRadiusMode === ShorthandMode.PerEdge) {
- borderRadiusStyle = `${commonBackground.borderRadius?.topLeft * scale.value}px ${
- commonBackground.borderRadius?.topRight * scale.value
- }px ${commonBackground.borderRadius?.bottomRight * scale.value}px ${
- commonBackground.borderRadius?.bottomLeft * scale.value
- }px`
- }
- let style = {
- padding: innerPaddingStyle,
- borderRadius: borderRadiusStyle
- }
- let colorRGBA = ''
- if (backgroundColorSelect && backgroundColor) {
- colorRGBA = backgroundColor
- }
- if (backgroundImageEnable) {
- if (backgroundType === 'outerImage' && typeof outerImage === 'string') {
- style['background'] = `url(${imgUrlTrans(outerImage)}) no-repeat ${colorRGBA}`
- } else {
- style['background-color'] = colorRGBA
- }
- } else {
- style['background-color'] = colorRGBA
- }
- if (element.value.component !== 'UserView') {
- style['overflow'] = 'hidden'
- }
- if (backdropFilterEnable) {
- style['backdrop-filter'] = 'blur(' + backdropFilter + 'px)'
- }
- return style
+ return getComponentBackgroundStyle(element.value.commonBackground, {
+ scale: scale.value,
+ isUserView: element.value.component === 'UserView',
+ forceNoPadding: ['Group'].includes(element.value.component)
+ })
}
return {}
})
@@ -1277,6 +1235,12 @@ onMounted(() => {
background-size: 100% 100% !important;
}
+.blur-bg {
+ width: 100%;
+ height: 100%;
+ background-size: 100% 100% !important;
+}
+
.shape-selected {
outline: 1px solid var(--ed-color-primary, #3370ff);
}
diff --git a/core/core-frontend/src/utils/backgroundStyleUtils.ts b/core/core-frontend/src/utils/backgroundStyleUtils.ts
new file mode 100644
index 0000000000..e54e84e886
--- /dev/null
+++ b/core/core-frontend/src/utils/backgroundStyleUtils.ts
@@ -0,0 +1,165 @@
+import { imgUrlTrans } from '@/utils/imgUtils'
+import type {
+ CommonBackground,
+ CornerValues,
+ EdgeValues
+} from '@/components/visualization/component-background/Types'
+
+/**
+ * 判断是否启用背景图模糊
+ * @param commonBackground 组件背景配置
+ * @returns 是否启用背景图模糊
+ */
+export function isBlurBgEnabled(commonBackground: CommonBackground | undefined): boolean {
+ if (!commonBackground) {
+ return false
+ }
+ const { backdropFilterEnable, backgroundImageEnable, backgroundType, outerImage } =
+ commonBackground
+ return (
+ backdropFilterEnable === true &&
+ backgroundImageEnable === true &&
+ backgroundType === 'outerImage' &&
+ typeof outerImage === 'string'
+ )
+}
+
+/**
+ * 获取边距样式值
+ * @param edgeValues 边距配置
+ * @param scale 缩放比例
+ * @returns CSS 边距样式值
+ */
+export function getEdgeValuesStyle(edgeValues: EdgeValues | number | undefined, scale = 1): string {
+ if (edgeValues === undefined) {
+ return '0px'
+ }
+ if (typeof edgeValues === 'number') {
+ return `${edgeValues * scale}px`
+ }
+ const mode = edgeValues.mode
+ const top = (edgeValues.top ?? 0) * scale
+ const right = (edgeValues.right ?? 0) * scale
+ const bottom = (edgeValues.bottom ?? 0) * scale
+ const left = (edgeValues.left ?? 0) * scale
+ if (mode === 'uniform') {
+ return `${top}px`
+ } else if (mode === 'per_edge') {
+ return `${top}px ${right}px ${bottom}px ${left}px`
+ }
+ return `${top}px`
+}
+
+/**
+ * 获取圆角样式值
+ * @param cornerValues 圆角配置
+ * @param scale 缩放比例
+ * @returns CSS 圆角样式值
+ */
+export function getCornerValuesStyle(
+ cornerValues: CornerValues | number | undefined,
+ scale = 1
+): string {
+ if (cornerValues === undefined) {
+ return '0px'
+ }
+ if (typeof cornerValues === 'number') {
+ return `${cornerValues * scale}px`
+ }
+ const mode = cornerValues.mode
+ const topLeft = (cornerValues.topLeft ?? 0) * scale
+ const topRight = (cornerValues.topRight ?? 0) * scale
+ const bottomLeft = (cornerValues.bottomLeft ?? 0) * scale
+ const bottomRight = (cornerValues.bottomRight ?? 0) * scale
+ if (mode === 'uniform') {
+ return `${topLeft}px`
+ } else if (mode === 'per_edge') {
+ return `${topLeft}px ${topRight}px ${bottomRight}px ${bottomLeft}px`
+ }
+ return `${topLeft}px`
+}
+
+/**
+ * 生成背景模糊层样式
+ * @param commonBackground 组件背景配置
+ * @param scale 缩放比例
+ * @returns CSS 样式对象
+ */
+export function getBlurBgStyle(
+ commonBackground: CommonBackground | undefined,
+ scale = 1
+): Record {
+ if (!isBlurBgEnabled(commonBackground)) {
+ return {}
+ }
+ const { outerImage, backdropFilter, borderRadius } = commonBackground
+ return {
+ position: 'absolute',
+ inset: '0',
+ background: `url(${imgUrlTrans(outerImage!)}) no-repeat center/cover`,
+ filter: `blur(${backdropFilter ?? 0}px)`,
+ borderRadius: getCornerValuesStyle(borderRadius, scale),
+ pointerEvents: 'none'
+ }
+}
+
+/**
+ * 生成组件背景样式
+ * @param commonBackground 组件背景配置
+ * @param options 配置选项
+ * @returns CSS 样式对象
+ */
+export function getComponentBackgroundStyle(
+ commonBackground: CommonBackground | undefined,
+ options: {
+ scale?: number
+ isUserView?: boolean
+ forceNoPadding?: boolean
+ } = {}
+): Record {
+ if (!commonBackground) {
+ return {}
+ }
+ const {
+ backdropFilterEnable,
+ backdropFilter,
+ backgroundColorSelect,
+ backgroundColor,
+ backgroundImageEnable,
+ backgroundType,
+ outerImage,
+ innerPadding,
+ borderRadius
+ } = commonBackground
+ const { scale = 1, isUserView = false, forceNoPadding = false } = options
+ const style: Record = {
+ padding: forceNoPadding ? '0px' : getEdgeValuesStyle(innerPadding, scale),
+ borderRadius: getCornerValuesStyle(borderRadius, scale)
+ }
+ // 背景色
+ let colorRGBA = ''
+ if (backgroundColorSelect && backgroundColor) {
+ colorRGBA = backgroundColor
+ }
+ // 背景图
+ const blurEnabled = isBlurBgEnabled(commonBackground)
+ if (backgroundImageEnable) {
+ if (blurEnabled) {
+ style['background-color'] = colorRGBA
+ } else if (backgroundType === 'outerImage' && typeof outerImage === 'string') {
+ style['background'] = `url(${imgUrlTrans(outerImage)}) no-repeat ${colorRGBA}`
+ } else {
+ style['background-color'] = colorRGBA
+ }
+ } else {
+ style['background-color'] = colorRGBA
+ }
+ // 溢出处理
+ if (!isUserView) {
+ style['overflow'] = 'hidden'
+ }
+ if (backdropFilterEnable && !blurEnabled) {
+ style['backdrop-filter'] = `blur(${backdropFilter ?? 0}px)`
+ }
+ return style
+}