Sfoglia il codice sorgente

feat(CanvasTool): add font scale control for interactive iframe tools

新增工具iframe字号缩放功能,支持1~24倍缩放,每单位对应1px字号调整,初始为16px,添加了增减按钮和当前缩放值展示,限制了缩放边界并处理了异常情况
lsc 16 ore fa
parent
commit
05cf10c8c9
1 ha cambiato i file con 73 aggiunte e 0 eliminazioni
  1. 73 0
      src/views/Editor/CanvasTool/index2.vue

+ 73 - 0
src/views/Editor/CanvasTool/index2.vue

@@ -70,6 +70,23 @@
           </svg>
         </div>
       </Popover>
+      <!-- 工具iframe字号缩放:比例1~24,每±1对应字号±1px,初始16px -->
+      <div class="handler-item font-scale-ctrl" v-if="hasInteractiveTool">
+        <span class="scale-btn" :class="{ disable: fontScale <= MIN_FONT_SCALE }" @click="changeFontScale(-1)">
+          <svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
+            stroke-linecap="round">
+            <line x1="5" y1="12" x2="19" y2="12" />
+          </svg>
+        </span>
+        <span class="scale-value">{{ fontScale }}</span>
+        <span class="scale-btn" :class="{ disable: fontScale >= MAX_FONT_SCALE }" @click="changeFontScale(1)">
+          <svg width="1em" height="1em" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
+            stroke-linecap="round">
+            <line x1="12" y1="5" x2="12" y2="19" />
+            <line x1="5" y1="12" x2="19" y2="12" />
+          </svg>
+        </span>
+      </div>
       <Popover trigger="click" v-model:value="textTypeSelectVisible"
         style="height: 100%;display: flex;align-items: center;" :offset="10" v-if="!isFrame">
         <template #content>
@@ -341,6 +358,32 @@ const hasInteractiveTool = computed(() => {
   return elements.some((el: any) => el.type === 'frame' && toolTypeArray.value.includes(el.toolType))
 })
 
+// 工具iframe字号缩放:比例最小1最大24,每±1对应字号±1px,初始16px
+const MIN_FONT_SCALE = 1
+const MAX_FONT_SCALE = 24
+const BASE_FONT_SIZE = 16
+const fontScale = ref(1)
+
+const setToolIframeFontSize = () => {
+  try {
+    const iframe = document.getElementsByTagName('iframe')[0] as HTMLIFrameElement | undefined
+    const iframeDoc = iframe?.contentWindow?.document
+    if (iframeDoc?.documentElement) {
+      iframeDoc.documentElement.style.fontSize = `${BASE_FONT_SIZE + fontScale.value - 1}px`
+    }
+  }
+  catch (error) {
+    console.warn('设置iframe字号失败:', error)
+  }
+}
+
+const changeFontScale = (delta: number) => {
+  const next = fontScale.value + delta
+  if (next < MIN_FONT_SCALE || next > MAX_FONT_SCALE) return
+  fontScale.value = next
+  setToolIframeFontSize()
+}
+
 const iframeLabel = computed(() => {
   return getTypeLabel(frametype.value)
 })
@@ -730,6 +773,36 @@ const updateGradientColors = (color: string) => {
   }
 }
 
+.font-scale-ctrl {
+  gap: 8px;
+  padding: 0 10px;
+
+  .scale-btn {
+    display: flex;
+    align-items: center;
+
+    svg {
+      width: 14px;
+      height: 14px;
+    }
+
+    &:hover {
+      color: #f89c46;
+    }
+
+    &.disable {
+      opacity: .4;
+      cursor: not-allowed;
+    }
+  }
+
+  .scale-value {
+    min-width: 20px;
+    text-align: center;
+    font-size: 13px;
+  }
+}
+
 .reset-preview-btn {
   gap: 5px;
   color: #6b7280;