JavaScript-Load-Image でExifのorientation(回転方向)をもとに画像を回転させるとき、chromeだと正しくない方向に回転してしまう問題

https://github.com/blueimp/JavaScript-Load-Image/releases
https://www.fxsitecompat.dev/ja/docs/2020/jpeg-images-are-now-rotated-by-default-according-to-exif-data/
2020年5月現在、スマホで撮った写真をブラウザ表示するとき回転方向を正しく調整するためにJavaScript-Load-Imageを使って回転させる時、chromeだと正しくない方向に回転してしまう問題が発生した。
原因はおそらくchrome81、Firefox 75以降、image-orientation CSS プロパティの初期値が none から from-image に変わったこと。
対策は、最新の Load-Image を利用するように変更すること。v5.11.0を利用するようにすると問題は解決した。
ただしバージョンアップに伴い、DateTimeOriginalやGPS座標の取得方法が少々変わっていたため、調整が必要だった。
以下は単純な現象再現用html。

<!DOCTYPE html>
<html lang="ja">
<head>
<script src="./load-image.all.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
	document.querySelector("#fulImage").addEventListener("change", function(e) {
		var file = this.files[0];
		loadImage.parseMetaData(file, function(data) {
			var options = {
				canvas: true,
				orientation: data.exif.get("Orientation")
			};
			loadImage(file, function(canvas) {
				document.querySelector("#imgPhoto").src = canvas.toDataURL(file.type);
			}, options);
		});
	});
});
</script>
</head>
<body>
	<img id="imgPhoto" width="300" height="300">
	<input type="file" id="fulImage">
</body>
</html>

iOSだと、ブラウザ位置情報の取得を行うとOpenLayersでの地図表示ができなくなる問題

iOSのブラウザだと、navigator.geolocation.watchPosition()の呼び出し後にOpenLayers国土地理院地図を表示させようとしても、地図領域が真っ白(拡大・縮小アイコンは表示される)で何も表示されないという問題が起きた。
html例は以下。
原因は、このページをhttpsでアクセスする場所に置いているのに、国土地理院のurlをhttpで指定していたこと。
(位置情報取得にはhttpsアクセスが要求されるので必然的にページを配置するのはhttpsアクセスできるサーバになる)
「url: "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png"」→「url: "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png"」に変更することで、ブラウザ位置情報の取得を行っても、OpenLayersでの地図表示ができるようになった。

<!DOCTYPE html>

<html>
<head runat="server">
    <link rel="stylesheet" href="./ol.css" />
    <script src="./ol.js"></script>
</head>
<body>
    <div id="map" style="width:500px; height:500px; border:solid 1px black;"></div>
    <div id="pos"></div>

<script>
window.onload=function(){
	// 位置情報を常に変数に格納し続ける
	navigator.geolocation.watchPosition(
		function (position) {
			currentLatitude = position.coords.latitude;
			currentLongitude = position.coords.longitude;
			document.querySelector("#pos").innerText = currentLatitude + " , " + currentLongitude;
		},
		function (error) { alert("位置情報の取得に失敗しました。サイト設定で位置情報へのアクセスを許可してください。\n( " + error.message + ")"); },
		{ "enableHighAccuracy": true, "timeout": 20000, "maximumAge": 0 }
	);

	// 地図表示
	var obMap = new ol.Map({
		target: 'map',
		view: new ol.View({ maxZoom: 16 })
	});

	var obTileLayer = new ol.layer.Tile({
		source: new ol.source.XYZ({
			url: "http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png", // ●ページがhttpsでアクセスされているのに、ここがhttpなのが問題
			projection: "EPSG:3857"
		})
	});
	obMap.addLayer(obTileLayer);

	obMap.getView().setCenter(ol.proj.fromLonLat([132.7533995, 34.5698292]));
	obMap.getView().setZoom(9);
};
</script>

</body>
</html>



そうは言っても、ページをhttpsでアクセスする場所に置いた状態で国土地理院のurlをhttpで指定するだけなら、ちゃんと地図は表示されていた。
なぜ位置情報の取得をすると突然表示できなくなるのか……。

javascriptでサイズ変更した画像をinput[type='file']要素には格納できない

