WordleVSを作った

WordleVSというブラウザゲームを作った。

作る上で得たtipsなどを適当に書く。

書きたいことを思い出したら更新するかも。

モバイルでのCSSアニメーションのちらつき

cssでカードがフリップするアニメーションを付けている。

.box-animate {
  transition: transform 0.8s;
  transform-style: preserve-3d;
  animation: flip-in .25s forwards;
}

こんな感じでアニメーションをつけている。

このアニメーションがiOSで検証時にちらついた。 モバイル対応のUI開発は基本的にデベロッパーツールを用いて行っていたが、そのときには発現しなかった。

フリップのアニメーションがコマ送りっぽくなったり、要素の上に重ねたモーダル(div要素)の上にちらついたり、動作が不安定だった。

解決法

.box {
  ...
  perspective: 1000px;
}

上のようにperspective: 1000px;をアニメーションを付ける要素に書いてあげると解消した。

理屈は謎で呪文みたいなものだと思っている(gpuを使わせる?とか見たような気がするけど分からない)。

iOSでのonClickが不安定

キーボードの処理はonClickで行っているが、これが時々不安定になる。

例えば、キーボードを「p -> o -> i -> u」のように連続で隣り合った(近い?)キーを押すと入力が「ppii」になってしまう。

pの次に押したiも、pとして入力される、というものだ。

これはonClickだけではなくて、cssにhoverで暗くするなどのリアクションを与えたときにも、iを押したはずなのにpのキーが暗くなっているというようなことが起こった。

解決策

onTouchStartならiOSでも問題なく動作したので、モバイルならonTouchStartを使って、PCならonClickを使う。

const handleTouchOrClick = () => {
	if (window.ontouchstart === undefined) {
		props.handleInput(props.keyName);
	}
};

...

<SomeButton>
    onTouchStart={() => props.handleInput(props.keyName)}
    onClick={() => handleTouchOrClick()}
</SomeButton>

モバイルだと、onClickonTouchStartも発火するので、handleTouchOrClickを定義してモバイルのときはonClickでは何もしないようにした。そうしないと2つが発火して入力が2回になってしまう。

注意点

hoverなどの問題は解決していないので、タッチにリアクションをつけたいときにどうすればいいのかは考えなければならない。

(発火する関数でスタイルを動的に変更させる、とか?)

クリップボードにコピーさせる

web apiにはクリップボードにコピーさせるものがある。 今回はroomIdをクリップボードにコピーさせたかった。

起こった問題は、navigator.clipboard.writeText(content);がunsecureなhttpの環境では使えなかったというものだ。 httpsな環境じゃないと使えないらしい。

解決策

document.execCommand(非推奨)を使う。

function unsecuredCopyToClipboard(text: string) {
	const textArea = document.createElement("textarea");
	textArea.value = text;
	document.body.appendChild(textArea);
	textArea.focus();
	textArea.select();
	try {
		document.execCommand("copy");
	} catch (err) {
		console.error("Unable to copy to clipboard", err);
	}
	document.body.removeChild(textArea);
}

const copyToClipboard = (content: string) => {
	if (window.isSecureContext && navigator.clipboard) {
		navigator.clipboard.writeText(content);
	} else {
		unsecuredCopyToClipboard(content);
	}
};

const onCopy = () => {
    ...
    copyToClipboard(props.roomId);
    ...
}

ブラウザがsecureで、クリップボードapiが使えるならそっちを使って、unsecureならexecCommandを使うようにする。

ドキュメントも要参考。

Built with Hugo
Theme Stack designed by Jimmy