たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 18602
目次
本題
作った
ソースコード
公式
ざっくり
つくる
環境
Figma デスクトップアプリ版を入れる
プラグインをつくる
VSCode で開く
git を使う(お好みで)
Vite + React で UI 部分を開発できるようにする
そもそも Vite とか Webpack とか esbuild って何?
esbuild
Vite
Figma の esbuild サンプルを見る
フロントエンド難しすぎ
Figma プラグイン開発で esbuild + Vite + React + Tailwind CSS を使うようにセットアップ
フォルダ構成を変更しておく
esbuild
Vite と React
package.json の編集
React で UI を作る
ビルドしてみる
Figma 側で読み込んでみる
タイプチェックをする
Tailwind CSS を入れる(欲しければ)
Figma Plugin API になれよう
code.ts
座標系
console.log
アイテム(ノード)の選択イベント
片っぽだけ矢印をつける
PluginAPI['mixed'] ←こいつ何?
UI 側のダークモード対応
Figma の UI コンポーネントを使いたい
localStorage はなさそう
ところでどうやって線を書こう?
プラグインを作る
線を書く
矢印を書く
UI とプラグインでやり取りするメッセージ
UI 部分
公開
リリースビルドする
二段階認証を有効にする
公開に必要なもの
審査通った
まとめ
メモ
おわりに
どうもこんばんわ。
届きました。こちら
Rin'ca、待望のアルバム— Peak A Soul+ (@PAS_STAFF) February 17, 2024
2ndアルバム『Piece of Rin'ca~Pleasant~』全12曲
3rdアルバム『Piece of Rin'ca~natural ~』全13曲
2月23日2枚同時リリース!https://t.co/GwkbMU2ZNhhttps://t.co/Va7oo3QbLa
収録曲は↓
宜しくお願いします。#ピースオブりんかpic.twitter.com/lgOAIwAVU3
特におすすめなのが 恋するMODE(2ndアルバム) と 青い春は君と。(3rdアルバム) です!!!
恋するMODE、ガチ名曲。ずっと聞いてられる。ついでにゲームのD.C.4もいい!!!。
あと後者もめっちゃ好きなんだけどCUFFS 系列全然CD出してくれないからこの値段ならすごく安い!!
Figmaで矢印を引くプラグイン、どれがいいんだろう?
選択した2つのアイテム?間を矢印で引いて欲しいんだけどいまいちどれが良いのか分からないのでもういっそのこと作るかになってる。
2つ図形を選んで、その間を矢印で結んでくれます。
ちゃんと右左折が必要な場合は曲がってくれます(複雑じゃなければ)
今回はこの話です。
どぞー
デスクトップ版Figmaを入れるだけでいいらしい(無料ユーザーでも作れるぽい)。
そしてTypeScriptで作れるらしい。よかった。
ユーザーの入力を受け付けるUIの部分と、実際にFigmaのキャンバス?で図形書いたりする部分はコードレベルで分かれているらしい。(ui.html、code.js)UIの部分は<iframe>で読み込まれるらしい。そしてブラウザ用のAPIも叩けるって!
(Webブラウザの技術、localStorageとか<input type="file">、fetch()も使えるのかな?)
(localStorgeは使えんかった)
UI側じゃない、Figma側の方はブラウザではないJavaScript実行環境らしいので、JavaScriptの言語機能は使えるけど、ブラウザ由来の機能は使えないとのこと。ちなみに、使える言語機能はES6までです。
Electronのレンダラープロセス、メインプロセスの関係に似てますね。今のElectron分からんけど;;How Plugins Run | Developer Docs
Figma plugins are written using primarily JavaScript and HTML. The environment exposed to plugins by the Figma editor, FigJam, Figma Slides, and Figma Buzz is very similar to a standard web browser and includes many of the same features. There are, however, some important differences.
https://developers.figma.com/docs/plugins/how-plugins-run/
せっかくなので、UI部分はhtml / css直書きよりはReactとかTailwind CSSを使いたいところですが、、、
どうやらui.html以外のファイルを渡すことが出来ないらしい。Reactは複数の<script>からなるし、CSSもどっかに出てくるので、どうにかして1つのHTMLに全てのJSとCSSとHTMLを詰め込まないといけない。
というか、Reactの例とesbuild (Vite?)の例がありました。今回はこれに乗っかります。
plugin-samples/webpack-react at main · figma/plugin-samples
🔌 Sample Figma plugins. Contribute to figma/plugin-samples development by creating an account on GitHub.
https://github.com/figma/plugin-samples/tree/main/webpack-react
create-react-appのようにWebpackで良い感じにやるplugin-samples/esbuild-react at main · figma/plugin-samples
🔌 Sample Figma plugins. Contribute to figma/plugin-samples development by creating an account on GitHub.
https://github.com/figma/plugin-samples/tree/main/esbuild-react
Next.js (や他のフレームワーク)がオーバースペックすぎる!Reactだけよこせな構成で使われるViteのサンプルもあるあとあんまり関係ないけどなんかとてもわかりやすく説明してる気がする。なんだこれ?
ご丁寧にGIF画像つかってコマンドラインの操作方法とか書いてる。でもやってることは難しそう。
矢印が引ける、Figma Plugin作ります。
あ、今回はFigma プラグイン開発には必須ではないReact、Vite、esbuild、Tailwind CSSとかを使うので、最小限の例が見たければ他行ったほうが良いと思います。
必要なものは、Figma デスクトップアプリ、VSCode(テキストエディタなら何でも良い)、Node.jsです。
| なまえ | あたい |
|---|---|
| OS | Windows 10 Pro |
| Node.js | v20.9.0 |
こちら、私はWindows版をいれます。秒でインストールが終わりました。。。UACとか求められなかったけどどういう事なの?
なにか適当なプロジェクトを開いて(なければ作ります)
↓ デザインの方を押す

