ホエールテック株式会社 ホエールテック株式会社

  • ブログ

fabric.jsのgetScaledWidth・getScaledHeightに苦戦した話

エンジニア1年生のつなまよです。

PDFさしこむくんPDFさしこむくんライトでは、フロントエンドで、fabric.jsというライブラリを使用しています。

fabric.jsはとても高機能で便利なライブラリなのですがオブジェクトの大きさを取得する「getScaledWidth」「getScaledHeight」というメソッドの使い方に苦戦したのでまとめます。

結論

fabric.jsの【 getScaledWidth() 、getScaledHeight() 】この二つのメソッドはスケールの変更が起きていいない辺に対して使用すると+1された値が取得される。

スケールの変更が起きていない辺の座標を取得する場合は別のメソッドを使用する必要がある。

背景

ホエールテックの学習を兼ねた開発テーマであった「PDFさしこむくん」は、2023年4月の中頃から開発を開始したのですが、最初に90%完成した!と思ったのは5月末でした。
そこから機能追加や見た目の変更が要件として上がり、それらの実装が完了したのが6月頭です。

それからリリースされることとなる8月末までが長い道のりでした。
バグを修正しては新たなバグが発見され、そのバグを修正するには前回のバグの対処法(計算法)では対応できない。
その場しのぎの修正と新たなバグのいたちごっこです。

もちろん、なるべくその場しのぎではない、根本的な解決方法を選択してはいるのですが、このパターンでは対応できないというような細かな漏れが水面下で発生していました。

そして、それら1px単位の座標修正の皺寄せが集約されたのがscalingイベントです。

scalingイベントでは
・拡大縮小中のフィールドがPDFの外側に出ない制御
・フィールドの最小サイズが15px以下にならない制御
の二つを行っています。

このscalingイベント内で多く使用していたのがタイトルのgetScaledWidth/Heightメソッドです。

解決方法

scaling前のオブジェクトの各頂点の座標と幅と高さ
scalingイベント中のオブジェクトの各頂点の座標と幅と高さ
をそれぞれ取得した後、
scalingイベントで発生する計算を8つに場合分けし、さらにそれらを2つずつに分解しました。
合計すると16パターンの計算を記述しています。

8つというのはフィールドのどの方向からのイベントなのか、です。

今回の場合、上下中央からの拡大縮小は、左右の幅が変更されません。
また、左右中央からの拡大縮小は、上下の高さが変更されません。

そのため、それらの場合はgetScaledメソッドを使用せず計算します。

また、今回はなぜかキャンバスの左側と上側に1pxずつズレが発生しており、この修正を後から発生する処理を記述するメソッドに任せていたために、「上下」、「左右」をひとまとめにできず、「左上から」「左中央から」「左下から」……というように結局16パターンに分解し、それぞれ計算することで解決しました。(先輩方に、何か突っ込まれそうな雰囲気を感じますが、今回こうせざるを得なかったんです!!突っ込みは、fabric.js触ってからにしてくださいね!)

学んだこと

今回の「PDFさしこむくん」の開発では、このgetScaledメソッドによるズレ以外にも様々な困難があったのですが、総括として

・バグが発生した時は徹底的にパターンを切り分けよ
・バグの解決、究明は突き詰めるべし。あとで自分の首が締まる
・ある機能や操作をできない時はできない理由まで究明しよう

fabric.jsとの長い旅路を終えた?つなまよは、肝に銘じることとなりました。

つなまよ
つなまよ
叙情系エンジニア
2匹の犬を飼っている駆け出しエンジニア。
伊坂幸太郎、円城塔、六冬和生、志磨遼平が好き。
採用情報
お問い合わせ