Created
March 4, 2024 02:48
-
-
Save mrgarita/97822c9b1b05e40f4e268f054c43d54e to your computer and use it in GitHub Desktop.
JS:スマホの縦でも横でもキャンバスが収まるようにする
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="ja"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<!-- Google Fonts --> | |
<link rel="preconnect" href="https://fonts.googleapis.com"> | |
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap" rel="stylesheet"> | |
<!-- /Google Fonts --> | |
<title>スマホの縦でも横でもキャンバスが収まるようにする</title> | |
<style> | |
*{ | |
margin: 0; | |
padding: 0; | |
line-height: 0; /* ブラウザでキャンバスの下に隙間ができるのを防ぐ */ | |
} | |
</style> | |
<script src="main.js" type="text/javascript"></script> | |
</head> | |
<body> | |
<canvas id="canvas" width="320" height="400"></canvas> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* スマホの縦でも横でもキャンバスが収まるようにする | |
*/ | |
let canvas = null; // キャンバス(描画領域) | |
let g = null; // 描画対象 | |
let pos = {x:0, y:0}; // キャンバス上のXY座標 | |
let canvasHeightRatio; // キャンバス幅に対する高さの割合 | |
let resolutionRatio = 0; // 元キャンバスに対する表示サイズの大きさ割合 | |
// 画像オブジェクト(画像ファイルをキャンバスで利用するため) | |
let img; | |
/* | |
* タッチして指を動かしている時の処理 | |
*/ | |
const touchMoveListener = (e) => { | |
// 端末のデフォルト動作をキャンセル | |
e.preventDefault(); | |
// タッチ開始情報を取得 | |
const touches = e.touches; | |
// ページ上のオフセット位置取得 | |
const rect = e.target.getBoundingClientRect(); | |
// キャンバス上のXY座標を取得 | |
pos.x = Math.floor(touches[0].pageX/resolutionRatio - rect.left); | |
pos.y = Math.floor(touches[0].pageY/resolutionRatio - rect.top); | |
}; | |
/* | |
* キャンバスに描画する | |
*/ | |
const drawCanvas = () =>{ | |
// 背景塗りつぶし | |
g.fillStyle = "royalblue"; | |
g.fillRect(0, 0, canvas.width, canvas.height); | |
// テキスト描画 | |
g.fillStyle = "snow"; | |
const titleText = "Crime and Punishment"; | |
const textObj = g.measureText(titleText); // キャンバス文字列の情報を得る | |
g.fillText(titleText, canvas.width/2-textObj.width/2, canvas.height/4); // 画面中央にくるように配置 | |
// ●を描画 | |
g.fillStyle = "snow"; | |
g.beginPath(); | |
g.arc(pos.x, pos.y, 20, 0, Math.PI*2, false); | |
g.fill(); | |
// 画像ファイルを描画 | |
g.drawImage(img, canvas.width/2 - img.width/2, canvas.height/2 - img.height/2); | |
} | |
/* | |
* キャンバスのサイズを端末サイズに合わせて変更 | |
*/ | |
const getSize = ()=>{ | |
// 端末ウインドウ幅に対するウインドウ高さの割合を取得 | |
const windowHeightRatio = window.innerHeight / window.innerWidth; | |
// 端末のウインドウサイズからキャンバスサイズを再計算する | |
let width; | |
let height; | |
if (windowHeightRatio > canvasHeightRatio) { // 縦長状態(ポートレイト) | |
width = window.innerWidth; | |
height = window.innerWidth * (canvas.height / canvas.width); | |
} else { // 横長状態(ランドスケープ) | |
width = window.innerHeight * (canvas.width / canvas.height); | |
height = window.innerHeight; | |
} | |
// 現在の端末でキャンバスを表示する際のサイズを設定 | |
canvas.style.width = `${width}px`; | |
canvas.style.height = `${height}px`; | |
console.log(`キャンバス表示サイズ w:h = ${width}px:${height}px`); | |
// 元キャンバス(canvas.height)に対する表示サイズ(height)の大きさ割合を計算(正しいタッチ座標の取得に利用) | |
resolutionRatio = height / canvas.height; | |
console.log("resolutionRatio = " + resolutionRatio); | |
} | |
// 端末サイズが変更されたときのイベント処理 | |
window.addEventListener("resize", getSize, false); | |
/* | |
* ゲームのメイン処理 | |
*/ | |
const GameMain = () =>{ | |
drawCanvas(); | |
// フレーム再描画 | |
requestAnimationFrame(GameMain); | |
} | |
/* | |
* 起動時の処理 | |
*/ | |
window.addEventListener("load", ()=>{ | |
// キャンバス取得 | |
canvas = document.querySelector("#canvas"); | |
g = canvas.getContext("2d"); // コンテキスト:描画対象 | |
// キャンバスの幅に対する高さの割合を取得 | |
canvasHeightRatio = canvas.height / canvas.width; | |
// キャンバス文字描画設定 | |
g.font = "normal 24px Roboto"; // フォントサイズ・フォント種類 設定 | |
g.textBaseline = "top"; // テキスト描画時のベースライン | |
// タッチイベント設定 | |
canvas.addEventListener("touchmove", touchMoveListener, false); | |
// 画像ファイルを読み込む | |
img = new Image(); | |
img.src = "https://dianxnao.com/public/assets/cat.png"; | |
// 画像読み込みが完了してから開始 | |
img.addEventListener("load", ()=>{ | |
console.log("画像読み込み完了!"); | |
getSize(); // 端末サイズチェック | |
GameMain(); // ゲームループ開始 | |
}, false); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment