Sfoglia il codice sorgente

fix: 调整背景图

jiaxing.liao 4 mesi fa
parent
commit
cbe217e6ce
28 ha cambiato i file con 145 aggiunte e 130 eliminazioni
  1. 30 5
      src/renderer/src/lvgl-widgets/ImageBg.vue
  2. 2 2
      src/renderer/src/lvgl-widgets/bar/Bar.vue
  3. 4 2
      src/renderer/src/lvgl-widgets/bar/index.ts
  4. 1 1
      src/renderer/src/lvgl-widgets/button-matrix/ButtonMatrix.vue
  5. 6 7
      src/renderer/src/lvgl-widgets/button-matrix/index.tsx
  6. 3 12
      src/renderer/src/lvgl-widgets/button/Button.vue
  7. 2 1
      src/renderer/src/lvgl-widgets/button/index.ts
  8. 2 2
      src/renderer/src/lvgl-widgets/button/style.json
  9. 2 1
      src/renderer/src/lvgl-widgets/container/index.ts
  10. 8 4
      src/renderer/src/lvgl-widgets/hooks/useWidgetStyle.ts
  11. 4 7
      src/renderer/src/lvgl-widgets/image-button/ImageButton.vue
  12. 2 2
      src/renderer/src/lvgl-widgets/image/Image.vue
  13. 3 13
      src/renderer/src/lvgl-widgets/label/Label.vue
  14. 2 1
      src/renderer/src/lvgl-widgets/label/index.ts
  15. 8 47
      src/renderer/src/lvgl-widgets/page/Page.vue
  16. 6 1
      src/renderer/src/lvgl-widgets/page/index.ts
  17. 3 3
      src/renderer/src/lvgl-widgets/slider/Slider.vue
  18. 6 3
      src/renderer/src/lvgl-widgets/slider/index.ts
  19. 2 1
      src/renderer/src/lvgl-widgets/span-group/index.tsx
  20. 1 1
      src/renderer/src/lvgl-widgets/switch/Switch.vue
  21. 4 2
      src/renderer/src/lvgl-widgets/switch/index.ts
  22. 3 1
      src/renderer/src/lvgl-widgets/type.d.ts
  23. 7 0
      src/renderer/src/lvgl-widgets/window/index.tsx
  24. 1 1
      src/renderer/src/model/index.ts
  25. 1 1
      src/renderer/src/types/resource.d.ts
  26. 27 3
      src/renderer/src/views/designer/config/property/components/StyleBackground.vue
  27. 2 3
      src/renderer/src/views/designer/config/property/components/StyleSpace.vue
  28. 3 3
      src/renderer/src/views/designer/sidebar/components/EditImageModal.vue

+ 30 - 5
src/renderer/src/lvgl-widgets/ImageBg.vue

@@ -1,15 +1,40 @@
 <template>
-  <div v-if="src" class="w-full h-full absolute left-0 top-0 z-0">
-    <img width="100%" height="100%" class="absolute z-0" :src="src" />
-    <div v-if="imageColorStyle" class="absolute w-full h-full z-1" :style="imageColorStyle"></div>
+  <div
+    ref="wrapperRef"
+    v-if="src"
+    class="w-full h-full absolute left-0 top-0 z-0 overflow-hidden flex items-center justify-center"
+    :style="{ opacity: imageStyle?.opacity }"
+  >
+    <img class="absolute z-0" :src="src" />
+    <img ref="imgRef" class="absolute z-1" :src="src" :style="shadowImageStyle" />
   </div>
 </template>
 
 <script setup lang="ts">
+import { ref, computed } from 'vue'
 import { CSSProperties } from 'vue'
+import { useElementSize } from '@vueuse/core'
 
