Преглед изворни кода

fix: 修改覆盖色实现

jiaxing.liao пре 5 дана
родитељ
комит
ffdb4f9212
1 измењених фајлова са 34 додато и 21 уклоњено
  1. 34 21
      src/renderer/src/lvgl-widgets/ImageBg.vue

+ 34 - 21
src/renderer/src/lvgl-widgets/ImageBg.vue

@@ -1,25 +1,17 @@
 <template>
   <div
-    ref="wrapperRef"
     v-if="getImgSrc"
     class="w-full h-full absolute left-0 top-0 z-0 overflow-hidden flex items-center justify-center"
     :style="{ opacity: imageStyle?.opacity }"
     v-bind="$attrs"
   >
-    <img v-bind="imageProps" class="absolute z-0" :src="getImgSrc" />
-    <img
-      v-bind="imageProps"
-      ref="imgRef"
-      class="absolute z-1"
-      :src="getImgSrc"
-      :style="shadowImageStyle"
-    />
+    <img v-bind="imageProps" ref="imgRef" class="absolute z-0" :src="getImgSrc" />
+    <div v-if="hasCoverColor" class="absolute z-1 pointer-events-none" :style="maskStyle"></div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, computed, ImgHTMLAttributes } from 'vue'
-import { CSSProperties } from 'vue'
+import { ref, computed, type CSSProperties, type ImgHTMLAttributes } from 'vue'
 import { useElementSize } from '@vueuse/core'
 import { useProjectStore } from '@/store/modules/project'
 
@@ -34,23 +26,44 @@ defineOptions({
   inheritAttrs: false
 })
 
-const wrapperRef = ref<HTMLDivElement>()
 const imgRef = ref<HTMLImageElement>()
 const projectStore = useProjectStore()
 
-const wrapperSize = useElementSize(wrapperRef)
 const imgSize = useElementSize(imgRef)
 
 // 图片覆盖色样式
-const shadowImageStyle = computed((): CSSProperties => {
-  const color = props.imageStyle?.backgroundColor
-  const offsetX = wrapperSize.width.value / 2 + imgSize.width.value / 2
+const getCssSize = (value: unknown, fallback: number) => {
+  if (value === undefined || value === null || value === '') {
+    return fallback ? `${fallback}px` : undefined
+  }
+  return typeof value === 'number' ? `${value}px` : String(value)
+}
+
+const getStyleObject = (style: unknown): CSSProperties => {
+  return style && typeof style === 'object' && !Array.isArray(style) ? (style as CSSProperties) : {}
+}
+
+const getCssUrl = (url: string) => `url("${url.replace(/"/g, '\\"')}")`
+
+const hasCoverColor = computed(() => !!props.imageStyle?.backgroundColor)
+
+const maskStyle = computed((): CSSProperties => {
+  const imageUrl = getCssUrl(getImgSrc.value || '')
+  const imagePropStyle = getStyleObject(props.imageProps?.style)
+
   return {
-    height: 'inherit',
-    maxWidth: `${wrapperSize.width.value}px`,
-    maxHeight: `${wrapperSize.height.value}px`,
-    filter: `drop-shadow(${offsetX}px 0px 0 ${color || 'transparent'})`,
-    left: `-${imgSize.width.value}px`
+    ...imagePropStyle,
+    width: getCssSize(props.imageProps?.width, imgSize.width.value),
+    height: getCssSize(props.imageProps?.height, imgSize.height.value),
+    backgroundColor: props.imageStyle?.backgroundColor,
+    maskImage: imageUrl,
+    WebkitMaskImage: imageUrl,
+    maskSize: '100% 100%',
+    WebkitMaskSize: '100% 100%',
+    maskPosition: 'center',
+    WebkitMaskPosition: 'center',
+    maskRepeat: 'no-repeat',
+    WebkitMaskRepeat: 'no-repeat'
   }
 })