Browse Source

feat: icon 支持

kindring 10 months ago
parent
commit
4e6de6c080

+ 60 - 0
plugins/SVGLoader.ts

@@ -0,0 +1,60 @@
+import { readFileSync, readdirSync } from 'fs'
+let idPerfix = ''
+const svgTitle = /<svg([^>+].*?)>/
+const clearHeightWidth = /(width|height)="([^>+].*?)"/g
+const hasViewBox = /(viewBox="[^>+].*?")/g
+const clearReturn = /(\r)|(\n)/g
+function findSvgFile(dir: string):string[] {
+    const svgRes = []
+    const dirents = readdirSync(dir, {
+        withFileTypes: true
+    })
+    for (const dirent of dirents) {
+        if (dirent.isDirectory()) {
+            svgRes.push(...findSvgFile(dir + dirent.name + '/'))
+        } else {
+            const svg = readFileSync(dir + dirent.name)
+                .toString()
+                .replace(clearReturn, '')
+                .replace(svgTitle, ($1, $2: string) => {
+                    let width: string = '0'
+                    let height: string = '0'
+                    let content = $2.replace(clearHeightWidth, (s1: string, s2: string, s3: string) => {
+                        if (s2 === 'width') {
+                            width = s3
+                        } else if (s2 === 'height') {
+                            height = s3
+                        }
+                        return ''
+                    })
+                    if (!hasViewBox.test($2)) {
+                        content += `viewBox="0 0 ${width} ${height}"`
+                    }
+                    return `<symbol id="${idPerfix}-${dirent.name.replace('.svg', '')}" ${content}>`
+                })
+                .replace('</svg>', '</symbol>')
+            svgRes.push(svg)
+        }
+    }
+    return svgRes
+}
+export const svgLoader = (path: string, perfix = 'icon') => {
+    if (path === '') return
+    idPerfix = perfix
+    console.log('svgLoader');
+    const res = findSvgFile(path)
+    return {
+        name: 'svg-transform',
+        transformIndexHtml(html: any) {
+            return html.replace(
+                '<body>',
+                `
+          <body>
+            <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">
+              ${res.join('')}
+            </svg>
+        `
+            )
+        }
+    }
+}

+ 3 - 1
src/App.vue

