Explorar o código

模式,透明度,图库,布局

qianduan hai 9 meses
pai
achega
9ad5355014

BIN=BIN
src/assets/iconData/underpainting.png


+ 6 - 2
src/components/maskedbox/digitalSlider.vue

@@ -17,6 +17,10 @@ const props = defineProps({
         type: Number,
         default: 200
     },
+    step: {
+        type: Number,
+        default: 1
+    }
 })
 const lineNum: any = ref()
 
@@ -37,11 +41,11 @@ function numberChange(params: any) {
     <div class="same_row_in upAndDown_padding">
         <span class="title_12 w_60 default_size" style="flex: none;">{{ title }}</span>
         <div class="grey_input_bgc w_60_index">
-            <el-input-number class="card_number" v-model="lineNum" :min="min" :max="max" size="small"
+            <el-input-number class="card_number" v-model="lineNum" :min="min" :max="max" :step="step" size="small"
                 controls-position="right" @input="numberChange" />
         </div>
         <div class="card_slider" style="width: 100%;">
-            <el-slider v-model="lineNum" :min="min" :max="max" size="small" @input="numberChange" />
+            <el-slider v-model="lineNum" :min="min" :max="max" :step="step" size="small" @input="numberChange" />
         </div>
     </div>
 </template>

+ 219 - 6
src/components/maskedbox/layout.vue

@@ -11,13 +11,35 @@
       <div class="center_in_column">
         <div class="dpjis">
           <!-- 上 -->
-          <div class="jAgYAh"></div>
+          <el-tooltip content="固定顶部" placement="left" effect="light" v-if="topFlag">
+            <div class="jAgYAh" @click="reversal('top')"></div>
+          </el-tooltip>
+          <div class="cPsGLK" v-else>
+            <input class="bcwrvZ_input" ref="inputRef" v-model="topNumber" type="number" @blur="handleBlur"
+              v-if="topInput">
+            <p class="bcwrvZ" @dblclick="handleDoubleClick" v-else>35</p>
+          </div>
           <!-- 右 -->
-          <div class="bTzFoR"></div>
+          <el-tooltip content="固定右侧" placement="left" effect="light" v-if="rightFlag">
+            <div class="bTzFoR" @click="reversal('right')"></div>
+          </el-tooltip>
+          <div class="gjYPCM" v-else>
+            <p class="cMizyy">35</p>
+          </div>
           <!-- 下 -->
-          <div class="eIwCFM"></div>
+          <el-tooltip content="固定底部" placement="left" effect="light" v-if="bottomFlag">
+            <div class="eIwCFM" @click="reversal('bottom')"></div>
+          </el-tooltip>
+          <div class="YoRMb" v-else>
+            <p class="gboeoP">35</p>
+          </div>
           <!-- 左 -->
-          <div class="fVBVzi"></div>
+          <el-tooltip content="固定左侧" placement="left" effect="light" v-if="leftFlag">
+            <div class="fVBVzi" @click="reversal('left')"></div>
+          </el-tooltip>
+          <div class="ljHwKA" v-else>
+            <p class="eEegxJ">35</p>
+          </div>
           <!-- 视图盒子 -->
           <div class="box_view"></div>
         </div>
@@ -41,23 +63,77 @@
 <script setup lang="ts">
 import { ref } from "vue";
 
+// 固定宽度
 const fixedWidth = ref(true)
+// 固定高度
 const fixedHeight = ref(true)
-
+// 固定顶部
+const topFlag = ref(false)
+const topInput = ref(false)
+const topNumber: any = ref(22)
+// 固定右侧
+const rightFlag = ref(true)
+const rightInput = ref(false)
+// 固定底部
+const bottomFlag = ref(true)
+const bottomFInput = ref(false)
+// 固定左侧
+const leftFlag = ref(false)
+const leftInput = ref(false)
+
+const inputRef = ref<HTMLInputElement | null>(null);
+// 双击输入框获取焦点
+function handleDoubleClick() {
+  topInput.value = true
+  setTimeout(() => {
+    if (inputRef.value) {
+      inputRef.value.focus();
+    }
+  })
+}
+// 失去焦点
+function handleBlur() {
+  topInput.value = false
+}
 // 固定宽度
 function getFixedWidth() {
   if (fixedWidth.value) {
     fixedWidth.value = false
+    rightFlag.value = false
+    leftFlag.value = false
   } else {
     fixedWidth.value = true
+    rightFlag.value = true
+    leftFlag.value = false
   }
 }
 // 固定高度
 function getFixedHeight() {
   if (fixedHeight.value) {
     fixedHeight.value = false
+    topFlag.value = false
+    bottomFlag.value = false
   } else {
     fixedHeight.value = true
+    topFlag.value = false
+    bottomFlag.value = true
+  }
+}
+//反转/切换
+function reversal(params: any) {
+  console.log(params, 665);
+  if (params == 'top') {
+    topFlag.value = false
+    bottomFlag.value = true
+  } else if (params == 'right') {
+    rightFlag.value = false
+    leftFlag.value = true
+  } else if (params == 'bottom') {
+    bottomFlag.value = false
+    topFlag.value = true
+  } else if (params == 'left') {
+    leftFlag.value = false
+    rightFlag.value = true
   }
 }
 </script>
@@ -111,6 +187,64 @@ function getFixedHeight() {
   }
 }
 
