Переглянути джерело

feat: 添加动态font支持

LosMessi 2 роки тому
батько
коміт
949610bae9
5 змінених файлів з 76 додано та 7 видалено
  1. BIN
      public/data/kaiti.ttf
  2. 9 3
      src/data/pages.json
  3. 57 0
      src/utils/loadFonts.js
  4. 3 1
      src/views/demo.vue
  5. 7 3
      src/views/page.vue

BIN
public/data/kaiti.ttf


+ 9 - 3
src/data/pages.json

@@ -4,14 +4,15 @@
     "config": {
       "title": "考察手册",
       "logo": "http://img2.wmnetwork.cc/w/202104/08/0_20210408153854_gtJk9Tym.png",
-      "background": "https://ndzx.hqedust.com/file/image/backgroud.png"
+      "background": "https://ndzx.hqedust.com/file/image/backgroud.png",
+      "fonts": "kaiti=http://localhost:8081/data/kaiti.ttf"
     },
     "main": {
       "background": "https://ndzx.hqedust.com/file/image/bg.jpg",
       "logo": "https://ndzx.hqedust.com/file/image/logo.png",
       "paperId": 2,
-      "style": " font-family:STKaiti;",
-      "title": "全国乡村振兴理论研讨会暨《摆脱贫困》学习座谈会"
+      "style": "font-family:kaiti;",
+      "title": "《摆脱贫困》出版三十周年暨乡村振兴理论研讨会"
     },
     "pages": [
       {
@@ -31,6 +32,11 @@
               }
             ]
           },
+          {
+            "type": "text",
+            "text": "《摆脱贫困》出版三十周年暨乡村振兴理论研讨会",
+            "style": "font-family:kaiti;"
+          },
           {
             "type": "matrix",
             "children": [

+ 57 - 0
src/utils/loadFonts.js

@@ -0,0 +1,57 @@
+function checkFont(name) {
+  if (!document.fonts) return false;
+  const fonts = [...document.fonts.values()];
+  return !!fonts.find(font => font.family === name);
+}
+
+function loadFont(font) {
+  return new Promise(resolve => {
+    if (!font) return resolve(true);
+    const { name, url, descriptors = {} } = font;
+    if (!name || !url) return resolve(true);
+    if (!document.fonts || checkFont(name)) return resolve(true);
+    const fontFace = new FontFace(name, `url(${url})`, descriptors);
+    fontFace
+      .load()
+      .then(font => {
+        document.fonts.add(font);
+        resolve(true);
+      })
+      .catch(err => {
+        console.error(err);
+        resolve(true);
+      });
+  });
+}
+
+function allSettled(arr) {
+  return new Promise(resolve => {
+    let res = [];
+    const push = data => {
+      res.push(data);
+      if (res.length === arr.length) {
+        resolve(res);
+      }
+    };
+    arr.forEach(p => {
+      p.then(value => {
+        push({ status: 'fulfilled', value });
+      }).catch(reason => {
+        push({ status: 'rejected', reason });
+      });
+    });
+  });
+}
+
+export default async function (fonts) {
+  if (typeof fonts === 'string' && fonts.length > 0) {
+    fonts = fonts.split('|').map(font => {
+      font = font.split('=');
+      const [name, url] = font;
+      return { name, url };
+    });
+  }
+  if (!Array.isArray(fonts) && !fonts.length) return;
+  console.log('fonts', fonts);
+  return allSettled(fonts.map(font => loadFont(font)));
+}

+ 3 - 1
src/views/demo.vue

@@ -3,6 +3,7 @@
 </template>
 <script>
 import pages from '../data/pages.json';
+import loadFonts from '../utils/loadFonts';
 
 export default {
   created(){
@@ -11,7 +12,8 @@ export default {
       _pages[page.id] = page;
     });
     pages.data.pages = _pages;
-    this.$store.dispatch('setPage', pages.data).then(() => {
+    this.$store.dispatch('setPage', pages.data).then(async () => {
+      await loadFonts(pages.data.config.fonts);
       this.$router.push('/page/demo/main');
     })
   }

+ 7 - 3
src/views/page.vue

@@ -18,7 +18,8 @@
 <script>
 import EventBus from '@/utils/eventBus.js';
 import QR from '../plugins/qr';
-import {fetch} from '@/api/page.js'
+import {fetch} from '@/api/page.js';
+import loadFonts from '../utils/loadFonts';
 
 export default {
   data(){
@@ -90,11 +91,14 @@ export default {
       this.backMain = (id != 'main');
       if(this.loading) return;
       this.loading = true;
-      fetch("paper.getpaper", {uuid}).then((res) => {
-        this.loading = false;
+      fetch("paper.getpaper", {uuid}).then(async res => {
         this.$store.dispatch('setPage', res);
+        if(res.main.fonts) {
+          await loadFonts(res.main.fonts);
+        }
         res.title && (document.title = res.title);
         this.getPageInfo();
+        this.loading = false;
       }).catch((err) => {
         console.log("err", err)
         this.loading = false;