Open1

Three.jsのSVGLoaderでstrokeをdepth有りのgeometryにしたい!

pontaponta

ゴール

前提

SVGで設定されているstrokepathの境界線が中央に来るように指定されたstroke-widthの幅で描画される。

目指すもの

今回は下記条件を満たすようなプログラムの作成をゴールとする。

  • strokeの外側とpathの外側が一致している。
  • strokeExtrudeGeometry等を利用して高さを変更できるようにする。

現状

SVGファイルのロード

SVGファイルをロードする際はSVGLoaderを利用している。
SVGの読み込みに成功すると、ShapePathの配列を返却する。

path

SVGファイルのpathで記述されている部分については、ShapePathで利用できるtoShapesを利用してshapeを取得することができる。
取得したshapeExtrudeGeometryに渡すことで描画している。

stroke

SVGファイルのpath内のstroke部分については、SVGLoaderpointsToStrokeを利用してBufferGeometryとして描画している。

実装方針

方針1:strokeの情報からshapeを返却するようにする

方針2:すでにレンダーできているBufferGeometryからExtrudeGeometryに変換する

方針3:pathの情報からstroke用のshapeのデータを作成する

pathで利用しているShapePathのデータはあるので、これを利用して所望のstrokeShapePathを計算する。

参考資料

Painting: Filling, Stroking and Marker Symbols — SVG 2
SVGに関する規格

SVG: スケーラブルベクターグラフィック | MDN
SVGに関するMDNのドキュメント

SVGLoader – three.js docs
Three.jsでSVGをロードする際に利用。

Extrude SVG strokes and svg loader example extrude option. by repalash · Pull Request #20796 · mrdoob/three.js
SVGLoaderにstrokeExtrudeGeometryとして出力するオプションを追加するPR。2021年5月で更新が止まっており、マージされる様子はない。

pointsToStroke: Return a shape rather than a geometry · Issue #21326 · mrdoob/three.js
pointsToStrokegeometryではなくshapeを返却する方が良いのでは?と言う提案をするIssue。

r3f svg react-spring transitions - CodeSandbox
react-three-fiberでSVGをロードしてそれぞれのpathをディレイ付きでアニメーション表示する例。

SVGLoader: Add stroke support by yomboprime · Pull Request #16077 · mrdoob/three.js
SVGのstrokeのサポートを追加するPR