+.cPsGLK {
+  top: 0px;
+  left: 79px;
+  width: 2px;
+  height: 36px;
+  background: rgba(15, 116, 231, 0.3);
+  position: absolute;
+  cursor: pointer;
+}
+
+.bcwrvZ {
+  width: 39px;
+  height: 22px;
+  background: rgb(15, 115, 230);
+  border-radius: 11px;
+  position: absolute;
+  color: rgb(255, 255, 255);
+  display: flex;
+  -webkit-box-align: center;
+  align-items: center;
+  -webkit-box-pack: center;
+  justify-content: center;
+  top: 8px;
+  left: -19px;
+}
+
+.bcwrvZ_input {
+  border-radius: 11px;
+  width: 39px;
+  height: 22px;
+  position: absolute;
+  top: 8px;
+  left: -19px;
+  border: 1px solid rgb(15, 115, 230);
+  text-align: center;
+  color: rgb(15, 115, 230);
+}
+
+input[type="number"]::-webkit-inner-spin-button,
+input[type="number"]::-webkit-outer-spin-button {
+  -webkit-appearance: none;
+  margin: 0;
+}
+
+input[type="number"] {
+  -moz-appearance: textfield;
+  /* Firefox */
+}
+
+/* 可选:去除上下箭头 */
+input[type="number"] {
+  caret-color: rgb(15, 115, 230);
+}
+
+input[type="number"]:focus {
+  outline: none;
+}
+
 .bTzFoR {
   position: absolute;
   height: 35px;
@@ -138,6 +272,32 @@ function getFixedHeight() {
   }
 }
 
+.gjYPCM {
+  top: 50px;
+  right: 0px;
+  height: 2px;
+  width: 53px;
+  background: rgba(15, 116, 231, 0.3);
+  position: absolute;
+  cursor: pointer;
+}
+
+.cMizyy {
+  width: 39px;
+  height: 22px;
+  background: rgb(15, 115, 230);
+  border-radius: 11px;
+  position: absolute;
+  color: rgb(255, 255, 255);
+  display: flex;
+  -webkit-box-align: center;
+  align-items: center;
+  -webkit-box-pack: center;
+  justify-content: center;
+  top: -11px;
+  left: 6px;
+}
+
 .eIwCFM {
   position: absolute;
   height: 21px;
@@ -165,6 +325,32 @@ function getFixedHeight() {
   }
 }
 
+.YoRMb {
+  bottom: 0px;
+  right: 76px;
+  position: absolute;
+  height: 36px;
+  width: 2px;
+  background: rgba(15, 116, 231, 0.3);
+  cursor: pointer;
+}
+
+.gboeoP {
+  width: 39px;
+  height: 22px;
+  background: rgb(15, 115, 230);
+  border-radius: 11px;
+  position: absolute;
+  color: rgb(255, 255, 255);
+  display: flex;
+  -webkit-box-align: center;
+  align-items: center;
+  -webkit-box-pack: center;
+  justify-content: center;
+  top: 8px;
+  left: -19px;
+}
+
 .fVBVzi {
   position: absolute;
   height: 35px;
@@ -192,6 +378,32 @@ function getFixedHeight() {
   }
 }
 
+.ljHwKA {
+  top: 50px;
+  left: 0px;
+  height: 2px;
+  width: 53px;
+  background: rgba(15, 116, 231, 0.3);
+  position: absolute;
+  cursor: pointer;
+}
+
+.eEegxJ {
+  width: 39px;
+  height: 22px;
+  background: rgb(15, 115, 230);
+  border-radius: 11px;
+  position: absolute;
+  color: rgb(255, 255, 255);
+  display: flex;
+  -webkit-box-align: center;
+  align-items: center;
+  -webkit-box-pack: center;
+  justify-content: center;
+  top: -11px;
+  left: 7px;
+}
+
 .kdbebz {
   width: 100px;
   height: 100px;
@@ -330,4 +542,5 @@ function getFixedHeight() {
   margin-top: 8px;
   text-align: center;
   transform: scale(0.85);
-}</style>
+}
+</style>

+ 89 - 0
src/components/maskedbox/pattern.vue

@@ -0,0 +1,89 @@
+<template>
+    <div class="same_row_in upAndDown_padding">
+        <span class="title_12 w_60 default_size" style="flex: none;">模式</span>
+        <div class="card_alignment">
+            <div class="card_item_text" :class="item.flag ? 'activate_text' : ''" v-for="(item, index) in arrList"
+                :key="index" @click="selectAlignment(item.id)">
+                <span class="img_icon_text" :class="item.flag ? 'activate_text' : ''">{{ item.title }}</span>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from "vue";
+const props = defineProps({
+    mode: {
+        type: Number,
+        required: true
+    },
+})
+const arrList: any = ref([{
+    id: 'contain',
+    flag: false,
+    title: '适应',
+}, {
+    id: 'fill',
+    flag: false,
+    title: '拉伸',
+}])
+onMounted(() => {
+    selectAlignment(props.mode)
+})
+
+const emit = defineEmits(['update:mode']);
+function selectAlignment(mode: any) {
+    arrList.value.forEach(item => {
+        if (item.id == mode) {
+            item.flag = true
+        } else {
+            item.flag = false
+        }
+    })
+    emit('update:mode', mode);
+}
+</script>
+
+<style lang="scss" scoped>
+.card_alignment {
+    width: 100%;
+    background: rgb(243, 243, 248);
+    border-radius: 4px;
+    display: flex;
+    -webkit-box-pack: center;
+    justify-content: center;
+    padding: 2px;
+    height: 24px;
+}
+
+.card_item_text {
+    flex: 1 1 0%;
+    height: 100%;
+    text-align: center;
+    display: flex;
+    flex-direction: row;
+    -webkit-box-pack: center;
+    justify-content: center;
+    -webkit-box-align: center;
+    align-items: center;
+    cursor: pointer;
+}
+
+.activate_text {
+    color: rgb(15, 116, 231) !important;
+    background: rgb(255, 255, 255);
+    border-radius: 3px;
+    font-size: 12px;
+    cursor: pointer;
+}
+
+.img_icon_text {
+    color: rgb(171, 171, 180);
+    font-size: 12px;
+}
+
+.w_60_index {
+    width: 60px !important;
+    margin-right: 5px;
+}
+</style>