https://note.com/club_cloud/n/n2be6f64394f3
サイズ変更した画像など自前でjavascript生成したblobデータをinput[type='file']要素に格納することはできないっぽい。
blobデータをbase64文字列にして、input[type='hidden']要素に格納することはできる。
FormDataオブジェクトにblobデータを追加してPOST送信することもできる。
(FormData は、XMLHttpRequest.send() メソッドの引数に指定するオブジェクトなので、通常の画面サブミットでは使えない)

HTMLのinput要素にファイル(具体的にはinput[type="file"]のvalueに""以外)を設定することが出来ません。
C:/password.txtを勝手にセットする、みたいなヤバイことが出来てしまうからです。

//POSTするデータを取り出す
let fd = new FormData($('#postform').get(0))
//元のセットしてあったファイルを削除
fd.delete("file")
//スクショを載せる
fd.append("file", screenshot_file, screenshot_file.name)

みたいなコードで、直接POSTするデータに追加します。
もとのinput[type="file"]はいじってないので、Ajaxでこのformdataを送信することになります。

スマホのinputで数字キーボードを表示させるにはinputmode属性を使う

https://blog.tomoyukikashiro.me/post/ja/how-to-control-browser-keyboard-inputmode/
https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/inputmode
htmlのinput要素を選択したとき、スマホで表示される仮想キーボードの種類を単純に切り替えたい場合は、inputmode属性を使う。

これだとPCブラウザでスピナーが表示されたりブラウザの自動入力チェックが行われて面倒くさい
<input type="number">

これなら単純に数値キーボードが表示されるだけになる
<input type="text" inputmode="decimal">

検索すると以下がよく出てくるが、単に仮想キーボードを切り替えたい場合はinputmodeを使うのがいいと思う。
<input type="tel"> 本来の目的と違う利用なので不安。小数が入力できない。
<input pattern="\d*"> うまく動作しない。

スマホで取った写真をプレビュー表示

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<title>スマホで取った写真をプレビュー表示</title>
<style></style>
<script>
document.addEventListener("DOMContentLoaded", () => {

	document.querySelector("#btnScan").addEventListener("click", function() {
		document.querySelector("#fulImage").click();
	});

	document.querySelector("#fulImage").addEventListener("change", function(e) {
		var reader = new FileReader();
		reader.onload = function (e) {
			document.querySelector("#imgPhoto").src = e.target.result;
		};
		reader.readAsDataURL(e.target.files[0]);
	});

});
</script>
</head>
<body>

<div><img id="imgPhoto" width="300" height="300"><div>

<div>
	<input type="file" id="fulImage" style="display:none">
	<button id="btnScan">scan</button>
</div>

</body>
</html>

潮汐で月側だけでなく月の反対側も満潮になる原理

https://ja.wikipedia.org/wiki/%E6%BD%AE%E6%B1%90
月は単に地球の周りを回っているわけではなく、月と地球はお互いがお互いを引っ張り合いながら回っている。
イメージとしては大人と子供が手をつないでぐるぐる回っているようなイメージ。
そのため、月には地球から離れる方向、地球には月から離れる方向の遠心力が発生する。
月の反対側の地域が満潮になる原因は、この「月から離れる方向の遠心力」である。
月側の地域が満潮になる原因は、「月から離れる方向の遠心力」より「月が地球を引っ張る重力」の方が上回っているから。
月側と月の反対側の中間の地域は「月から離れる方向の遠心力」と「月が地球を引っ張る重力」がちょうど打ち消し合って海面が引っ張り上げる力が消えるので干潮になる。



しかし理屈は判ったが、これって月が絶妙な距離でないと「月側だけでなく月の反対側も満潮になる」とならないのでは?
もっと月が近ければ重力の影響が遠心力を上回って月側だけが満潮になり、もっと月が遠ければ遠心力の影響が重力を上回って月と反対側だけが満潮になる気がする。
公転と自転の同期みたいに必然的にそうなるんだろうか?

いや必然的にそうなるな。
地球が重力と遠心力がつりあった距離に居なければ、そもそも月と地球がお互いの周りを回っているという状態にならない。
もし遠心力のほうが強ければお互いがどんどん離れていってバラバラに吹っ飛んでいってしまう。
もし重力のほうが強ければお互いがどんどん近づき続けて中央で衝突する。