ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
Editor.jsでインラインのマーカーツールで作成する

Editor.jsでインラインのマーカーツールで作成する

概要 Editor.jsでインラインのマーカーツールを作成する方法の備忘録です。 参考 以下のページが参考になりました。 https://editorjs.io/creating-an-inline-tool/ https://note.com/eveningmoon_lab/n/n638b9541c47c TypeScriptでの記述にあたっては、以下が参考になりました。 https://github.com/codex-team/editor.js/issues/900 実装 Nuxtで実装します。以下のmarker.tsを作成します。 import type { API } from "@editorjs/editorjs"; class MarkerTool { button: null | HTMLButtonElement; state: boolean; api: API; tag: string; class: string; // 静的メソッドで許可されるHTMLタグと属性を指定 static get sanitize() { return { mark: { class: "cdx-marker", }, }; } // インラインツールとしての振る舞いを定義 static get isInline() { return true; } constructor({ api }: { api: API }) { this.api = api; this.button = null; this.state = false; this.tag = "MARK"; this.class = "cdx-marker"; } // ボタン要素を作成し、SVGアイコンを設定 render() { this.button = document.createElement("button"); this.button.type = "button"; this.button.innerHTML = '<svg width="20" height="18"><path d="M10.458 12.04l2.919 1.686-.781 1.417-.984-.03-.974 1.687H8.674l1.49-2.583-.508-.775.802-1.401zm.546-.952l3.624-6.327a1.597 1.597 0 0 1 2.182-.59 1.632 1.632 0 0 1 .615 2.201l-3.519 6.391-2.902-1.675zm-7.73 3.467h3.465a1.123 1.123 0 1 1 0 2.247H3.273a1.123 1.123 0 1 1 0-2.247z"/></svg>'; this.button.classList.add(this.api.styles.inlineToolButton); return this.button; } // 選択されたテキストを <mark> タグで囲む surround(range: Range) { if (this.state) { this.unwrap(range); return; } this.wrap(range); } // テキストを <mark> タグでラップ wrap(range: Range) { const selectedText = range.extractContents(); const mark = document.createElement(this.tag); mark.className = this.class; // class 属性の追加 mark.appendChild(selectedText); range.insertNode(mark); this.api.selection.expandToTag(mark); } // <mark> タグを解除 unwrap(range: Range) { const mark = this.api.selection.findParentTag(this.tag); const text = range.extractContents(); mark?.remove(); range.insertNode(text); } // ツールの状態をチェック checkState() { const mark = this.api.selection.findParentTag(this.tag, this.class); this.state = !!mark; if (this.state) { this.button?.classList.add("cdx-marker--active"); } else { this.button?.classList.remove("cdx-marker--active"); } } } export default MarkerTool; 上記を以下のように呼び出します。 ...

Editor.jsのmax-widthを変更する

Editor.jsのmax-widthを変更する

概要 Editor.jsを使用する際、デフォルトでは左右に大きなマージンができます。これを解決する方法を紹介します。 方法 以下が参考になりました。 https://github.com/codex-team/editor.js/issues/1328 具体的には、以下を追加します。 .ce-block__content, .ce-toolbar__content { max-width: calc(100% - 80px) !important; } .cdx-block { max-width: 100% !important; } ソースコード全体は以下です。 <script setup lang="ts"> import EditorJS from "@editorjs/editorjs"; import type { OutputData } from "@editorjs/editorjs"; const blocks = ref<OutputData>({ time: new Date().getTime(), blocks: [ { type: "paragraph", data: { text: "大明副使蒋 承奉すらく 、 欽差督察総制提督浙江等処軍務各衙門 、近年以来、日本各島小民、仮るに買売を以て名と為し 、 しばしば中国辺境を犯し、居民を刼掠するを因となし、旨を奉じて 、 浙江等処承宣布政使司 に議行し、本職に転行して 、 親しく貴国に詣り面議せしめん等の因あり。", }, }, ], }); const editor = () => { new EditorJS({ holder: "editorjs", data: blocks.value, onChange: async (api) => { blocks.value = await api.saver.save(); }, }); }; editor(); </script> <template> <div style="background-color: aliceblue"> <div id="editorjs"></div> <hljson :content="blocks" /> </div> </template> <style> .ce-block__content, .ce-toolbar__content { max-width: calc(100% - 80px) !important; } .cdx-block { max-width: 100% !important; } pre { background-color: #f4f4f4; border: 1px solid #ccc; padding: 10px; } </style> 結果、以下のように、左右のマージンが小さくなりました。 ...

Nuxt 3 x Composition APIでLeaflet Marker Clusterを試す

Nuxt 3 x Composition APIでLeaflet Marker Clusterを試す

