]> git.ipfire.org Git - thirdparty/google/fonts.git/commitdiff
add more components
authorMarc Foley <m.foley.88@gmail.com>
Wed, 16 Jul 2025 09:01:12 +0000 (10:01 +0100)
committerMarc Foley <m.foley.88@gmail.com>
Wed, 16 Jul 2025 09:19:40 +0000 (10:19 +0100)
tagger2/AddTag.js [new file with mode: 0644]
tagger2/Panel.js [new file with mode: 0644]
tagger2/TagView.js [new file with mode: 0644]
tagger2/TagsByCategories.js [new file with mode: 0644]

diff --git a/tagger2/AddTag.js b/tagger2/AddTag.js
new file mode 100644 (file)
index 0000000..2ba2925
--- /dev/null
@@ -0,0 +1,105 @@
+import {FontTag} from "./models.js";
+
+export default {
+    props: ["categories"],
+    data: function() {
+        return {
+            category: "", 
+            newFamily: "",
+            newScore: 0,
+            isVF: false,
+            axes: [],
+            axisName: "",
+            axisPositions: 2,
+        }
+    },
+    methods: {
+        addTag() {
+            const tag = new FontTag(this.category, this.newFamily, [], this.newScore)
+            this.$emit('tag-added', tag);
+        },
+        addVFTags() {
+            // perform a cross product of the axes and their positions and create a new VF tag for each combination
+            const solved = this.axesCombos(this.axes);
+            for (let coordinateSet of solved) {
+                const vfTag = new FontTag(this.category, this.newFamily, coordinateSet.axes, coordinateSet.score);
+                this.$emit('tag-added', vfTag);
+            }
+        },
+        addAxis() {
+            console.log("Adding axis", this.axisName, this.axisPositions);
+            const positions = [];
+            for (let i = 0; i < this.axisPositions; i++) {
+                positions.push({"coordinate": 0, "score": 0}); // Default position for each axis
+            }
+            this.axes.push({
+                tag: this.axisName,
+                positions: positions
+            })
+        },
+        deleteAxis(axis) {
+            const index = this.axes.indexOf(axis);
+            if (index > -1) {
+                this.axes.splice(index, 1);
+            }
+        },
+        _axesCombos(axes, current = [], res = []) {
+            if (current.length === axes.length) {
+                const axisSet = {score: 0, axes: []};
+                for (let i = 0; i < current.length; i++) {
+                    axisSet.score += Number(current[i].score);
+                    axisSet.axes.push({tag: axes[i].tag, coords: current[i].coordinate});
+                }
+                res.push(axisSet);
+                return res;
+            }
+            for (let i = 0; i < axes[current.length].positions.length; i++) {
+                this._axesCombos(axes, [...current, axes[current.length].positions[i]], res);
+            }
+            return res;
+        },
+        axesCombos(axes) {
+            let axisSets = this._axesCombos(axes);
+            axisSets.forEach((axisSet) => {
+                axisSet.axes.forEach((axis) => {
+                    delete axis.score;
+                });
+            });
+            return axisSets;
+        }
+    },
+    template: `
+        <div style="border: 1px solid black">
+            <h3>Add Tag</h3>
+            <input type="checkbox" v-model="isVF" value="true" /> Variable Font
+            <h3>Category</h3>
+            <select v-model="category">
+                <option v-for="category in categories" :key="category">
+                    {{ category }}
+                </option>
+            </select>
+            <h3>Family</h3>
+            <input type="text" v-model="newFamily" placeholder="Add new family" />
+            <div v-if="isVF">
+                <input type="text" v-model="axisName" placeholder="Axis name" />
+                <input type="number" v-model="axisPositions"/>
+                <button @click="addAxis">Add Axis</button>
+                <div v-for="axis in axes">
+                    <h4>{{ axis.tag }}</h4>
+                    <button @click="deleteAxis(axis)">Delete Axis</button>
+                    <div v-for="(position, index) in axis.positions" :key="index">
+                        Coordinate:
+                        <input type="number" v-model="position.coordinate" placeholder="Position" />
+                        Score:
+                        <input type="number" v-model="position.score" placeholder="Score" />
+                    </div>
+                </div>
+            <button @click="addVFTags">Add</button>
+            </div>
+            <div v-else>
+                <input type="number" v-model="newScore" placeholder="Initial score" />
+                <button @click="addTag">Add</button>
+            </div>
+        </div>
+    `,
+}
\ No newline at end of file
diff --git a/tagger2/Panel.js b/tagger2/Panel.js
new file mode 100644 (file)
index 0000000..620ca20
--- /dev/null
@@ -0,0 +1,15 @@
+export default {
+  props: ['panel', 'tags'],
+  methods: {
+    remove() {
+      this.$emit('remove');
+    }
+  },
+  template: `
+    <div class="panel" style="border:1px solid #ccc; padding:1em; margin-bottom:1em;">
+      <button @click="remove" style="float:right">✕</button>
+      <tags-by-font v-if="panel.type === 'font'" :tags="tags" :font="panel.font"></tags-by-font>
+      <tags-by-categories v-else-if="panel.type === 'categories'" :tags="tags" :categories="panel.categories"></tags-by-categories>
+    </div>
+  `
+};
diff --git a/tagger2/TagView.js b/tagger2/TagView.js
new file mode 100644 (file)
index 0000000..f732888
--- /dev/null
@@ -0,0 +1,16 @@
+export default {
+    props: ["tag"],
+    template: `
+        <div>
+            <div class="tag-title">
+                <span class="tag-name">{{ tag.tagName }}</span>
+                <span class="tag-family">{{ tag.family.name }}</span>
+                <span class="tag-score">Score: {{ tag.score }}</span>
+            </div>
+            <div class="text-editor" contenteditable="true" :style="tag.cssStyle">
+                Hello world
+            </div>
+        </div>
+            
+    `,
+}
\ No newline at end of file
diff --git a/tagger2/TagsByCategories.js b/tagger2/TagsByCategories.js
new file mode 100644 (file)
index 0000000..38ab873
--- /dev/null
@@ -0,0 +1,56 @@
+export default {
+  props: ['tags', 'categories'],
+  data() {
+    return {
+      selectedCategories: [...this.categories],
+      sortBy: 'family' // Default sorting option
+    };
+  },
+  watch: {
+    categories(newVal) {
+      this.selectedCategories = [...newVal];
+    }
+  },
+  computed: {
+    filteredTags() {
+      // Use selectedCategories for filtering
+      const filtered = this.tags.filter(tag => this.selectedCategories.includes(tag.tagName));
+      // Sort by family name and tag name
+      if (this.sortBy === 'score') {
+        return filtered.sort((a, b) => b.score - a.score);
+      }
+      if (this.sortBy === 'family') {
+        return filtered.sort((a, b) => {
+          if (a.family.name < b.family.name) return -1;
+          if (a.family.name > b.family.name) return 1;
+          if (a.tagName < b.tagName) return -1;
+          if (a.tagName > b.tagName) return 1;
+          return 0;
+        });
+      }
+    },
+    sortedCategories() {
+      const res = this.tags.map(tag => tag.tagName)
+        .filter((value, index, self) => self.indexOf(value) === index)
+        .sort();
+      return res;
+    }
+  },
+  template: `
+    <div>
+      <h3>Tags for categories:</h3>
+      <select v-model="sortBy">
+        <option value="family">Family</option>
+        <option value="score">Score</option>
+      </select>
+      <select v-model="selectedCategories" multiple>
+        <option v-for="category in sortedCategories" :key="category">
+          {{ category }}
+        </option>
+      </select>
+        <div v-for="tag in filteredTags" :key="tag.family.name + tag.tagName">
+          <tag-view :tag="tag"></tag-view>
+        </div>
+    </div>
+  `
+};