-defineProps<{
+const props = defineProps<{
   src?: string
-  imageColorStyle?: CSSProperties
+  imageStyle?: CSSProperties
 }>()
+
+const wrapperRef = ref<HTMLDivElement>()
+const imgRef = ref<HTMLImageElement>()
+
+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
+  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`
+  }
+})
 </script>

+ 2 - 2
src/renderer/src/lvgl-widgets/bar/Bar.vue

@@ -2,7 +2,7 @@
   <div :style="styleMap?.mainStyle" class="box-border relative">
     <ImageBg
       :src="styleMap?.mainStyle?.imageSrc"
-      :image-color-style="styleMap?.mainStyle?.imageColorStyle"
+      :image-color-style="styleMap?.mainStyle?.imageStyle"
     />
     <div
       class="absolute left-0 h-full top-0"
@@ -10,7 +10,7 @@
     >
       <ImageBg
         :src="styleMap?.indicatorStyle?.imageSrc"
-        :image-color-style="styleMap?.indicatorStyle?.imageColorStyle"
+        :image-color-style="styleMap?.indicatorStyle?.imageStyle"
       />
     </div>
   </div>

+ 4 - 2
src/renderer/src/lvgl-widgets/bar/index.ts

@@ -51,7 +51,8 @@ export default {
           color: '#2092f53c',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {
@@ -74,7 +75,8 @@ export default {
           color: '#2092f5ff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {

+ 1 - 1
src/renderer/src/lvgl-widgets/button-matrix/ButtonMatrix.vue

@@ -1,5 +1,5 @@
 <template>
-  <div :style="styleMap?.mainStyle" class="box-border flex flex-col">
+  <div :style="styleMap?.mainStyle" class="box-border flex flex-col overflow-hidden">
     <div
       v-for="(row, index) in group || []"
       :key="index"

+ 6 - 7
src/renderer/src/lvgl-widgets/button-matrix/index.tsx

@@ -49,7 +49,8 @@ export default {
           color: '#ffffffff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {
@@ -222,12 +223,10 @@ export default {
                 {
                   label: '内边距',
                   field: 'padding',
-                  valueType: 'padding'
-                },
-                {
-                  label: '间距',
-                  field: 'spacer',
-                  valueType: 'spacer'
+                  valueType: 'padding',
+                  componentProps: {
+                    hasGap: true
+                  }
                 }
               ]
         }

+ 3 - 12
src/renderer/src/lvgl-widgets/button/Button.vue

@@ -2,19 +2,9 @@
   <div
     :style="styleMap?.mainStyle"
     style="display: flex; align-items: center; justify-content: center"
+    class="relative overflow-hidden"
   >
-    <img
-      v-if="styleMap?.mainStyle?.imageSrc"
-      width="100%"
-      height="100%"
-      class="absolute z-0"
-      :src="styleMap?.mainStyle.imageSrc"
-    />
-    <div
-      v-if="styleMap?.mainStyle?.imageSrc"
-      class="absolute w-full h-full z-1"
-      :style="styleMap?.mainStyle?.imageColorStyle"
-    ></div>
+    <ImageBg :src="styleMap?.mainStyle?.imageSrc" :imageStyle="styleMap?.mainStyle?.imageStyle" />
     <span class="z-2" v-html="innerText"></span>
   </div>
 </template>
@@ -23,6 +13,7 @@
 import { computed } from 'vue'
 import { symbols } from '@/constants'
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number

+ 2 - 1
src/renderer/src/lvgl-widgets/button/index.ts

@@ -41,7 +41,8 @@ export default {
           color: '#2195f6ff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         text: {

+ 2 - 2
src/renderer/src/lvgl-widgets/button/style.json

@@ -114,7 +114,7 @@
             "text": {
               "color": "#000000ff",
               "family": "xx",
-              "size": 16,
+              "size": 12,
               "weight": "normal",
               "align": "center"
             },
@@ -146,7 +146,7 @@
             "text": {
               "color": "#000000ff",
               "family": "xx",
-              "size": 16,
+              "size": 12,
               "weight": "normal",
               "align": "center"
             },

+ 2 - 1
src/renderer/src/lvgl-widgets/container/index.ts

@@ -41,7 +41,8 @@ export default {
           color: '#ffffffff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {

+ 8 - 4
src/renderer/src/lvgl-widgets/hooks/useWidgetStyle.ts

@@ -21,7 +21,7 @@ type StyleMap = Record<
   string,
   CSSProperties & {
     imageSrc?: string
-    imageColorStyle?: CSSProperties
+    imageStyle?: CSSProperties
     line?: { color: string; width: number; radius: boolean }
     curve?: { color: string; width: number; radius: boolean }
   }
@@ -89,7 +89,10 @@ export const getStyle = (key, value) => {
     }
     // 阴影样式
     case 'shadow': {
-      style.boxShadow = `${value?.x}px ${value?.y}px ${value?.width}px ${value?.spread}px ${value?.color}`
+      style.boxShadow =
+        value?.width > 0
+          ? `${value?.x}px ${value?.y}px ${value?.width}px ${value?.spread}px ${value?.color}`
+          : 'none'
       break
     }
     // 内边距样式
@@ -171,8 +174,9 @@ export const useWidgetStyle = (param: StyleParam) => {
             getImageByPath(basePath + imagePath).then((res) => {
               if (res?.base64) {
                 styleMap.value[`${partItem.name}Style`].imageSrc = res.base64
-                styleMap.value[`${partItem.name}Style`].imageColorStyle = {
-                  background: style?.[key]?.image?.color
+                styleMap.value[`${partItem.name}Style`].imageStyle = {
+                  backgroundColor: style?.[key]?.image?.color,
+                  opacity: (style?.[key]?.image?.alpha || 255) / 255
                 }
               }
             })

+ 4 - 7
src/renderer/src/lvgl-widgets/image-button/ImageButton.vue

@@ -1,12 +1,9 @@
 <template>
   <div :style="styleMap?.mainStyle" class="relative">
-    <img
-      width="100%"
-      height="100%"
-      class="absolute left-0 top-0 z-0"
-      :src="src || defaultImg"
-      alt="image btn"
-    />
+    <div class="w-full h-full absolute left-0 top-0 z-0 flex items-center justify-center">
+      <img :src="src || defaultImg" alt="image btn" />
+    </div>
+
     <div
       class="absolute left-0 top-0 z-0 w-full h-full flex items-center justify-center overflow-hidden z-1"
     >

+ 2 - 2
src/renderer/src/lvgl-widgets/image/Image.vue

@@ -1,6 +1,6 @@
 <template>
-  <div :style="boxStyle">
-    <img :style="imgStyle" width="100%" height="100%" :src="src || defaultImg" alt="img" />
+  <div :style="boxStyle" class="overflow-hidden flex items-center justify-center">
+    <img :style="imgStyle" :src="src || defaultImg" alt="img" />
   </div>
 </template>
 

+ 3 - 13
src/renderer/src/lvgl-widgets/label/Label.vue

@@ -1,18 +1,7 @@
 <template>
   <div :style="styleMap?.mainStyle" class="overflow-hidden break-all">
-    <img
-      v-if="styleMap?.mainStyle?.imageSrc"
-      width="100%"
-      height="100%"
-      class="absolute left-0 top-0 z-0"
-      :src="styleMap?.mainStyle?.imageSrc"
-    />
-    <div
-      v-if="styleMap?.mainStyle?.imageSrc"
-      class="absolute left-0 top-0 w-full h-full z-1"
-      :style="styleMap?.mainStyle?.imageColorStyle"
-    ></div>
-    <div class="z-2 w-full h-full" v-html="innerText"></div>
+    <ImageBg :src="styleMap?.mainStyle?.imageSrc" :imageStyle="styleMap?.mainStyle?.imageStyle" />
+    <div class="z-2 w-full h-full absolute left-0 right-0" v-html="innerText"></div>
   </div>
 </template>
 
@@ -20,6 +9,7 @@
 import { computed } from 'vue'
 import { symbols } from '@/constants'
 import { useWidgetStyle } from '../hooks/useWidgetStyle'
+import ImageBg from '../ImageBg.vue'
 
 const props = defineProps<{
   width: number

+ 2 - 1
src/renderer/src/lvgl-widgets/label/index.ts

@@ -41,7 +41,8 @@ export default {
           color: '#2195f600',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         text: {

+ 8 - 47
src/renderer/src/lvgl-widgets/page/Page.vue

@@ -1,63 +1,24 @@
 <template>
-  <div class="relative" :style="getProps.rootStyle">
-    <img
-      v-if="bgImage"
-      width="100%"
-      height="100%"
-      class="absolute z-0"
-      :src="bgImage"
-      alt="bg image"
-    />
-    <div v-if="bgImage" class="z-1 absolute w-full h-full" :style="getProps.imageColor"></div>
+  <div class="relative box-border overflow-hidden" :style="styleMap?.mainStyle">
+    <ImageBg :src="styleMap?.mainStyle?.imageSrc" :imageStyle="styleMap?.mainStyle?.imageStyle" />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, computed, type CSSProperties } from 'vue'
-import { getImageByPath } from '@/utils'
-import { useProjectStore } from '@/store/modules/project'
+import ImageBg from '../ImageBg.vue'
+import { useWidgetStyle } from '../hooks/useWidgetStyle'
 
 const props = defineProps<{
   width?: number
   height?: number
   styles: any
   state?: string
+  part?: string
 }>()
 
-const projectStore = useProjectStore()
-
-const bgImage = ref('')
-
-const getProps = computed(() => {
-  const styles = props.styles
-  let stateStyles = styles[0]
-
-  const imageId = stateStyles?.background?.image?.imgId
-  if (imageId && projectStore.project) {
-    // 加载图片
-    const basePath = projectStore.project.meta.path
-    const imagePath = projectStore.project.resources.images.find(
-      (item) => item.id === imageId
-    )?.path
-    getImageByPath(basePath + imagePath).then((res) => {
-      bgImage.value = res?.base64 || ''
-    })
-  } else {
-    bgImage.value = ''
-  }
-
-  return {
-    rootStyle: {
-      width: `${props.width}px`,
-      height: `${props.height}px`,
-      boxSizing: 'border-box',
-
-      backgroundColor: stateStyles?.background.color
-    } as CSSProperties,
-    imageColor: {
-      background: stateStyles?.background?.image?.color
-    } as CSSProperties
-  }
+const styleMap = useWidgetStyle({
+  widget: 'page',
+  props
 })
 </script>
 <

+ 6 - 1
src/renderer/src/lvgl-widgets/page/index.ts

@@ -28,7 +28,12 @@ export default {
           state: 'default'
         },
         background: {
-          color: '#ffffffff'
+          color: '#ffffffff',
+          image: {
+            imgId: '',
+            color: '',
+            alpha: 255
+          }
         }
       }
     ]

+ 3 - 3
src/renderer/src/lvgl-widgets/slider/Slider.vue

@@ -2,7 +2,7 @@
   <div :style="styleMap?.mainStyle" class="box-border relative">
     <ImageBg
       :src="styleMap?.mainStyle?.imageSrc"
-      :image-color-style="styleMap?.mainStyle?.imageColorStyle"
+      :image-color-style="styleMap?.mainStyle?.imageStyle"
     />
     <div
       class="absolute left-0 h-full top-0"
@@ -10,7 +10,7 @@
     >
       <ImageBg
         :src="styleMap?.indicatorStyle?.imageSrc"
-        :image-color-style="styleMap?.indicatorStyle?.imageColorStyle"
+        :image-color-style="styleMap?.indicatorStyle?.imageStyle"
       />
       <div
         :style="styleMap?.knobStyle"
@@ -19,7 +19,7 @@
       >
         <ImageBg
           :src="styleMap?.knobStyle?.imageSrc"
-          :image-color-style="styleMap?.knobStyle?.imageColorStyle"
+          :image-color-style="styleMap?.knobStyle?.imageStyle"
         />
       </div>
     </div>

+ 6 - 3
src/renderer/src/lvgl-widgets/slider/index.ts

@@ -53,7 +53,8 @@ export default {
           color: '#2092f53c',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {
@@ -80,7 +81,8 @@ export default {
           color: '#2092f5ff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {
@@ -96,7 +98,8 @@ export default {
           color: '#2092f5ff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {

+ 2 - 1
src/renderer/src/lvgl-widgets/span-group/index.tsx

@@ -50,7 +50,8 @@ export default {
           color: '#2092f500',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {

+ 1 - 1
src/renderer/src/lvgl-widgets/switch/Switch.vue

@@ -10,7 +10,7 @@
     <div
       v-if="getStyle?.imageSrc"
       class="absolute w-full h-full z-1"
-      :style="getStyle?.imageColorStyle"
+      :style="getStyle?.imageStyle"
     ></div>
     <div
       class="w-full h-full p-4px flex box-border"

+ 4 - 2
src/renderer/src/lvgl-widgets/switch/index.ts

@@ -47,7 +47,8 @@ export default {
           color: '#e6e6e6ff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {
@@ -73,7 +74,8 @@ export default {
           color: '#2092f5ff',
           image: {
             imgId: '',
-            color: ''
+            color: '',
+            alpha: 255
           }
         },
         border: {

+ 3 - 1
src/renderer/src/lvgl-widgets/type.d.ts

@@ -160,8 +160,10 @@ export interface IStyleConfig {
     image?: {
       // 图片源ID
       imgId: string
-      // 图片颜色 带透明度
+      // 图片颜色
       color: string
+      // 图片透明度
+      alpha: number
     }
   }
   // 文字样式

+ 7 - 0
src/renderer/src/lvgl-widgets/window/index.tsx

@@ -75,6 +75,13 @@ export default {
           width: 0,
           radius: 0,
           side: ['all']
+        },
+        shadow: {
+          color: '#2092f5ff',
+          x: 0,
+          y: 0,
+          spread: 0,
+          width: 0
         }
       },
       {

+ 1 - 1
src/renderer/src/model/index.ts

@@ -103,7 +103,7 @@ export const createFileResource = (path: string, type: 'image' | 'font' | 'other
         compressFormat: 'none',
         colorFormat: 'RGB565A8',
         // alphaColor: '#FFFFFF00',
-        alpha: 255,
+        // alpha: 255,
         bin: '',
         ditheringAlgorithm: 'None',
         storageMode: 'BIN'

+ 1 - 1
src/renderer/src/types/resource.d.ts

@@ -13,7 +13,7 @@ export type ImageResource = {
   // 颜色格式
   colorFormat: string
   // 透明度 0-255
-  alpha: number
+  // alpha: number
   // 颜色
   // alphaColor: string
   // 绑定BinId

+ 27 - 3
src/renderer/src/views/designer/config/property/components/StyleBackground.vue

@@ -13,7 +13,7 @@
     <el-form-item v-if="!onlyColor" label="背景图片" label-position="left" label-width="60px">
       <ImageSelect v-model="image" />
     </el-form-item>
-    <el-form-item v-if="!onlyColor" label="图片颜色" label-position="left" label-width="60px">
+    <el-form-item v-if="!onlyColor" label="图片遮罩" label-position="left" label-width="60px">
       <ColorPicker
         use-type="pure"
         picker-type="chrome"
@@ -23,6 +23,14 @@
       />
       <span class="text-text-active">{{ imageColor }}</span>
     </el-form-item>
+    <el-form-item v-if="!onlyColor" label="透明度" label-position="left" label-width="60px">
+      <el-slider
+        v-model="imageAlpha"
+        :disabled="!modelValue?.image"
+        :max="255"
+        :min="0"
+      ></el-slider>
+    </el-form-item>
   </div>
 </template>
 
@@ -43,6 +51,7 @@ const modelValue = defineModel<{
   image?: {
     imgId: string
     color: string
+    alpha: number
   }
 }>('modelValue')
 // 纯色
@@ -73,7 +82,7 @@ const gradientColor = computed({
 // 图像颜色
 const imageColor = computed({
   get() {
-    return modelValue.value?.image?.color
+    return modelValue.value?.image?.color || '#ffffff00'
   },
   set(val: string) {
     if (modelValue.value?.image) {
@@ -81,6 +90,17 @@ const imageColor = computed({
     }
   }
 })
+// 图像透明度
+const imageAlpha = computed({
+  get() {
+    return modelValue.value?.image?.alpha
+  },
+  set(val: number) {
+    if (modelValue.value?.image) {
+      modelValue.value.image.alpha = val
+    }
+  }
+})
 
 const image = computed({
   get() {
@@ -91,10 +111,14 @@ const image = computed({
       if (!modelValue.value?.image) {
         modelValue.value.image = {
           imgId: '',
-          color: ''
+          color: '',
+          alpha: 255
         }
       }
       modelValue.value.image.imgId = val
+      if (!imageColor.value) {
+        imageColor.value = '#ffffff00'
+      }
     }
   }
 })

+ 2 - 3
src/renderer/src/views/designer/config/property/components/StyleSpace.vue

@@ -1,6 +1,6 @@
 <template>
   <div>
-    <el-form-item v-if="!hideLetterSpacing" label="行间距" label-position="left" label-width="60px">
+    <el-form-item v-if="!hideLetterSpacing" label="行" label-position="left" label-width="60px">
       <el-input-number
         v-model="lineHeight"
         controls-position="right"
@@ -9,7 +9,7 @@
         :max="100"
       />
     </el-form-item>
-    <el-form-item label="字间距" label-position="left" label-width="60px">
+    <el-form-item label="字" label-position="left" label-width="60px">
       <el-input-number
         v-model="letterSpacing"
         controls-position="right"
@@ -48,7 +48,6 @@ const lineHeight = computed({
   get: () => modelValue.value?.lineHeight,
   set: (val: number) => {
     if (modelValue.value) {
-      
       modelValue.value.lineHeight = val
     }
   }

+ 3 - 3
src/renderer/src/views/designer/sidebar/components/EditImageModal.vue

@@ -80,10 +80,10 @@
             <span class="ml-8px">{{ formData.alphaColor }}</span>
           </el-form-item></el-col
         > -->
-        <el-col :span="12">
+        <!-- <el-col :span="12">
           <el-form-item label="透明度" prop="alpha">
             <el-slider v-model="formData.alpha" :max="255" :min="0"></el-slider> </el-form-item
-        ></el-col>
+        ></el-col> -->
         <el-col :span="12">
           <el-form-item label="存储方式" prop="storageMode">
             <el-select v-model="formData.storageMode">
@@ -180,7 +180,7 @@ const formData = ref<ImageResource>({
   path: '',
   compressFormat: 'none',
   colorFormat: '',
-  alpha: 255,
+  // alpha: 255,
   bin: '',
   // alphaColor: '#FFFFFF00',
   ditheringAlgorithm: 'None',