お詫び
今、完成 & 書き上げたので何も文章を考えていないです。
はじめに
クソアプリカレンダー 24日目を担当します。今年が 6回目の参加です。
これまでに作ったものはこのようなものです。
毎年参加しているからこのセクションがだんだん賑わってくる。
何を作ったのか
DSのマリオ64のミニゲームぽいやつ です
クソアプリ名は...好きなサービスです!
成果物
DSのマリオ64のミニゲームとは
きっかけ1
めちゃくちゃ強い人の動画が流れてきた。
きっかけ2
findy のスコアの話でこのまえTLが賑わっていた(何かのイベントきっかけぽい)。
そのとき、ここにエイプリルフール企画で何か連携できるようなものを作れば、findy に声をかけてもらえるのではと思い立つ。
ということで、Findyから連携できるサービスと、そのサービスが提供する認証認可プロバイダーを作ろうとした。find-y のIDを連携させることでスコア連携させるという仕組みだ。元々、自作の認証認可プロバイダには興味があった。が、やってみようとしたところ、そもそもスコアの改竄という不正にどうしても対処できなくて諦めた。何か良い方法はないだろうか。
技術的な解説
ふつ〜〜〜〜の React + Vite + TS のクライアントサイドレンダリング。静的な JS/HTML を firebase app にデプロイ。
特筆することがあるとすれば、sin/cos を使っていること + style タグと classname でスタイリングしていること。
import { FC, ReactNode } from "react";
export const CSSAnimationRightLeftBlock: FC<{
children: ReactNode;
idx: number;
}> = ({ children, idx }) => {
return (
<div className={`block-${idx}`}>
<style>{`
.block-${idx} {
position: absolute;
left: ${Math.random() * 800}px;
top: ${Math.random() * 400 + 100}px;
font-size: 32px;
animation: animate 3s 0s infinite linear;
}
@keyframes animate {
0% {
transform: translateY(calc(sin(0deg) * 150px)) translateX(calc(cos(0deg) * 50px));
}
50% {
transform: translateY(calc(sin(0deg) * 150px)) translateX(calc(cos(180deg) * 50px));
}
100% {
transform: translateY(calc(sin(0deg) * 150px)) translateX(calc(cos(360deg) * 50px));
}
}
`}</style>
{children}
</div>
);
};
CSSライブラリ探す時間が無かったのと keyframe が欲しかったのでこうした。@scope
を使えば style の衝突も避けられるとの期待だが、うまくいなかなかったので繰り返し要素のスタイリングは idx を渡して classname をいじっている。
本家ミニゲームは周期性を持ったアニメーションがあったので、この実装は苦労した。JS と setTimeout だとカクカクした動きになることに気づいて、この解決に悩んだ。その時 Marqueeタグに詳しくないと攻略できないブロック崩しゲーム の経験から、滑らかな動きを実現する方法としての marquee を思い出したが、 marquee がとる範囲が多くて要素が重なってクリックイベントを検出するのが難しかったのと、marquee に対する JSX(TS?)のLSPサポートが切れていて開発体験が最悪だったので撤退。そのとき sin/cos が Chrome でも使えるようになったことになったことを思い出したので試してみたけど、学生時代に数学をサボったせいで、三角関数をうまく使いこなせない。三角関数を使えば周期性を実現できるってのは、ツイッターのレスバで学んだ(学校の勉強は役に立つのか立たないのかみたいなやつ)。実質半日での開発だったのでこの辺りの調査が足りていないので、冬休みゆっくり調べることにします。