@@ -9,7 +9,9 @@ onMounted(() => {
 </script>
 
 <template>
-  <mac-window :title="'test'"/>
+  <mac-window :title="'test'" :icon="'home'">
+    测试
+  </mac-window>
 </template>
 
 <style scoped>

+ 15 - 1
src/assets/base.css

@@ -25,9 +25,19 @@
     padding-left: 5px;
     display: flex;
     width: 100%;
+    box-sizing: border-box;
+    align-items: center;
     /*    运行拖拽*/
 }
-/*.top-bar*/
+.top-bar .top-title{
+    width: 100%;
+    height: 30px;
+    display: flex;
+    align-items: center;
+}
+
+
+    /*.top-bar*/
 .control-box{
     width: auto;
     height: 100%;
@@ -92,3 +102,7 @@
     position: relative;
     /*    允许被点击*/
 }
+
+.ml-1\.5{
+    margin-left: 1.5rem;
+}

+ 1 - 0
src/assets/svg/home.svg

@@ -0,0 +1 @@
+<svg t="1682498600579" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3469" width="200" height="200"><path d="M1014.613212 543.119765c-3.970428 3.806699-9.076726 5.699816-14.172791 5.699816-5.372358 0-10.744715-2.108011-14.766308-6.293333l-64.539922-67.24145 0 523.543917c0 11.307533-9.15859 20.466124-20.466124 20.466124l-265.261433 0c-11.307533 0-20.466124-9.15859-20.466124-20.466124 0-11.2973 9.15859-20.466124 20.466124-20.466124l244.795309 0 0-545.729196-367.233895-382.614188-367.223662 382.593721 0 545.749662 224.329185 0L370.07357 672.353105c0-11.307533 9.168824-20.466124 20.466124-20.466124l244.86694 0c11.2973 0 20.466124 9.15859 20.466124 20.466124 0 11.2973-9.168824 20.466124-20.466124 20.466124l-224.400816 0 0 306.009486c0 11.307533-9.15859 20.466124-20.466124 20.466124l-265.261433 0c-11.2973 0-20.466124-9.15859-20.466124-20.466124L104.812137 475.264331l-64.550155 67.251683c-7.828292 8.15575-20.783349 8.42181-28.939099 0.593518s-8.42181-20.783349-0.593518-28.939099L498.201739 6.293333c3.857864-4.021593 9.18929-6.293333 14.766308-6.293333 5.566786 0 10.898211 2.27174 14.756075 6.293333l487.482607 507.887332C1023.035022 522.336416 1022.768963 535.291472 1014.613212 543.119765z" p-id="3470"></path></svg>

+ 1 - 0
src/assets/svg/question.svg

@@ -0,0 +1 @@
+<svg t="1687851320065" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1454" width="200" height="200"><path d="M878.933333 1024c-8.533333 0-17.066667 0-21.333333-4.266667l-179.2-110.933333c-21.333333 8.533333-42.666667 12.8-59.733333 17.066667-34.133333 8.533333-72.533333 12.8-106.666667 12.8-260.266667 0-469.333333-209.066667-469.333333-469.333334S251.733333 0 512 0s469.333333 209.066667 469.333333 469.333333c0 55.466667-8.533333 106.666667-25.6 157.866667-8.533333 25.6-21.333333 55.466667-38.4 81.066667-12.8 21.333333-38.4 25.6-59.733333 17.066666-21.333333-12.8-25.6-38.4-17.066667-59.733333 12.8-21.333333 21.333333-42.666667 29.866667-64 12.8-42.666667 21.333333-85.333333 21.333333-128 0-213.333333-170.666667-384-384-384s-384 170.666667-384 384 170.666667 384 384 384c29.866667 0 59.733333-4.266667 85.333334-8.533333 21.333333-4.266667 46.933333-12.8 68.266666-21.333334 12.8-4.266667 25.6-4.266667 38.4 4.266667l132.266667 81.066667v-72.533334c0-25.6 17.066667-42.666667 42.666667-42.666666s42.666667 17.066667 42.666666 42.666666V981.333333c0 17.066667-8.533333 29.866667-21.333333 38.4 0 4.266667-8.533333 4.266667-17.066667 4.266667z" fill="#A6AAAF" p-id="1455"></path><path d="M512 618.666667c-25.6 0-42.666667-17.066667-42.666667-42.666667V512c0-25.6 17.066667-42.666667 42.666667-42.666667 46.933333 0 85.333333-38.4 85.333333-85.333333s-38.4-85.333333-85.333333-85.333333-85.333333 38.4-85.333333 85.333333c0 25.6-17.066667 42.666667-42.666667 42.666667s-42.666667-17.066667-42.666667-42.666667c0-93.866667 76.8-170.666667 170.666667-170.666667s170.666667 76.8 170.666667 170.666667c0 81.066667-55.466667 145.066667-128 166.4v25.6c0 25.6-17.066667 42.666667-42.666667 42.666667z" fill="#A6AAAF" p-id="1456"></path><path d="M512 682.666667m-42.666667 0a42.666667 42.666667 0 1 0 85.333334 0 42.666667 42.666667 0 1 0-85.333334 0Z" fill="#A6AAAF" p-id="1457"></path></svg>

File diff suppressed because it is too large
+ 0 - 0
src/assets/svg/setting.svg


+ 14 - 0
src/components/magnet.vue

@@ -0,0 +1,14 @@
+<script setup lang="ts">
+
+</script>
+
+<template>
+<!-- 磁帖 布局组件, -->
+<div class="magnet">
+
+</div>
+</template>
+
+<style scoped>
+
+</style>

+ 6 - 0
src/components/public/icon/iconSvg.ts

@@ -0,0 +1,6 @@
+import iconSvg from './iconSvg.vue';
+
+export function bindIconSvg(app: any) {
+    app.component('iconSvg', iconSvg);
+    return app;
+}

+ 36 - 0
src/components/public/icon/iconSvg.vue

@@ -0,0 +1,36 @@
+<script setup lang="ts">
+import {computed} from 'vue'
+// import type {PropType} from 'vue'
+
+let props = defineProps({
+  iconClass: {
+    type: String,
+    required: true,
+  },
+  className: {
+    type: String,
+    default: '',
+  },
+});
+
+let svgClass = computed(() => `svg-icon ${props.className ?? ''}`);
+
+let iconName = computed(() => `#icon-${props.className}`);
+
+</script>
+
+<template>
+  <svg :class="svgClass" aria-hidden="true">
+    <use :xlink:href="iconName"/>
+  </svg>
+</template>
+
+<style scoped>
+.svg-icon {
+  width: 1em;
+  height: 1em;
+  vertical-align: -0.15em;
+  fill: currentColor;
+  overflow: hidden;
+}
+</style>

+ 7 - 4
src/components/window/macWindow.vue

@@ -1,12 +1,13 @@
 <script setup lang="ts">
 import {ComponentInternalInstance, getCurrentInstance, Ref, ref, UnwrapRef} from "vue";
-import {actionMap, IpcAction, windowAction} from "../../tools/IpcCmd.ts";
+import { IpcAction, windowAction} from "../../tools/IpcCmd.ts";
 
 import "@/assets/base.css"
 
 const { proxy } = getCurrentInstance() as ComponentInternalInstance
 defineProps<{
   title: string,
+  icon: string,
 }>()
 const isDing: Ref<UnwrapRef<boolean>> = ref(false)
 const isFull: Ref<UnwrapRef<boolean>> = ref(false)
@@ -31,9 +32,11 @@ const btnClickHandel = (action: IpcAction) => {
 <template>
   <div class="window">
     <div class="top-bar">
-      <div class="drag flex items-center" >
-<!--        <svg-icon :icon-class="icon"/>-->
-        <span class="ml-1.5 ">{{title}}</span>
+      <div class="drag top-title" >
+        <slot name="top">
+          <icon-svg  :class-name="icon"/>
+          <span class="ml-1.5 ">{{title}}</span>
+        </slot>
 
       </div>
 

+ 2 - 0
src/main.ts

@@ -2,10 +2,12 @@ import {App, createApp} from 'vue'
 import './style.css'
 import AppPage from './App.vue'
 import {windowInit} from "./util/pageHandle.ts";
+import {bindIconSvg} from "@/components/public/icon/iconSvg.ts";
 
 
 const app: App = createApp(AppPage)
 
 windowInit(app);
+bindIconSvg(app);
 
 app.mount('#app');

+ 3 - 1
vite.config.ts

@@ -4,12 +4,14 @@ import optimizer from "vite-plugin-optimizer";
 
 import {buildPlugin} from "./plugins/buildPlugin";
 import { devPlugin, getReplacer } from "./plugins/devPlugin";
+import {svgLoader} from "./plugins/SVGLoader";
 
 export default defineConfig({
       plugins: [
           optimizer(getReplacer()),
           devPlugin(),
-          vue()
+          vue(),
+          svgLoader('./src/assets/svg/'),
       ],
     build: {
         rollupOptions: {

Some files were not shown because too many files changed in this diff