+ 130 - 0
src/components/maskedbox/photoGallery.vue

@@ -0,0 +1,130 @@
+<template>
+    <div class="space_between_in" style="margin-bottom: 14px;">
+        <div class="same_row_in">
+            <span class="title_gall" :class="galleryFlag ? 'blue_gall_title' : ''" @click="getSwitchGallery(1)">推荐</span>
+            <span class="title_gall" :class="!galleryFlag ? 'blue_gall_title' : ''" @click="getSwitchGallery(2)">我的图片</span>
+        </div>
+    </div>
+    <div class="card_photo" v-if="galleryFlag">
+        <div class="photo_row_col" v-for="(item, index) in listData" :key="index">
+            <div class="photo_img">
+                {{ item.title }}
+            </div>
+        </div>
+    </div>
+    <div class="card_photo" v-else>
+        <div class="photo_row_col" v-for="(item, index) in myPicture" :key="index">
+            <div class="photo_img">
+                {{ item.title }}
+            </div>
+        </div>
+        <div class="photo_row_col" v-if="myPicture.length == 0">
+            <el-tooltip class="box-item" effect="dark" content="大小要求: <= 512KB,格式要求:png" placement="bottom">
+                <div class="add_phone">
+                    <el-icon size="25">
+                        <Plus />
+                    </el-icon>
+                </div>
+            </el-tooltip>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from "vue";
+
+// 切换图库
+const galleryFlag = ref(true)
+const listData = [{
+    title: '1',
+}, {
+    title: '2',
+}, {
+    title: '3',
+}, {
+    title: '3',
+}, {
+    title: '3',
+}, {
+    title: '3',
+}, {
+    title: '3',
+}, {
+    title: '3',
+}]
+
+const myPicture: any = ref([])
+function getSwitchGallery(params: any) {
+    if (params == 1) {
+        galleryFlag.value = true
+    } else {
+        galleryFlag.value = false
+    }
+}
+</script>
+
+
+<style lang="scss" scoped>
+.title_gall {
+    cursor: pointer;
+    font-size: 13px;
+    font-weight: 500;
+    color: rgb(51, 51, 51);
+}
+
+.title_gall:nth-child(2) {
+    margin-left: 20px;
+}
+
+.blue_gall_title {
+    color: rgb(15, 115, 230);
+}
+
+.card_photo {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: wrap;
+}
+
+.photo_row_col {
+    padding: 0px 4px;
+    max-width: 25%;
+    flex: 0 0 25%;
+    margin-bottom: 9px;
+}
+
+.photo_img {
+    position: relative;
+    height: 111px;
+    box-sizing: border-box;
+    cursor: pointer;
+    display: flex;
+    -webkit-box-pack: center;
+    justify-content: center;
+    -webkit-box-align: center;
+    align-items: center;
+    border: 1px solid rgb(208, 208, 208);
+    background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAFVBMVEWjo6OCgoKfn5+GhoaBgYGbm5uJiYnd6F5WAAAATElEQVQI102MUQnAMBDFnoXACSh1MHoGnoVZmH8P49Yb9C8kEN1zzmetpSHpMnyQOLYBtwna/Mk0BKge9VIahkoTbmiTuJN9pv2IghflVgzV/Toi9QAAAABJRU5ErkJggg==);
+    background-repeat: repeat;
+    background-size: 10px 10px;
+}
+
+.photo_img:hover {
+    border: 1px solid rgb(15, 116, 231);
+}
+
+.add_phone {
+    position: relative;
+    height: 111px;
+    box-sizing: border-box;
+    cursor: pointer;
+    display: flex;
+    -webkit-box-pack: center;
+    justify-content: center;
+    -webkit-box-align: center;
+    align-items: center;
+    border: 1px solid rgb(208, 208, 208);
+    font-size: 14px;
+    background: rgb(250, 250, 250);
+}
+</style>