次に、左上のロゴを押して、プラグイン→開発→プラグインの新規作成を押します。
名前は適当につけて、今回はFigmaのデザインの方だけで動けばいいので、デザインの方を選びます。
矢印を作るプラグインを作るわけですが、矢印の設定とかをするための画面が必要なので、カスタムUIを選びます。
あとは保存先を尋ねてくるので、適当に選びます。
これで最小限のプラグインのコードが出来たらしいです。
完了を押すとプラグインにありました!
保存先をVSCodeで開きます。
ファイルの中身はこうなってるでしょうか?
Node.jsを使ったことがあれば気付くかもしれませんが、node_modulesとか言うのがいませんね。
というわけでnpm iします。
まあコマンドプロンプトとかGitBashでも何でも良いんですが、VSCodeから起動できるのでもうそれで、ターミナルをVSCodeで開きます。Windows以外はしらんけど多分おんなじ感じだと思う。
そこでnpm iを打ち込んでエンターです。
ながい。gradleのそれと違ってライブラリはプロジェクト毎にダウンロードするので長いです。
これで依存関係もおっけー
Gitを使いたい場合は。git initコマンドを叩いてね。
コミットとかしたい場合は。とりあえず動かしたければ要らないね。
gitignoreがすでにあるので便利ですね。
git initNext.jsとかはこのWebpackとかのバンドラーの設定をいい感じにやってくれてたから。。。いざ自分がやろうとするときついな。
雰囲気でesbuildサンプルとにらめっこしてみる。
ガチでフロントエンド何もわからない。
型付きでおなじみTypeScriptのコードはブラウザでは動かせないんですね。ブラウザはJavaScriptしか分からないので。
なので、TypeScriptをJavaScriptに変換しないといけないのですが、これはesbuildがやってくれるらしい。
あ、今更ですがTypeScriptはJavaScriptに変換される都合上、お硬い言語にあるinstanceofとかはありません。
型情報はJavaScriptに変換する際に消え去るので、実行時にクラスを判別とかは出来ないです。
また、ReactのJSX / TSXもJavaScriptに直さないといけないのですが、これもJavaScriptにしないといけません。
これもesbuildがやってくれるらしい。
その他、ライブラリのコードを自分の書いたコードといっしょに吐き出して本番で動かせる(node_modules無しで起動)ようにする機能、
古いJavaScript実行環境でも(Figmaのプラグイン(UIじゃない方)はES6+までの言語機能はサポート)新しい言語構文を使えるように、古くても動くように書き直す機能とかもesbuildがやるらしい。
これらはesbuild以外のWebpackとかも同じことをやるらしい。
Viteは何?
ありざいす

