1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

お絵かきできるSNSを作りたい!9

Last updated at Posted at 2020-06-02

お絵かきできるSNSを作りたい後半戦、下のメニューを作っていきます。

まずはPNGで保存機能。

function saveCanvas(){
	var src1_img = new Image();
	var src2_img = new Image();
	src1_img.src = $("#canvas")[0].toDataURL();
	src1_img.addEventListener('load', function() {
		src2_img.src = $("#canvas2")[0].toDataURL();
		src2_img.addEventListener('load', function() {
			var dst_canvas = document.createElement('canvas');
			dst_canvas.width = 800;
			dst_canvas.height = 600;
			dst_canvas.getContext("2d").drawImage(src1_img, 0, 0, 800, 600);
			dst_canvas.getContext("2d").drawImage(src2_img, 0, 0, 800, 600);

			var imageType = "image/png";
			var fileName = "download.png";
			// base64エンコードされたデータを取得 「data:image/png;base64,iVBORw0k~」
			var base64 = dst_canvas.toDataURL(imageType);
			// base64データをblobに変換
			var blob = Base64toBlob(base64);
			// blobデータをa要素を使ってダウンロード
			saveBlob(blob, fileName);
		}, false);
	}, false);
}

// Base64データをBlobデータに変換
function Base64toBlob(base64){
	// カンマで分割して以下のようにデータを分ける
	// tmp[0] : データ形式(data:image/png;base64)
	// tmp[1] : base64データ(iVBORw0k~)
	var tmp = base64.split(',');
	// base64データの文字列をデコード
	var data = atob(tmp[1]);
	// tmp[0]の文字列(data:image/png;base64)からコンテンツタイプ(image/png)部分を取得
	var mime = tmp[0].split(':')[1].split(';')[0];
	//  1文字ごとにUTF-16コードを表す 0から65535 の整数を取得
	var buf = new Uint8Array(data.length);
	for (var i = 0; i < data.length; i++) {
		buf[i] = data.charCodeAt(i);
	}
	// blobデータを作成
	var blob = new Blob([buf], { type: mime });
	return blob;
}

// 画像のダウンロード
function saveBlob(blob, fileName){
	var url = (window.URL || window.webkitURL);
	// ダウンロード用のURL作成
	var dataUrl = url.createObjectURL(blob);
	// イベント作成
	var event = document.createEvent("MouseEvents");
	event.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
	// a要素を作成
	var a = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
	// ダウンロード用のURLセット
	a.href = dataUrl;
	// ファイル名セット
	a.download = fileName;
	// イベントの発火
	a.dispatchEvent(event);
}

無駄に関数が増えました。
レイヤーが2枚あるので1枚にがっちゃんこしてます。

次はフルスクリーンボタンの実装です。

var blFullscreen = true;
function doFullscreen(){
	var elem = document.getElementById("screen");
	if (blFullscreen){
		if (elem.requestFullscreen) {
		  elem.requestFullscreen();
		} else if (elem.webkitRequestFullScreen) {
		  elem.webkitRequestFullScreen();
		} else if (elem.mozRequestFullScreen) {
		  elem.mozRequestFullScreen();
		} else if (elem.msRequestFullscreen) {
		  elem.msRequestFullscreen();
		}
		blFullscreen = false;
	} else {
		if (document.webkitCancelFullScreen) {
			document.webkitCancelFullScreen();
		} else if (document.mozCancelFullScreen) {
			document.mozCancelFullScreen();
		} else if (document.msExitFullscreen) {
			document.msExitFullscreen();
		} else if(document.cancelFullScreen) {
			document.cancelFullScreen();
		} else if(document.exitFullscreen) {
			document.exitFullscreen();
		}
		blFullscreen = true;
	}
}

フルスクリーン状態の判定をJSで行おうとするとブラウザによって挙動が怪しくなり悩むくらいならとグローバルおじさんになりました。

そして、左右反転。
これがちょっと手間で、左右反転するとレイヤー1とレイヤー2のX座標も反転させています。
メインの関数は↓こちら。

var blReflect = true;
function doReflect(){
	if (blReflect){
		$("#canvas").css('transform', 'scale(-1, 1)');
		$("#canvas2").css('transform', 'scale(-1, 1)');
		blReflect = false;
	} else {
		$("#canvas").css('transform', 'scale(1, 1)');
		$("#canvas2").css('transform', 'scale(1, 1)');
		blReflect = true;
	}
}

あとは、押したとき、動かしている時、離したときに左右反転状態かを判定してX座標を左右逆になるようにしました。

		if (blReflect) {
			ox=event.clientX-event.target.getBoundingClientRect().left;
		} else {
			ox=$("#canvas").width() + (parseInt($("body").css('padding-left')) * 2) - event.clientX-event.target.getBoundingClientRect().left;
		}

今回最後は最初から書き直すの実装です。
これはページリロードでいいんじゃ・・?とも思いましたが、折角なのでちゃんと実装しました。

function doClear(){
	if(confirm('本当にいいんですね?')){
		ct.clearRect(0, 0, $("#canvas").width(), $("#canvas").height());
		ct2.clearRect(0, 0, $("#canvas2").width(), $("#canvas2").height());
	}
}

ちゃんとアラートで消すことを確認する親切設計。
レイヤー1とレイヤー2をクリアしています。

次回、Ctrl+Zをしたい。お楽しみに。

次:お絵かきできるSNSを作りたい!10
最初:お絵かきできるSNSを作りたい!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?