+ 48 - 4
src/components/widgets/Icon.vue

@@ -1,11 +1,55 @@
 <template>
-  <div style="width: 50px;font-size: 30px;">icon{{ input }}</div>
+  <div class="center_in"
+    :style="{ width: btndata.css.width + 'px', height: btndata.css.height + 'px', backgroundColor: btndata.css.backgroundColor, borderRadius: btndata.css.borderRadius + 'px', }">
+    <div class="icon_card_btn" :style="{ width: btndata.css.iconSize + 'px', height: btndata.css.iconSize + 'px', }">
+      <el-image class="images_icon"
+        :style="{ width: btndata.css.iconSize + 'px', height: btndata.css.iconSize + 'px', left: '-' + btndata.css.iconSize + 'px', filter: 'drop-shadow(' + btndata.css.iconSize + 'px 0 0 ' + btndata.css.iconColor + ')' }"
+        :src="getAssetsImages(btndata.config.img)" fit="contain" />
+    </div>
+  </div>
 </template>
 
 <script setup lang="ts">
+import { watch, ref } from "vue";
+const props = defineProps(["config"])
 
-import { ref } from "vue";
-const input = ref('')
+const btndata: any = ref({})
+function getAssetsImages(name) {
+  var arr = '../../assets/iconData/' + name + '.png'
+  return new URL(`${arr}`, import.meta.url).href;
+}
+
+watch(() => props.config, (newValue) => {
+  if (newValue) {
+    btndata.value = newValue
+  }
+}, { immediate: true, deep: true })
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.card_btn {
+  flex-direction: column;
+  background-color: #fff;
+  border-radius: 8px;
+  overflow: hidden;
+}
+
+.bg_item_btn {
+  width: 60px;
+  height: 60px;
+  border-radius: 50%;
+  background-color: rgba(21, 140, 251, 0.1);
+}
+
+.icon_card_btn {
+  overflow: hidden;
+  position: relative;
+}
+
+.images_icon {
+  position: relative;
+  // left: -30px;
+  // -webkit-filter: drop-shadow(30px 0 0 rgba(21, 140, 251, 1));
+  // filter: drop-shadow(30px 0 0 rgba(21, 140, 251, 1));
+}
+</style>

+ 40 - 4
src/components/widgets/Picture.vue

@@ -1,11 +1,47 @@
 <template>
-  <div style="width: 50px;font-size: 30px;">pictre{{ input }}</div>
+  <div :class="btndata.config.picture ? '' : 'card_title_picture'"
+    :style="{ width: btndata.css.width + 'px', height: btndata.css.height + 'px', borderRadius: btndata.css.borderRadius + 'px', opacity: btndata.css.opacity }">
+    <el-image style="width: 100%;height: 100%;" :fit="btndata.config.pictureMode"
+      :src="getAssetsImages(btndata.config.picture)" v-if="btndata.config.picture">
+    </el-image>
+    <div class="card_icon_outline" v-if="!btndata.config.picture">
+      <el-icon color="rgb(183 213 247)"><PictureFilled /></el-icon>
+    </div>
+  </div>
 </template>
 
 <script setup lang="ts">
+import { watch, ref } from "vue";
+const props = defineProps(["config"])
 
-import { ref } from "vue";
-const input = ref('')
+const btndata: any = ref({})
+function getAssetsImages(name) {
+  var arr = '../../assets/iconData/' + name + '.png'
+  return new URL(`${arr}`, import.meta.url).href;
+}
+
+watch(() => props.config, (newValue) => {
+  if (newValue) {
+    btndata.value = newValue
+  }
+}, { immediate: true, deep: true })
 </script>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+.card_title_picture {
+  position: relative;
+  background-color: rgba(158, 219, 255, .4);
+}
+
+.card_icon_outline {
+  position: absolute;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  top: 0;
+  left: 0;
+  bottom: 0;
+  right: 0;
+  font-size: 40px;
+}
+</style>