概要 以下の記事で、Nuxt 3でLeaflet Marker Clusterを試す方法を紹介しました。今回は、Composition APIを使った書き方に更新したので、その備忘録です。 インストール 以下をインストールします。 npm i leaflet leaflet.markercluster @vue-leaflet/vue-leaflet npm i -D @types/leaflet @types/leaflet.markercluster ソースコード 以下を参考にしてください。 https://github.com/nakamura196/nuxt3-demo/blob/main/components/map/MarkerCluster.vue まとめ TypeScriptに一部対応できていない点がありますが、参考になりましたら幸いです。

Nuxt3 x Vuetify x Cytoscape

Nuxt3 x Vuetify x Cytoscape

概要 Nuxt3とVuetifyを使用したサンプルリポジトリに、Cytoscapeの動作デモを追加しました。 https://github.com/nakamura196/nuxt3-demo 以下のページで動作確認いただけます。 https://nakamura196.github.io/nuxt3-demo/ インストール 以下を実行しました。 npm i cytoscape npm i @types/cytoscape ソースコード <template> <div id="view"> <v-btn class="ma-4" color="primary" v-on:click="addNode">push</v-btn> <div id="cy"></div> </div> </template> <script setup lang="ts"> import cytoscape from "cytoscape"; let cy: any = null; // = ref(null); //reactive({}); //: any const count: number = 0; // = ref(0); //reactive(0); const addNode = () => { cy.add([ { group: "nodes", data: { id: "node" + count }, position: { x: 300, y: 200 }, }, { group: "edges", data: { id: "edge" + count, source: "node" + count, target: "cat" }, }, ]); }; onMounted(() => { cy = cytoscape({ container: document.getElementById("cy"), boxSelectionEnabled: false, autounselectify: true, style: cytoscape .stylesheet() .selector("node") .css({ height: 80, width: 80, "background-fit": "cover", "border-color": "#000", "border-width": 3, "border-opacity": 0.5, content: "data(name)", "text-valign": "center", }) .selector("edge") .css({ width: 6, "target-arrow-shape": "triangle", "line-color": "#ffaaaa", "target-arrow-color": "#ffaaaa", "curve-style": "bezier", }), elements: { nodes: [ { data: { id: "cat" } }, { data: { id: "bird" } }, { data: { id: "ladybug" } }, { data: { id: "aphid" } }, { data: { id: "rose" } }, { data: { id: "grasshopper" } }, { data: { id: "plant" } }, { data: { id: "wheat" } }, ], edges: [ { data: { source: "cat", target: "bird" } }, { data: { source: "bird", target: "ladybug" } }, { data: { source: "bird", target: "grasshopper" } }, { data: { source: "grasshopper", target: "plant" } }, { data: { source: "grasshopper", target: "wheat" } }, { data: { source: "ladybug", target: "aphid" } }, { data: { source: "aphid", target: "rose" } }, ], }, layout: { name: "breadthfirst", directed: true, padding: 10, }, }); }); </script> <style scoped> #cy { width: 100%; height: 80%; position: absolute; background-color: lightcyan; } </style> まとめ 参考になりましたら幸いです。 ...

Vue.js: Splitpanesを用いた際のiframeを含むpaneへの対処方法

Vue.js: Splitpanesを用いた際のiframeを含むpaneへの対処方法

Splitpanesは、以下のように、ペイン(pane)分割・リサイズを可能にするVue.jsのライブラリです。 https://github.com/antoniandre/splitpanes このライブラリの利用にあたり、ペインにiframe要素を含む際、リサイズがうまくできないことがありました。これに対して、以下で対応方法が記載されていました。 https://github.com/antoniandre/splitpanes/pull/162 上記に記載がある通り、以下を追記することで、iframe要素を含むペインがあっても、正しくリサイズ操作を行うことができました。 .splitpanes--dragging .splitpanes__pane { pointer-events: none; } 同様のことでお困りの方の参考になりましたら幸いです。

VueUseを用いたテキスト選択(Nuxt3)

VueUseを用いたテキスト選択(Nuxt3)

概要 Nuxt3(Vue3)を用いたテキストの選択機能の実装にあたり、VueUseを使用してみましたので、その備忘録です。 https://vueuse.org/ デモ 以下のページからお試しいただけます。 https://nuxt3-demo-git-main-nakamura196.vercel.app/textSelection ソースコードは以下です。 https://github.com/nakamura196/nuxt3-demo/blob/main/pages/textSelection.vue インストール方法 以下のページに記載があります。 https://vueuse.org/guide/ 具体的な手順は、以下のとおりです。 npm i -D @vueuse/nuxt @vueuse/core // nuxt.config.ts export default defineNuxtConfig({ modules: [ '@vueuse/nuxt', ], }) まとめ テキスト選択以外にも、便利な機能が色々と使えるようなので、引き続き試してみたいと思います。

vue3とbabylon.jsの双方向のやりとり例(その2)

vue3とbabylon.jsの双方向のやりとり例(その2)

