/ChickenPaint_Be

お絵かき掲示板Petit NoteのためのBootstrap5対応のChickenPaint

Primary LanguageJavaScriptGNU General Public License v3.0GPL-3.0

ChickenPaint Be

「ChickenPaint」は、Nicholas Sherlock氏が開発したペイントソフトです。

thenickdude/chickenpaint: An HTML5 Port of the ChibiPaint multi-layer Oekaki painting tool

そして、このリポジトリにあるのは、その「ChickenPaint」を改造したものです。
IEのサポートが完全に終了したため、互換性のための古いJavaScriptが必要なくなりました。
そして、古い非推奨のJavaScriptを推奨されるものに置き換える作業が必要になりました。
その作業の過程で、キーボードインベントの処理の書き直しを行いました。
しかし、Bootstrap4にも非推奨になったキーボードイベントのコードが残っていました。
Bootstrap4のコードを含む「ChickenPaint」のビルドを行ったあと手作業で該当箇所を置換してGoogleのクロージャーコンパイラーでminifyするとても無駄な作業が発生しました。
これらの問題を解決するためBootstrap5対応版を作りました。
改造したバージョンの「ChickenPaint」の名称は「ChickenPaint Be」です。
追加された機能と廃止された機能があり、またこの改造版に固有の問題が存在する可能性もあるため名称を変更しました。

noteにも、概要をまとめましたのでご一読いただければ幸いです。

ChickenPaintを改良したChickenPaint Beの新機能|さとぴあ

Bootstrap4にXSSの脆弱性

2024年7月、Bootstrap 4.0.0 - 4.6.2 にXSSの脆弱性がある事が明らかになりました。
Bootstrap4はサポートが終了しているため、セキュリティパッチが提供される事はありません。
つまり、Bootstrap5に移行する必要があるという事です。

npm audit reports moderate XSS vulnerability with bootstrap 4.6.2 · Issue #40685 · twbs/bootstrap

「ChickenPaint Be」は、Bootstrap5に移行しました。
Bootstrap5は現行サポートバージョンであるため、あらたな問題が発見されてたとしても、問題が修正される事を期待できます。

変更点

ChickenPaintのダイヤログ、ポップオーバーの日本語未翻訳箇所を翻訳して実装しました

Screen-2024-01-06_14-51-15

Screen-2024-01-06_15-15-24

変形確定前に別のレイヤーを選択、または新規レイヤーを追加しようとした時に表示されるダイヤログの動作を改良

  • 変形確定前にレイヤーを追加しようとすると変形を確定する取り消すなどの操作を促すダイヤログが表示されますが、従来の動作では、変形確定のエンターキーの押下で変形は確定されるものの、ダイヤログはすぐには消えず、レイヤーの追加も行われませんでした。
    修正後は、エンターキーによる変形の確定と同時にダイヤログは閉じられ、かつ、レイヤーも追加されます。 一連のダイヤログの日本語訳も追加しました。

描画時にも円カーソルが表示されるようになりました。

PaintBBS NEOとChickenPaintの円カーソルの表示を変更しました|さとぴあ

Petit.Note.-.Google.Chrome.2023-12-25.18-53-44.-.Trim.mp4

レイヤー2枚で起動するようになりました

image

これまでは白い背景レイヤー1枚で起動していましたが、透明なレイヤーが1枚追加されレイヤー2枚で起動するようになりました。
間違って白い背景レイヤーに線画を描く事故を減らす事ができます。

ショートカットキーの変更と拡張

ChickenPaintのショートカットキーを拡張しました|さとぴあ

  • R+左クリックでキャンバスの回転
  • Hでレイヤーの左右反転
  • Wで水彩
  • Aでエアブラシ
  • Sで薄消しゴム
  • Uでぼかしツール
  • Dで指先ツール
  • Cで混色ツール
  • SHIFT+CTRL+Eで全レイヤー結合
  • SHIFT+CTRL+Gでグループ結合
  • CTRL+Mでマスク適用
  • SHIFT+Mでマスク削除
  • CTRL+Iでネガポジ反転
  • SHIFT+左クリックでブラシサイズと不透明度のスライダーを緩やかに調整

レイヤーパレット固有のショートカットキー

レイヤーパレットの右クリックメニューが動作しなくなってしまったので、埋め合わせとして、ショートカットキーを追加しました。 以下はレイヤーマスクのサムネイルの上をクリックした時に動作するショートカットキーです。

  • shift+クリックでマスク表示/非表示切り替え(ドキュメントには記載がなかったものの元から存在していたショートカット)
  • alt+クリックでマスクの内容を表示/非表示(ドキュメントには記載がなかったものの元から存在していたショートカット)
  • ctrl+クリックでマスク適用(追加)
  • shift+crtl+クリックでマスク削除(追加)

2024_01_16_レイヤーマスクのショートカットキーを追加

レイヤーパレットにアイコンを追加

ChickenPaintのレイヤーパレットに複製iconを追加