+ 20 - 0
src/module/config/icon.ts

@@ -0,0 +1,20 @@
+const iconConfig = {
+    isActive: false,
+    img: 'set',
+    isResizable: true, //禁止缩放
+    aspectRatio: false, //禁止等比例缩放
+    resizable: true, //禁止调整大小
+}
+
+const iconCss = {
+    top: 0,
+    left: 0,
+    width: 50,
+    height: 50,
+    borderRadius: 30,
+    iconSize: 27,
+    iconColor: "rgba(255, 255, 255, 1)",
+    backgroundColor: 'rgba(21, 140, 251, 1)',
+}
+
+export { iconConfig, iconCss }

+ 19 - 0
src/module/config/picture.ts

@@ -0,0 +1,19 @@
+const pictureConfig = {
+    isActive: false,
+    isResizable: true, //禁止缩放
+    aspectRatio: false, //禁止等比例缩放
+    resizable: true, //禁止调整大小
+    pictureMode: 'contain',//适应contain,fill拉伸
+    picture: '',
+}
+
+const pictureCss = {
+    top: 0,
+    left: 0,
+    width: 260,
+    height: 170,
+    borderRadius: 15,
+    opacity: 1,
+}
+
+export { pictureConfig, pictureCss }

+ 6 - 4
src/module/index.ts

@@ -2,6 +2,8 @@
 import { TextConfig, TextCss } from "./config/text";
 import { switchConfig, switchCss } from "./config/switch";
 import { btnConfig, btnCss } from "./config/button";
+import { iconConfig, iconCss } from "./config/icon";
+import { pictureConfig, pictureCss } from "./config/picture";
 import { sceneConfig, sceneCss } from "./config/sceneButton";
 import { configList1, cssList1 } from "./config/input";
 
