🏆
canvasにトーナメントを書く
konvajsでcanvasに図形を描画するとき、canvasの左上を(0,0)として図形が通る点の座標や高さ、幅などを指定します。
今回はトーナメント表を書くときに「こうしたら楽だった」ということをまとめてみようと思います。
動的にデータを渡してトーナメントを生成する
座標の計算式を書く
ここからは数列の話になります。
まず、最小のブランケットの高さをB、ブランケット同士の間隔をMとします。
そうすると、2回戦のブランケットの高さAと3回戦のブランケットの高さCは
同様に4回戦のブランケットの高さDも作図するとわかるのですが、
とおけます。
ここで簡略化のために
となります。
1回戦のブランケットの横線のY座標
2回戦のブランケットの横線のY座標
3回戦のブランケットの横線のY座標
同様に、4回戦のブランケットの横線のY座標
(
お、数式書けそうですね!
x座標も同様に、横線の長さ
コードを書こう
として、太さ5pxの線を書いています。
nが偶数と奇数の場合で縦線を書く処理も要るのですが、ここでは割愛します。
import { Line } from "react-konva";
const lineBeginPointX = lineWidth * roundIdx;
const lineBeginPointY =
(1 / 2) * ((Math.pow(2, roundIdx) - 1) * BLOCK) +
Math.pow(2, roundIdx) * BLOCK * gameIdx;
...
<Line
opacity={!game.firstTeamName && !game.lastTeamName ? 0 : 1}
x={adjustX + lineBeginPointX}
y={adjustY + 10 + lineBeginPointY}
fillLinearGradientColorStops={fillColor(
progress * rounds.length - roundIdx
)}
points={[0, 0, lineWidth, 0, lineWidth, 5, 0, 5]}
closed
fillLinearGradientStartPoint={{ x: 0, y: 0 }}
fillLinearGradientEndPoint={{ x: lineWidth, y: 5 }}
width={lineWidth}
height={5}
/>
渡すデータが固定の時はわざわざ数式を立てなくてもいいかもしれませんが、意外ときれいに書けると楽しいよね!という話でした。
完成例
今回のトーナメントコンポーネントは以下のページなどで使っています。
こんなサービス作ってます
Discussion