概要 以下の記事で、vue3とbabylon.jsのやりとりを行うプログラムを作成しました。 今回は上記の発展版として、sceneに渡すmeshをvueから指定しています。以下のリンク先で内容をご確認いただけます。(途中、meshをうまく削除できていない箇所があります。今後修正予定です。) https://youtu.be/-dyQp-QX42I デモサイト https://nakamura196.github.io/nuxt3-babylonjs/10 ソースコード https://github.com/nakamura196/nuxt3-babylonjs/blob/main/pages/10/index.vue まとめ 参考になりましたら幸いです。

vue3とbabylon.jsの双方向のやりとり例

vue3とbabylon.jsの双方向のやりとり例

概要 vue3とbabylon.jsの双方向のやりとりを行うプログラムを試作しました。以下のリンク先で内容をご確認いただけます。 https://youtube.com/shorts/BIdj-3T2_z8 デモサイト https://nakamura196.github.io/nuxt3-babylonjs/9 ソースコード https://github.com/nakamura196/nuxt3-babylonjs/blob/main/pages/9/index.vue まとめ 参考になりましたら幸いです。

Nuxt 3でLeaflet Marker Clusterを試す

Nuxt 3でLeaflet Marker Clusterを試す

Nuxt 3でLeaflet Marker Clusterを試す機会がありました。実装例は以下です。 https://nuxt3-demo-nine.vercel.app/map-cluster 本実装にあたり、以下のページを参考にさせていただきました。 https://codesandbox.io/s/ns238 ソースコードは以下です。 https://github.com/nakamura196/nuxt3-demo 2023年3月時点においては、POC(Proof of Concept)の段階のようです。参考になりましたら幸いです。

TEIビューアでの利用を想定したCustom OpenSegDragon Viewerを作成しました。

TEIビューアでの利用を想定したCustom OpenSegDragon Viewerを作成しました。

概要 TEIビューアでの利用を想定したCustom OpenSegDragon Viewerを作成しました。 背景 以下のようなTEIとIIIFを対応させたビューア開発において、次に示す機能を持ったビューアが必要でした。 https://www.hi.u-tokyo.ac.jp/collection/digitalgallery/wakozukan/tei/ IIIFのマニフェストファイルを読み込むことができる。 ビューアコンポーネント側でのコマ送りを、コンポーネント外で把握することができる。 画像の部分領域をハイライトすることができる。 上記の要件を全てを満たす既存のIIIF対応ビューアを見つけることができなかったため、独自のビューアの開発を試みました。合わせて、npmパッケージとして公開することも試みました。 開発したビューア ドキュメンテーション等がまだ不十分ですが、以下のページで公開しています。このページで、ソースコードへのリンクも掲載しています。 https://www.npmjs.com/package/@nakamura196/osd-custom-viewer vue3とviteを使ったコンポーネントの開発およびnpmでの公開にあたっては、以下のサイトを参考にしました。 https://blog.egmond.dev/vue-component-to-npm-package 使用例 以下のページで導入例をご確認いただけます。 https://nakamura196.github.io/nuxt3-iiif-viewer/custom-osd コンポーネント内外からのコマ送りが可能です。これにより、例えばIIIF画像とTEIテキストの並列表示を行った際、TEIテキスト側からのコマ送りや、画像のコマ送りによる当該テキストへのスクロールなどを行うことができます。 またハイライト機能用いることで、あるテキスト行に対応した画像の部分領域をハイライトさせる、といったことが可能です。 使用例のソースコードは以下です。 https://github.com/nakamura196/nuxt3-iiif-viewer/blob/main/pages/custom-osd/index.vue ssrでの公開にあたり、pluginsフォルダに以下を追加しています。 https://github.com/nakamura196/nuxt3-iiif-viewer/blob/main/plugins/custom-osd.client.js まとめ ドキュメンテーションの充実や、IIIF v3への対応など、多くのTODOが残っていますが、参考になりましたら幸いです。

LeafletのVue3での使用例(座標範囲の取得を含む)

LeafletのVue3での使用例(座標範囲の取得を含む)

LeafletのVue3での使用例(座標範囲の取得を含む)を紹介するリポジトリを作成しました。 以下が動作例です。 https://static.ldas.jp/vue3-leaflet/ ソースコードは以下です。 https://github.com/ldasjp8/vue3-leaflet Vue3初学者のため、誤りなどがあるかもしれませんが、参考になりましたら幸いです。

Vue3でOpenSeadragonを使用するサンプルリポジトリを作成しました。

Vue3でOpenSeadragonを使用するサンプルリポジトリを作成しました。

Vue3でOpenSeadragonを使用するサンプルリポジトリを作成しました。 以下が動作例です。 https://static.ldas.jp/vue3-osd/ ソースコードは以下です。 https://github.com/ldasjp8/vue3-osd Vue3初学者のため、誤りなどがあるかもしれませんが、参考になりましたら幸いです。