Vite を使う理由
次世代フロントエンドツール
https://vite.dev/
どうやら、esbuildには開発サーバー機能がないらしい?。Reactとかのフロント開発では、開発サーバーを立ち上げて快適ホットリロードのありがたみを感じつつ開発をすると思いますがないらしい。これがないといちいちビルドし直さないといけない?
→ というより、Figma プラグインはUIに必要なJS / HTML / CSSを一つのhtmlにしないといけないので、ホットリロードよりもこのためかも。
そのためにViteを使ってるとかなんですかね?もうよくわからない。
どうやら、UI部分の開発にはVite、Figma上で動く方はesbuildにやらせているそうです。
"build": "npm run build:ui && npm run build:main -- --minify",
"build:main": "esbuild plugin-src/code.ts --bundle --outfile=dist/code.js",
"build:ui": "npx vite build --minify esbuild --emptyOutDir=false",
"build:watch": "concurrently -n widget,iframe \"npm run build:main -- --watch\" \"npm run build:ui -- --watch\"",てなわけで普通にReactを使ったWebサイトを作りたければ、すぐに使えるNext.jsとかを選ぼうねってReactの人が言ってる。Figma プラグイン開発でReact使いたければ地道にセットアップするしか無いと思いますが。。。
ViteじゃなくてWebpackでも良いはずなんだけど、WebpackはNext.jsで使ったことあるので今回はViteにしてみる。
Reactのコンポーネント置き場ようにsrcみたいなのを置いておくべきかなと思ったので。src-uiとsrc-pluginを作りました。src-uiにはReactとかのUI 関連を、src-pluginにはUIじゃないFigma上で動く方を。
src-pluginの方には早速code.tsを移動させました。
また、code.jsと、ui.htmlは要らなくなるので消します。消すのはcode.jsの方で、code.tsの方はsrc-pluginに移動させてください。
tsconfig.jsonも消しちゃいましょう。src-pluginフォルダ内にtsconfig.jsonを追加します。削除せずとも移動させるでも良かったんですが。中身はこんな感じ。plugin-samples/esbuild-react/plugin-src/tsconfig.json at main · figma/plugin-samples
🔌 Sample Figma plugins. Contribute to figma/plugin-samples development by creating an account on GitHub.
https://github.com/figma/plugin-samples/blob/main/esbuild-react/plugin-src/tsconfig.json
{
"compilerOptions": {
"target": "es6",
"lib": ["es6"],
"strict": true,
"typeRoots": ["../node_modules/@figma"]
}
}最後、変更した都合上、パスが変わってしまったので、manifest.jsonを変更します。
変更点は、mainの"code.js"が"dist/code.js"に。uiの"ui.html"が"dist/index.html"になります。
{
"name": "yajirushi-mode",
"id": "1344710416431362546",
"api": "1.0.0",
"main": "dist/code.js",
"capabilities": [],
"enableProposedApi": false,
"editorType": [
"figma"
],
"ui": "dist/index.html",
"networkAccess": {
"allowedDomains": [
"none"
]
},
"documentAccess": "dynamic-page"
}ここまでのファイル構成と、manifest.jsonです。
まずは簡単そうな、Figma上で動く方を(UIじゃない方)。VSCodeのターミナルへ戻り、esbuildライブラリを追加します。
開発時しか使わない(Reactみたいにブラウザ側では使わない)ので--save-devですね。
npm install --save-exact --save-dev esbuildひとまずこれで、次にVite + React + Tailwind CSSでUI側いきます。
Viteを入れて、Reactも使えるようにします。
・・・が、npx create以外の方法が書いてないのかな?npm install viteの方法で地道にセットアップしたいんやが?
というわけで手探りでやってみる。サンプルをみると、vite /vite-plugin-singlefile / plugin-react-refresh の3つを入れているのでまずは入れてみる。
plugin-react-refreshが非推奨になってしまったので、@vitejs/plugin-reactの方を入れます。
npm install --save-dev vite vite-plugin-singlefile @vitejs/plugin-react次に、Reactを入れます。--save-devは付けません。
npm install react react-domTypeScriptなので型定義ファイルも入れます。
npm install --save @types/react @types/react-domviteの設定ファイルを作ります。vite.config.tsをsrc-uiがあるフォルダと同じところに作成して、サンプルを参考にしながら(というかほぼコピペ)こんな感じ。plugin-samples/esbuild-react/vite.config.ts at main · figma/plugin-samples
🔌 Sample Figma plugins. Contribute to figma/plugin-samples development by creating an account on GitHub.
https://github.com/figma/plugin-samples/blob/main/esbuild-react/vite.config.ts
多分パスを./src-uiにすればいいはず。
import { defineConfig } from "vite";
import react from '@vitejs/plugin-react'
import { viteSingleFile } from "vite-plugin-singlefile";
// https://vitejs.dev/config/
export default defineConfig({
root: "./src-ui", // UI のコンポーネントとかがあるパス
plugins: [react(), viteSingleFile()],
build: {
target: "esnext",
assetsInlineLimit: 100000000,
chunkSizeWarningLimit: 100000000,
cssCodeSplit: false,
outDir: "../dist",
rollupOptions: {
output: {
inlineDynamicImports: true,
},
},
},
});現時点のファイル構成
Figmaの方はesbuildでJavaScriptに、Reactで作るUIの方はViteでJavaScriptにできるようにします。package.jsonを開き、scriptsの部分を変更します。scripts以降は変更ないです。
変更点はscripts内の、build、build:plugin、build:uiコマンドの追加です。
buildコマンド
pluginとuiのビルドをやるbuild:pluginesbuildを使い、code.tsをJavaScriptにしてdistに入れるように。
--target=es2015の部分。
optional chainingがES6だと使えないJavaScriptに入れてねって。build:uiviteを使ってvite.config.tsを元にJavaScriptにしたのちdistに入れてねってしてるらしい。{
"name": "yajirushi-mode",
"version": "1.0.0",
"description": "自分のFigmaプラグイン",
"main": "code.js",
"scripts": {
"lint": "eslint --ext .ts,.tsx --ignore-pattern node_modules .",
"lint:fix": "eslint --ext .ts,.tsx --ignore-pattern node_modules --fix .",
"build": "npm run build:ui && npm run build:plugin -- --minify",
"build:plugin": "esbuild src-plugin/code.ts --bundle --target=es2015 --outfile=dist/code.js",
"build:ui": "npx vite build --minify esbuild --emptyOutDir=false"
},消してしまったui.htmlをReactで再現させましょう。code.tsの方はそのままなので、ui.htmlの画面をReactで作って、ui.htmlでやっていたJavaScriptを書けば良いはず。
src-uiにApp.tsxって名前でファイルを作り、以下のtsxを貼り付けてね。
import { useState } from 'react'
function App() {
const [count, setCount] = useState(5)
return (
<>
<h2>Rectangle Creator</h2>
<p>
Count:
<input
onChange={(ev) => setCount(Number(ev.target.value))}
value={count} />
</p>
<button
onClick={() => {
parent.postMessage({ pluginMessage: { type: 'create-rectangles', count } }, '*')
}}
>
Create
</button>
<button
onClick={() => {
parent.postMessage({ pluginMessage: { type: 'cancel' } }, '*')
}}
>
Cancel
</button>
</>
)
}
export default App次に、同じフォルダへmain.tsxを作り、App()コンポーネントを呼び出します。
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
)最後に、また同じフォルダにindex.htmlを作り、以下をコピペします。Reactを呼び出すやつですね。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>やじるしモード</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>src-plugin/にはtsconfig.jsonがありますが、src-ui/にはtsconfig.jsonが無いからですね。src-uiフォルダ内にtsconfig.jsonを追加し、以下コピペ。これもサンプル通りです。。。plugin-samples/esbuild-react/ui-src/tsconfig.json at main · figma/plugin-samples
🔌 Sample Figma plugins. Contribute to figma/plugin-samples development by creating an account on GitHub.
https://github.com/figma/plugin-samples/blob/main/esbuild-react/ui-src/tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
}
}あと、vite-env.d.tsファイルを置くのが、Vite + Reactアプリのお作法?らしいので置いておきます。src-ui内にvite-env.d.tsファイルを作って、以下コピペ。
/// <reference types="vite/client" />npm run buildをターミナルで叩くことで、UI側とプラグイン側のJavaScript吐き出しが行われます。
distフォルダが出来て、code.jsとindex.htmlがあれば成功!!!
おっめでと~~~~🎉🎉🎉
まだ設定が終わったところなんですけどね初見さん。あとホットリロードとかはscriptsで書いてないので無いです。
Figmaのデスクトップアプリを開いて、作ってるやつを押してみれば良いはず。
はえ~最初に書いてあったui.htmlはこんな姿だったんですね~
(Reactで書くため速攻で消したので知らなかった)
ボタンを押してみる。えいっ
オレンジの四角形が5個並びました!おお~
とりあえずesbuildでFigma プラグイン側、ViteでFigma UI側両方がちゃんと設定されてうまく動いていそうです。
よかったよかった。
esbuildはTypeScriptの型が合っているかまでは見てくれないので、プロパティが足りないとか、型があってないとかのエラーがあってもトランスパイルされちゃいます。VSCode上でも見れますが、開いてないと分からないので型チェックするようにしましょう。
package.jsonを開いて、tscコマンドを追加します。scriptsに1個追加です。tscコマンドを足しました。src-pluginとsrc-uiの中にあるTypeScriptコードで型があっているかのチェックができるようになりました。
"scripts": {
"lint": "eslint --ext .ts,.tsx --ignore-pattern node_modules .",
"lint:fix": "eslint --ext .ts,.tsx --ignore-pattern node_modules --fix .",
"tsc": "tsc --noEmit -p src-plugin && tsc --noEmit -p src-ui",
"build": "npm run build:ui && npm run build:plugin -- --minify",
"build:plugin": "esbuild src-plugin/code.ts --bundle --target=es2015 --outfile=dist/code.js",
"build:ui": "npx vite build --minify esbuild --emptyOutDir=false"
},あ、要らなければ別にいいです。私は欲しいので...
Reactで書けるようになった!!でもCSS書きたくない。
というわけでTailwind CSSを入れます。Vite環境下での導入方法がちゃんとあります!
Tailwind CSSを入れて。
npm install -D tailwindcss postcss autoprefixerTailwind CSSの構成ファイルを以下のコマンドで生成します。tailwind.config.jsとpostcss.config.jsがでてくるはず。
npx tailwindcss init -pできたら、tailwind.config.jsを開いて書き換えます。Tailwind CSSのユーティリティ名の走査対象ファイルをsrc-uiにします。
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src-ui/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}次に、src-uiにApp.cssを追加します。
中身はこんな感じ。
@tailwind base;
@tailwind components;
@tailwind utilities;そして最後、App.tsxを開き、App.cssをimportします。
ついでに、味気ないのでApp.tsxをTailwind CSSでいい感じに見た目を揃えておきます。
import { useState } from 'react'
import "./App.css"
function App() {
const [count, setCount] = useState(5)
return (
<div className='flex flex-col space-y-2 items-center'>
<h2 className='text-3xl'>Rectangle Creator</h2>
<p>
Count:
<input
className='border-black border-b-2 ml-2'
onChange={(ev) => setCount(Number(ev.target.value))}
value={count} />
</p>
<button
className='rounded-md border-blue-300 border-2 px-4'
onClick={() => {
parent.postMessage({ pluginMessage: { type: 'create-rectangles', count } }, '*')
}}
>
Create
</button>
<button
className='rounded-md border-red-300 border-2 px-4'
onClick={() => {
parent.postMessage({ pluginMessage: { type: 'cancel' } }, '*')
}}
>
Cancel
</button>
</div>
)
}
export default Appセンスが無いのであれですが、とりあえずTailwind CSSのセットアップも出来ました。
本題の矢印を書く前に、手始めに四角形じゃなくて矢印を出せるようにしてみましょう。
サンプルコードではcreateRect()してますが、これをcreateLine()にすれば棒が出てくるようになります。
また、strokesで線の色、strokeCapで矢印を出せるようです。
// This plugin will open a window to prompt the user to enter a number, and
// it will then create that many rectangles on the screen.
// This file holds the main code for plugins. Code in this file has access to
// the *figma document* via the figma global object.
// You can access browser APIs in the <script> tag inside "ui.html" which has a
// full browser environment (See https://www.figma.com/plugin-docs/how-plugins-run).
// This shows the HTML page in "index.html".
figma.showUI(__html__);
// Calls to "parent.postMessage" from within the HTML page will trigger this
// callback. The callback will be passed the "pluginMessage" property of the
// posted message.
figma.ui.onmessage = (msg: {type: string, count: number}) => {
// One way of distinguishing between different types of messages sent from
// your HTML page is to use an object with a "type" property like this.
if (msg.type === 'create-rectangles') {
const nodes: SceneNode[] = [];
for (let i = 0; i < msg.count; i++) {
const line = figma.createLine();
line.x = i * 150;
line.strokes = [{ type: 'SOLID', color: { r: 1, g: 0, b: 0 } }]
line.strokeCap = 'ARROW_LINES'
figma.currentPage.appendChild(line);
nodes.push(line);
}
figma.currentPage.selection = nodes;
figma.viewport.scrollAndZoomIntoView(nodes);
}
// Make sure to close the plugin when you're done. Otherwise the plugin will
// keep running, which shows the cancel button at the bottom of the screen.
figma.closePlugin();
};こんな感じ。
なるほど。。。
Figmaは上に向けてマイナスになる。(WebGL のそれと違うのか...)
右向かってプラスは他と変わらんかも。
ここのコンソールを表示/非表示を選ぶことで、見慣れた画面が出てきます。consoleタブに移動すれば、console.log()の内容が出力されます。これはUI側(React)もFigma で動く側(code.ts)もここに出てきます。
code.tsでこんな感じに書けば、、、取れます。
選択中アイテムを配列で返してくれます。
// 2つのアイテム(Node)を選択したかどうか
figma.on("selectionchange", () => {
console.log(figma.currentPage.selection)
})注意点ですが、selectionの配列の順番は決まっていません。
これは、2個選択した際に、0番目が最初に選択したノードになるかもしれないし、2回目に選択したノードになるかもしれないということです。
strokeCap = 'ARROW_LINES'すれば矢印が引けることがわかりました、、、が、
別に両方矢印は要らない。片方ついてたらそれでいい。
というわけで調査してみた。Figmaで矢印を引いてNodeをconsole.logして色々見てみた。
結果、あれは線(createLine())ではなく、ベクターで出来てて(createVector())、VectorNetworkで、ストロークに矢印をつける(?)ようにすればいいらしい。
// Figma の矢印は LineNode じゃなくて VectorNode で出来てる
// SVG で線を書く必要がある
// M 0 0 L 900 0
// https://www.figma.com/plugin-docs/api/properties/VectorPath-data/
const lineVector: VectorNode = figma.createVector()
lineVector.strokeWeight = 5
lineVector.cornerRadius = 20
// 矢印を追加するためには、VectorPath ではなく、VectorNetwork を使って、最後(or 最初)のストロークに矢印をつける必要があるらしい。
// が、SVG の data を VectorNetwork にするのは面倒なので、
// vectorPaths に入れたあとに出てくる、vectorNetwork をディープコピーして矢印をつけることにする
lineVector.vectorPaths = [{
windingRule: 'NONE',
data: `M 0 0 L 900 0`
}]
// VectorNetwork を使ってストロークに矢印をつける
const vertices: VectorVertex[] = lineVector.vectorNetwork.vertices
.map((stroke, index) => {
if (index === lineVector.vectorNetwork.vertices.length - 1) {
// 終了側につける
return { ...stroke, strokeCap: 'ARROW_LINES' }
} else {
return stroke
}
})
// VectorNetwork をセットする
lineVector.setVectorNetworkAsync({
...lineVector.vectorNetwork,
vertices: vertices
})
figma.currentPage.appendChild(lineVector)vectorPathsした後に、またsetVectorNetworkAsyncしてて何がしたいんだって話ですが、SVGのパスを書くのが一番速く、簡単なのですが、矢印をストロークに付けたい場合は、VectorNetworkオブジェクト内のverticesに入ってるストロークを変化させる必要がある、、、が、VectorNetworkオブジェクトを作るのが多分とてもつらいので、SVGのパスをvectorPathsで書いてから、vectorNetworkプロパティに反映されたオブジェクトから最後のストロークだけ変化させて、setVectorNetworkAsyncで反映させる。
が一番いいのかなと思いました。
たまにこの、numberとPluginAPI['mixed']のunionで定義されているプロパティーがあります。
で、このPluginAPI['mixed']はJavaScriptのSymbolらしい、、、Symbol、はて何なんだ?
interface CornerMixin {
cornerRadius: number | PluginAPI['mixed']
cornerSmoothing: number
}というわけで見てみたけど、どうやら表現できない値の時にnumberではなくPluginAPI['mixed']を入れているらしい。symbolの言語機能を使っているとかではなく、ただ表現できない時にsymbolを入れてるだけだった。symbol使ったことないから助かる(?)。
だからunionなんですね、で、その表現できない値が何?
ってわけなんですが、どうやら角を丸くするやつとかは、右上だけ丸くする。など部分的に丸めたい時、1つのプロパティでは表現出来ないため、
代わりになる別のプロパティに値を入れて、元のプロパティにはPluginAPI['mixed']で表現出来ないよって表しているらしい。
// 四角形で、角丸の場合
if (rectangle.type === 'RECTANGLE') {
if (rectangle.cornerRadius === figma.mixed) {
// 一つのプロパティでは表現出来ない
// 代わりにそれぞれの角丸プロパティを参照する必要がある
console.log(rectangle.topLeftRadius)
console.log(rectangle.bottomRightRadius)
} else {
// 一つのプロパティで表現できる。あと型推論されて number になります
const cornerRadius: number = rectangle.cornerRadius
console.log(cornerRadius)
}
}背景勝手に暗くなるけどFigmaが既に用意してくれてるやつだしそれ使ったほうが良さそう(?)
この辺見て、
このサイト知ったのが作ったあとなので、私は使ってない!(頑張ってTailwind CSSで見た目整えた)
気が向いたらやるかも。もっと早く言って欲しかった
使えないっぽい。
代わりに、Figma プラグイン側にfigma.clientStorageっていう、Key-Valueで設定とか保存できるlocalStorageみたいなやつがいるので、それを使えば良さそう。UIから保存したい場合は、プラグイン側へメッセージを投げて、保存して貰う必要があります。
環境構築とFigma Plugin APIちょろっといじって気付いた。
どうやって線を書こう。というか、曲がった線なんて引けなくない?
createLine()の場合は、多分真っ直ぐにしか引けず、しかも傾けるとかは厳しそう雰囲気。
てなわけで調べた。SVGのパスが使えるらしい。
createVector | Developer Docs
Creates a new, empty vector network with no vertices.
https://developers.figma.com/docs/plugins/api/properties/figma-createvector/
figma.createVector()とか言うので、VectorNodeが作成できる。SVGで線がかけるやつらしく、例えばこんな感じなSVGのパスを書くと。。。const lineVector = figma.createVector()
lineVector.strokeWeight = 5
lineVector.vectorPaths = [{
windingRule: 'NONE',
data: `M 5501 -9064 L 5829 -8772 L 5829 -8772`
}]
figma.currentPage.appendChild(lineVector)線が引ける。
これをいい感じにすれば良さそうね。
ちなみに、このSVGのパス(M 5501 -9064 L 5829 -8772 L 5829 -8772)は何を表しているかと言うと、1行毎に分解するとわかりやすいかも。
M 5501 -9064 // M は Move。つまり移動。 X=5501 Y=-9064 に移動
L 5829 -8772 // L は Line。線が引ける。 X=5829 Y=-8772 まで線を引く
L 5829 -8772 // これも同様。X=5829 Y=-8772 まで線を引く最初と最後だけがあれば良いわけではなく、2つ以上Lが無いといけない?
なんか中間点ないと矢印引けないとかだっけ?
もうつかれたので、ここからは端折ります。
愚直に線を伸ばして当たるかどうか試してるだけです。
U字で線が書けるか、一回折れ曲がるだけで書けるかなどを試してうまく行けば線を書いてる。
開始点、曲がる点、曲がる点、終了点の座標を入れた配列を返しています。[ {x: 0, y: 0}, {x: 0, y: 0}, {x: 0, y: 0} ... ]
具体的にはこの辺のコード
線を書くための点をもらったら、そのとおりにSVGを書きます。
書いたら、VectorNetworkを取得して、ディープコピーした後、最初と最後の線を矢印で装飾します。
この辺です。
何となく共通化しといたほうがいいかなと思ってこの辺に。JSON.stringifyを使って文字列にした後、Figma プラグイン側にメッセージを送るため、シリアライズできる必要があります。
編集画面の各編集項目はコンポーネントに切り出してます。
面倒なので再レンダリングとかはまじで意識してないです、、、
そう言えば編集画面はかなり見通しが悪くなっちゃったので、カスタムフックに全部切り出しました。
といっても、位置と、UIで入力したパラメーターくらいしか渡していなく、線をどこまで書けばいいか等は全部プラグイン側なので、、、
yajirushi-mode/src-ui/hooks/useArrowSetting.ts at master · takusan23/yajirushi-mode
Contribute to takusan23/yajirushi-mode development by creating an account on GitHub.
https://github.com/takusan23/yajirushi-mode/blob/master/src-ui/hooks/useArrowSetting.ts
以下を参考に
BYFP: Publishing to the Community
We're exploring other ways of learning and exploring Figma. This article is a written version of our Build Your First Plugin: Publishing to the Community video tutorial! Welcome to part five of th...
https://help.figma.com/hc/en-us/articles/4407531267607-BYFP-Publishing-to-the-Community
Publish plugins to the Figma Community
Before you start Who can use this feature Supported on any plan You must be an approved creator to publish paid plugins to the Community. Learn more about selling resources on Community. Yo...
https://help.figma.com/hc/en-us/articles/360042293394-Publish-plugins-to-the-Figma-Community
プラグイン一覧を開くと、開発中のも表示されるので、ここから公開を押す。
もしwebpackとかvite等のバンドラーが開発モードだった場合は本番にしてビルドしましょう。
Figmaアカウントを二段階認証できるようにしないとだめらしい
必要な、というか面倒なのは以下ですね。
1920x1080)128x128)説明とかは、まあ一応それっぽい英語と日本語で書いておきました。
連絡先とか、誰かと一緒に作った場合はここで追加できます。
次にプライバシー?の質問があるけど、これはスキップできるらしい。
サーバーにデータ送るか、ログイン機能があるか、インターネット経由でアセット(Webフォントとか)ダウンロードするか等。
今回作ったプラグインはインターネット切り離しても動くと思う(必要なものは全てバンドルした)からほぼNoだと思う。
これで公開できます。
公開ボタンを押しましょう。
できた
アプリストアみたいに、審査があるらしい。わくてか
なんかプライバシーについての質問に答えると、ご協力ありがとうねって言ってくれます。
はやい。その日のうちに通ってない?
審査結果はメールで貰えます。
Figmaの座標系は上に向けてマイナスになるUI側をHTML / CSS / JavaScriptで書いて、プラグイン側をTypeScript (JS)で書いてもいい
esbuildとか使って余計にややこしくなったけど...esbuildがとても速い
ES6向けにビルドするよう注意ねReactやその周辺ツールは動くハズ。(Tailwind CSS、i18nextも動いた)
index.html一つにまとめる必要があるのでVite等のバンドラ設定しようUIはFigmaのコンポーネントが使えるかもしれないcode.jsとuiのindex.htmlは監視してる?
npm run buildした後にFigma デスクトップアプリに戻ると、プラグインが再読み込みされてるError: Syntax error on line 1: Unexpected token .optional chainingを使ったらエラーで進まなくなった。
dataOrNull?.nameとかdataOrNull?.getName?.()みたいに、Nullの可能性がある場合でも?.で呼び出せるやつFigmaのプラグインで動く方は、ES6+までの言語機能しか無い
esbuildのコマンドで--target=es2015すると、?.の構文をES2015 (ES6)で動かせるようにesbuildが書き直してくれます。TypeScript力が試されている感が
Kotlinにはない概念というか、、、TypeScriptの静的解析がとても賢いなと思うmanifest.jsonに書いたり..とかではないesbuildがめちゃめちゃ速い。以上です。