受け取った引数からスケール関数をダイナミックに作成してみよう~ネストした多角形ポリゴンの作成を例に~
こんにちわ。nap5です。
今回は小ネタですが、受け取った引数からスケール関数をダイナミックに作成するやり方の一つを紹介したいと思います。
使用するライブラリは以下です。
以前にも扱ったネストした多角形ポリゴンの作成をユースケースとしてスケール関数の作成にチャレンジしたいと思います。
以下が、受け取った引数からスケール関数をダイナミックに作成するコード
になります。
入力ドメインは-1から1までを受け取り、出力レンジは受け取った引数をもとに定義しています。
こうすることで、ネスト数が1段上がるたびにサイズをダウンスケールさせたり、アップスケールさせたりすることが可能になります。
import * as d3 from "d3";
const createScaler = ({ width }) => {
return d3
.scaleLinear()
.domain([-1, 1])
.range([-width / 2, width / 2]);
};
このスケール関数をネストした多角形ポリゴンの作成に落とし込んだコードが以下になります。
import * as d3 from "d3";
import { samples } from "culori";
import { degreesToRadians } from "popmotion";
import BABYLON from "babylonjs";
const { Scalar } = BABYLON;
const generateRadList = ({ edgeCount, rotationAngleOffset }) => {
rotationAngleOffset = Scalar.NormalizeRadians(
degreesToRadians(rotationAngleOffset)
);
return d3.range(edgeCount).map((num) => {
return (num / edgeCount) * (2 * Math.PI) + rotationAngleOffset;
});
};
const createPolygon = ({ edgeCount, scaler, rotationAngleOffset }) => {
const resultList = [];
const radList = generateRadList({ edgeCount, rotationAngleOffset });
let path = `M${scaler(Math.cos(radList[0]))},${scaler(Math.sin(radList[0]))}`;
radList.slice(1).forEach((item) => {
path = path + `L${scaler(Math.cos(item))},${scaler(Math.sin(item))}`;
});
path = path + `Z`;
return path;
};
const createScaler = ({ width }) => {
return d3
.scaleLinear()
.domain([-1, 1])
.range([-width / 2, width / 2]);
};
const createNestPolygon = ({
width,
edgeCount,
nestCount,
rotationAngleOffset,
}) => {
const widthInfoList = samples(nestCount + 1)
.slice(1)
.map((t) => {
return { t, w: width * t };
});
let resultPath = ``;
for (let index = 0; index < widthInfoList.length; index++) {
const widthInfo = widthInfoList[index];
resultPath =
resultPath +
createPolygon({
edgeCount,
scaler: createScaler({ width: widthInfo.w }),
rotationAngleOffset,
});
}
return resultPath;
};
const result = createNestPolygon({
edgeCount: 3,
nestCount: 3,
width: 2,
rotationAngleOffset: 60,
});
console.log(result);
このプログラムの実行結果は以下になります。
$ time node index.js
M0.16666666666666669,0.2886751345948128L-0.3333333333333333,5.551115123125783e-17L0.16666666666666646,-0.28867513459481303ZM0.33333333333333337,0.5773502691896256L-0.6666666666666666,1.1102230246251565e-16L0.3333333333333329,-0.5773502691896261ZM0.5,0.8660254037844386L-1,2.220446049250313e-16L0.49999999999999933,-0.866025403784439Z
real 0m1.266s
user 0m1.477s
sys 0m0.133s
出力されたsvgのパスコマンドをsvg-path-editorに張り付けてみます。
ファイルにも保存し、添付しましたので、ダウンロード後、ブラウザにドラッグアンドドロップすると見れると思います。
最近では、Twitterでモックアップ動画を公開しているので、こちらもよかったら、覗いてみてください。
最後に、Udemyでコースを公開しました。
良かったら覗いてみてください。
また、コースの内容紹介記事は以下になります。
簡単ですが、以上です。
この記事が気に入ったらサポートをしてみませんか?