下のレイヤーと結合アイコンを追加

  • 「下のレイヤーと結合」をペンによる操作で簡単に実現できるようにするため、レイヤーパレットに「下のレイヤーと結合」アイコンを追加しました。

グループ結合アイコンを追加

  • グループ結合アイコンを追加しました。
    通常の下のレイヤーと結合で結合するとクリッピングが解除されてしまいますが、レイヤーグループ内で下のレイヤーとクリッピングしていれば、グループ結合でレイヤーを結合しても、クリッピングが維持できます。
    また、たくさんレイヤーがある時はグループ化して閉じればレイヤーパレットの場所を取らず便利です。
    しかし、これまではグループレイヤーを結合するには右クリックメニューから選ぶか上段のメニューからグループ結合を選択する必要がありました。
    そして、レイヤーの右クリックメニュー機能を再実装できなかったので、実質上のメニューか、ショートカットキーでしか操作できなくなっていました。
    そこで、レイヤーパレットに「グループ結合」アイコンを追加しました。 1タップで、グループフォルダ内のレイヤーを結合して1つにします。
    グループフォルダを選択すると下のレイヤーと結合アイコンがグループ結合アイコンに入れ代わります。

複製アイコンを追加

  • 複製アイコンを追加しました。 これまでは、ショートカットキーを使うか、上段のメニューから複製を選択するしかありませんでした。 複製アイコンを1タップするだけでレイヤーやレイヤーグループが複製できるようになりました。

レイヤーパレットのマスクアイコンの動作を変更

  • レイヤーパレットのマスクアイコンの動作を変更しました。 選択しているレイヤーにマスクが無い時は「マスク追加」になり、マスクが存在している時は「マスク適用」に変わります。
    これによりペン操作で簡単にレイヤーマスクを適用できようになります。
    これまでの、マスクアイコンには「マスク追加」機能しかありませんでした。

操作パレットに左右反転アイコンを追加しました。

  • キーボードショートカットキー「Hでレイヤーの左右反転」に続き、アイコンも追加しました。
    これまではキーボードがないデバイスはメニューから左右反転を選択する必要がありました。
    左右反転アイコンの追加により、ワンタップで左右反転できるようになりました。

ChickenPaint Beの操作パレットに左右反転アイコンを追加|さとぴあ

ぼかしフィルタやグリッド等数値を入力する箇所は数値のみに

数値を入力する箇所は input type="number" に変更しました

  • これまでは、数値を入力する項目にアルファベットやひらがなの入力が可能でした。

グリッド設定でエンターキーを押下すると描画画面から移動してしまう問題

  • エンターキーのデフォルトの動作をキャンセルして、画面が移動しないようにしました。

Firefoxで、Altキーを押すとメニューが開閉する問題

  • Alt押下でキャンバスの色をスポイトできますが、この時にFirefoxのメニューバーが開閉する問題がありました。 Altキーのブラウザのデフォルトの動作をキャンセルしてこの問題を修正しました。

変形操作をレイヤー非表示、不透明度0%の時に行おうとした時のポップオーバーによるメッセージを追加

  • レイヤーの不透明度が0%の時や非表示の時にも、変形操作ができない理由を説明するポップオーバーが表示されるようになりました。

拡大縮小ボタン使用時の拡大縮小率の変更

  • 拡大で2倍、縮小で0.5倍だった拡縮率を拡大で 1.41倍、縮小で0.7092になるように変更しました。
    また縮小率0.7092倍時に描線がきれいに表示されないため、初期状態ではオフだったズーム時のアンチエイリアス処理を初期値でOnになるように変更しました。
    アンチエイリアスがかかると困る場合はメニューの「表示」の中にある、「ズームをなめらかに表示する」のチェックを外して使います。

テクスチャパレットにノイズテクスチャを追加

image

  • 「テクスチャパレット」に「ノイズテクスチャ」を追加しました。
    これまでも、「効果メニュー」の「単色ノイズ」とレイヤー効果でノイズをのせる事ができましたが、それとも少し違うノイズを出す事ができます。
    ペンや鉛筆と組み合わせて使う事で、より鉛筆らしい線を描写できます。
    また水彩ブラシなどの厚塗りの時にも効果を発揮します。

消しゴム使用時はテクスチャを無効化

  • 消しゴム使用時はテクスチャを無効化する処理を追加しました。
    テクスチャを選択している時にも、消しゴムで消去できるようになりました。
    これまでは、テクスチャを選択したまま消しゴムをかけると、薄くはなるものの、消す事ができませんでした。
  • 薄消しゴム使用時はテクスチャが適用されます。消しゴムを使ったテクスチャのかけ合わせによる模様の作成をする時は薄消しゴムをご利用ください。

ブラシプレビューの円をドラッグしてブラシサイズを変更する機能をペン対応に

