一旦完成でいいかな。何の役にも立たない、CSSでどこまで遊べるか試した一品。https://t.co/Fimln7gH5p#web1week pic.twitter.com/fDYaxO6Lol
— ckoshien/情報局NextJS移植中 (@ckoshien_tech) May 23, 2020
I like Gundam 00.
I challenged how much I could recreate a difficult UI in an anime (like the cockpit of 00 Gundam) with CSS.
ガンダム00のUIのデザインが好みで、HTMLとCSSでどれだけ再現できるかということにチャレンジしました。
以前、CSSアニメーションでトランザムという記事を書いたのですが、その発展応用になります。
今回もテーマ的にサーバサイドは特に用意してないのですが、React Hooksの実装力向上を目指して最後までHooksで書きました。
UIに凝ったのでHooks以外は大したことはしていませんが。
全てCSSで書くのも大変なので、グラデーションを指定したdiv要素の上に一部だけ透過したpng(canvaで製作)を用意しました。
さらにその中間に白い背景のdiv要素を挟み、それを動かすことでゲージの増減を再現しています。
最初に全体像を決めずに一つ一つコンポーネントを実装していたので、後からコンポーネントを丸ごと拡大縮小して配置する裏技を使いました。
transform
でscaleを指定できるんですね。
後先考えずに作ってできなかったら作り直すところでした。
<div
style={{
transform:'scale(0.45)',
position:'absolute',
top:12,
left:8
}}
>
<Status/>
</div>
もともとhooksを使う前はredux+class構文だったので、
reducerは割ととっつきやすかったのですが、呼び出し方を間違えていて何度試しても状態の共有ができておらず苦労しました。
全体で共有しているのは
- チャージ中かどうか
- 現在のチャージ割合(100倍)
import { useReducer } from "react";
const initialState = {
isCharging: false,
count:3000
};
function reducer(state, action) {
switch (action.type) {
case 'charging':
return {
...state,
isCharging: true
};
case 'discharging':
return {
...state,
isCharging: false
};
case 'setCount':
return {
...state,
count: action.count
};
default:
return state;
}
}
export function MyReducer() {
const [state, dispatch] = useReducer(reducer, initialState);
return {
state,
dispatch
}
}
呼び出し方
const Button =()=>{
const { state, dispatch } = useContext(storeContext);
return (
試行錯誤した跡が残っています。
GitHub