@@ -23,13 +25,13 @@ const baseComponent = [{
 }, {
     id: 8, type: 'Icon', name: "图标", active: false,
     displayPicture: true,
-    config: btnConfig,
-    css: btnCss,
+    config: iconConfig,
+    css: iconCss,
 }, {
     id: 9, type: 'Picture', name: "图片", active: false,
     displayPicture: true,
-    config: sceneConfig,
-    css: sceneCss,
+    config: pictureConfig,
+    css: pictureCss,
 }]
 
 const attributeValue = [{

+ 0 - 1
src/views/HomeView.vue

@@ -103,7 +103,6 @@
         <!-- 样式编辑控件 -->
         <div class="card_maskedbox" v-if="currentMove.soleId">
           <maskedbox :config="currentMove" @childEvent="childEvent"></maskedbox>
-          {{ currentMove }}
         </div>
         <div class="tabs_radio center_in" v-else>
           <el-empty description="暂无样式可调" :image-size="130" />

+ 24 - 8
src/views/maskedbox.vue

@@ -10,6 +10,7 @@
         </div>
         <div v-if="basicFlag" class="card_second_level">
             <digitalSlider v-if="config.config.size" v-model:num="config.config.size" title="层级"></digitalSlider>
+            <patternMode v-model:mode="config.config.pictureMode"></patternMode>
             <literalName v-if="'name' in config.config" v-model:name="config.config.name"></literalName>
             <boxSize v-if="config.css.width && config.css.height != 'auto' && config.css.height && config.config.resizable"
                 v-model:width="config.css.width" v-model:height="config.css.height"></boxSize>
@@ -22,6 +23,11 @@
                 v-model:fontWeight="config.css.fontWeight"></fontSize>
             <textAlignment v-if="config.css.textAlign" v-model:align="config.css.textAlign"></textAlignment>
             <lineNumber v-if="'lineNum' in config.config" v-model:num="config.config.lineNum"></lineNumber>
+            <digitalSlider v-if="'borderRadius' in config.css" v-model:num="config.css.borderRadius" title="圆角">
+            </digitalSlider>
+            <digitalSlider v-if="'opacity' in config.css" v-model:num="config.css.opacity" :min="0" :max="1" :step="0.1"
+                title="透明度">
+            </digitalSlider>
             <digitalSlider v-if="'textWidth' in config.css" v-model:num="config.css.textWidth" title="宽度"></digitalSlider>
         </div>
     </div>
@@ -33,12 +39,14 @@
             </el-icon>
         </div>
         <div v-if="imgFlag" class="card_second_level">
-            <fontSize v-model:fontSize="config.css.fontSize" v-model:fontWeight="config.css.fontWeight"></fontSize>
-            <iconSize v-model:num="config.config.size" v-model:iconName="config.config.img" @mousedown.stop
-                @childEvent="childEvent"></iconSize>
-            <colorSelection v-model:iconColor="config.css.iconColor" title="选择颜色"></colorSelection>
-            <textAlignment v-model:align="config.css.textAlign"></textAlignment>
-            <lineNumber v-model:num="config.config.lineNum"></lineNumber>
+            <fontSize v-if="'fontSize' in config.css && 'fontWeight' in config.css" v-model:fontSize="config.css.fontSize"
+                v-model:fontWeight="config.css.fontWeight"></fontSize>
+            <iconSize v-if="'iconSize' in config.css && 'img' in config.config" v-model:num="config.css.iconSize"
+                v-model:iconName="config.config.img" @mousedown.stop @childEvent="childEvent"></iconSize>
+            <colorSelection v-if="'iconColor' in config.css" v-model:iconColor="config.css.iconColor" title="选择颜色">
+            </colorSelection>
+            <textAlignment v-if="'textAlign' in config.css" v-model:align="config.css.textAlign"></textAlignment>
+            <lineNumber v-if="'lineNum' in config.config" v-model:num="config.config.lineNum"></lineNumber>
         </div>
     </div>
     <div class="box_padding" v-if="'backgroundColor' in config.css && 'borderRadius' in config.css">
@@ -56,12 +64,21 @@
             </colorSelection>
         </div>
     </div>
+    <div class="box_padding" v-if="'picture' in config.config">
+        <div class="same_row_in">
+            <span class="default_size title_5">图库</span>
+        </div>
+        <div style="padding: 18px 0px 13px;">
+            <photoGallery></photoGallery>
+        </div>
+    </div>
 </template>
 
 <script setup lang="ts">
 import { ref, watch } from "vue";
 import color from 'color';
 import layout from '../components/maskedbox/layout.vue';
+import patternMode from '../components/maskedbox/pattern.vue';
 import literalName from '../components/maskedbox/literalName.vue';
 import boxSize from '../components/maskedbox/boxSize.vue';
 import fontSize from '../components/maskedbox/fontSize.vue';
@@ -70,6 +87,7 @@ import colorSelection from '../components/maskedbox/colorSelection.vue';
 import textAlignment from '../components/maskedbox/textAlignment.vue';
 import lineNumber from '../components/maskedbox/lineNumber.vue';
 import digitalSlider from '../components/maskedbox/digitalSlider.vue';
+import photoGallery from '../components/maskedbox/photoGallery.vue';
 
 const props = defineProps({
     config: {
@@ -81,7 +99,6 @@ const props = defineProps({
 const basicFlag = ref(true)
 const imgFlag = ref(true)
 const backgroundFlag = ref(true)
-
 function getbasicSetting(params: any) {
     if (params == 'basic') {
         if (basicFlag.value) {
@@ -125,7 +142,6 @@ const emit = defineEmits(['childEvent', 'updateValue'])
 function childEvent() {
     emit('childEvent');
 }
-
 watch(() => props.config, (newValue) => {
     if (newValue.css) {
         // 初始化hex颜色