2024-10-26-ブラシパレット

  • ブラシプレビューのプレビュー画面の円をドラッグしてブラシサイズを変更する操作がペンでもできるようになりました。
    ペンでも操作できるようにするため、マウスに最適化されていた処理をPointerEventに書き直しました。
    また、各パレットとメインメニューのtouchmoveEventのデフォルトの動作をキャンセルし、誤動作が発生しないようにしました。
    ペンが画面から離れているにもかかわらず、ドラッグしている対象が動いたままになる問題を解決しました。

モバイル端末に最適化されたUI

スマホ・タブレットの縦横の向きが変った時は自動的にパレットの配置を初期化

  • スマホの縦横の画面の切り換えの時に使いにくいパレットの位置になってしまう事がありました。
    画面の向きの変化を検出して自動的にパレットの配置を初期化する事でこの問題を解決しました。

Screenshot_20240612-222002
縦表示から
Screenshot_20240612-222022
横表示へ。

iPad Air以下の画面サイズの端末の時はパレット折りたたみ式のモバイルUIで起動

  • デバイスの幅または高さが820px以下でタッチデバイスの時は、パレット折りたたみ式のモバイル用UIで起動します。

localhost_221021_59_Petit_Note_petitnote_(iPad Mini) paintbbs sakura ne jp_oeb_cgi_petit_(iPad Mini)

600px x 600pxのキャンバスを開いた時の画面の比較。 左、旧UI。右、モバイル端末に最適化された新UI。

より安全な機密データの受け渡し

パスワード等の機密データをGETパラメータにセットして送信する事がありました。

postUrl: "./?pwd=パスワード",

これをより安全なPOSTに変更する事ができるようになりました。 投稿が完了して画面が移動する直前に、handleExit関数を実行します。
この関数でFetch APIを使ったPOSTを行えばパスワードなどの機密データをより安全に送信する事ができます。

const handleExit = ()=>{
	const formData = new FormData();
	formData.append("pwd", "パスワード"); // 画像差し換え
fetch("./", {
	method: 'POST',
	mode: 'same-origin',
	headers: {
		'X-Requested-With': 'chickenpaint'
		,
	},
	body: formData
})
.then(response => {
	if (response.ok) {
		if (response.redirected) {
			return window.location.href = response.url;
		}
		response.text().then((text) => {
			if (text.startsWith("error\n")) {
					return window.location.href = "./?mode=paintcom";
				}
		})
	}
})
.catch(error => {
	console.error('There was a problem with the fetch operation:', error);
	return window.location.href = "./?mode=paintcom";
});
}

chickenpaint.min.jsから参照可能なスコープの中でconst handleExitを宣言します。
handleExitという名前の関数が定義されていない時は、handleExitは実行されず、従来と同じ動作になります。
handleExit関数で何を行うのかは掲示板の作者が決定します。

ファイルサイズを劇的に削減

  • ビルドツールをParcelに変更しました。
    それだけで、100kb以上のファイルサイズの削減を実現できました。
    さらに、Pointer Events のポリフィルのためのPEP、Promise対応のためのcore-jsを削除しました。
    IE11は完全にサポートが終了しているため、これらのポリフィルは必要なくなりました。
    これらのポリフィルを整理した結果、ファイルサイズは、779KBから594KBになり、約23.75%の削減になりました。

依存関係を整理

  • 使用していたnpmのパッケージの多くを整理しました。
    パッケージの脆弱性によって開発の続行が困難にならないようにするためパッケージの多くを整理しました。

このバージョンにはオリジナルの「ChickenPaint」には存在しない固有の問題があるかもしれません

  • もしも動作に問題がある場合は、このリポジトリのIssueを開いてください。
  • GitHubにアカウントが無い場合は、サポート掲示板をご利用ください。
  • かなりの箇所に手を加えているため、オリジナルの「ChickenPaint」には無い固有の問題が存在している可能性があります。
  • オリジナル版の「ChickenPaint」で発生していない問題をオリジナルの「ChickenPaint」のリポジトリに問い合わせないようお願いします。

ビルド

npm iでパッケージをインストールするとmake allも実行され、resources/js/に本番環境で使用するためのchickenpaint.jschickenpaint.min.js'がビルドされます。
example/index.htmlを開くとChickenPaint Beが起動します。
再度ビルドしたい時はmake allと入力します。

テスト用の開発サーバを起動

make devでParcelの開発サーバが起動します。
ブラウザで開発サーバのURLを開くと動作確認用のChickenPaint Beが起動します。
dist/ディレクトリに開発サーバで使用するファイル一式が入ります。
dist/ディレクトリに入るのは開発サーバを使った動作確認のためのファイルです。
dist/ディレクトリ内のファイルは配布に適していません。

掲示板などで利用する本番環境用のビルドずみファイル

掲示板などで使用する時に必要になるのは、resources/ディレクトリ内のファイルだけです。

resources/ディレクトリのminifyされたchickenpaint.jschickenpaint.min.jsをご利用ください。
ビルドずみファイルを含む必要なファイル一式はリポジトリのresources/ディレクトリにあります。
ビルドされたファイルは、すべてminifyされており、chickenpaint.jschickenpaint.min.jsは同じものです。