この記事は クソアプリ Advent Calendar 2021 の12日目の記事です。
作ったもの
Web上で選択した画像を配置して光らせるクソアプリを作りました。
サイズ調整が間に合わなかったため、スマホでは表示出来ません。(ごめんなさい)
作った背景(読み飛ばして良いポエム)
あれは10年ほど前のこと…
クリスマス時期にサーバー室での作業を終え、電気を消灯した時。
私の目に無数の光が飛び込んできたのでした。
それは、サーバーたちのLEDの灯火。
たしかに稼働していることを示す光。
その時私は思いました。
「うほっ、これは良いイルミネーション」
時は過ぎ、もうサーバー室で作業することはありませんが、
たまにあの時の光を思い出します。
良い機会ですので、思い出が風化する前に再現してみることにしました。
…そして2021/12/12、出来上がったのがこちらのクソアプリです。
コンセプト
Web地図用のライブラリを使用してみたかったので、Leafletを使用します。
使用ライブラリ
作業環境
- Windows 10
- react@17.0.2
- react-leaflet@3.2.2
- leaflet@1.7.1
作成のポイント
地図以外の画像を背景にする
地図ではなく自前の画像を使用する場合は、位置情報は緯度経度ではないため
「CRS.Simple」を利用するようです。
ImageOverlayで背景画像(ラック図)を表示しました。
参考
// ラック図の画像を読み込む
import BgImage from './assets/img/bg_server_rack_dark.png';
// 省略
const App = () => {
//画像サイズからXY軸調整
const map_image = {
url: BgImage,
width: 600,
height: 620
};
// 座標の指定
const imageBounds = new LatLngBounds([0, 0],
[map_image.height, map_image.width]);
//省略
return(
//省略
<MapContainer
className="map"
center={[310, 300]}
zoom={-4}
zoomControl={false}
scrollWheelZoom={false}
crs={CRS.Simple} // CRS.Simpleを設定
>
<ImageOverlay
url={BgImage}
bounds={imageBounds}
opacity={1.0}
zIndex={10}
/>
<MyComponent />
</MapContainer>
//省略
)
}
各機器の画像を地図のマーカーとして表示する
Leafletのdivアイコンという機能で、
各機器のコンポーネントを呼び出します。
参考
Creating a dynamic “JSX” marker with react-leaflet
機器毎にファイルを作成し、機器の画像と光らせたい部分の指定用に
divタグを付けておきます。
import React from 'react';
import SrvImg from '../assets/img/2u_SRV.png';
import '../assets/css/style.css';
const Srv2u = () => {
return (
<>
<div className="base">
<div className="light dsp"></div>
<div className="light orb"></div>
<img src={SrvImg} alt=""/>
</div>
</>
);
}
export default Srv2u;
作成したコンポーネントは、L.divIconで設定しておきます。
配置先はクリックした場所にしています。
<MapContainer>
の中に要素を入れておくと、イベントが拾えるようです。
useMapEvents
import ReactDOMServer from 'react-dom/server';
import L from "leaflet";
import { MapContainer, ImageOverlay, useMapEvents } from 'react-leaflet'
import "leaflet/dist/leaflet.css";
import './assets/css/style.css';
import Srv2u from './component/Srv2u';
// 省略
const App = () => {
// 省略
const iconSrv2u = L.divIcon({
html: ReactDOMServer.renderToString(<Srv2u />)
});
const MyComponent = () => {
let target_icon = iconSrv2u;
// 省略 機器のタイプをステートで分岐させています
// マップのクリックイベントを検知し、クリック箇所の座標にマーカーを追加します
// draggable:trueにするとマーカーを動かすことができます
const map = useMapEvents({
click: (e) => {
L.marker(e.latlng, {icon:target_icon, draggable:true}).addTo(map);
}
})
}
}
光らせる部分
cssのキーフレームで時間経過とともに色を変更します。
参考
コピペで簡単!CSSで作るグローエフェクト15選【光彩/ドロップシャドウ/テキスト装飾/HTML】
CSS3アニメーションに挑戦!色が移り変わる背景を実装しよう
通常時
.base {
width: 213px;
height: 29px;
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.dsp {
margin: 0;
padding: 0;
position: absolute;
top: 2px;
left: 15px;
width: 15px;
height: 17px;
background: #85c4ee;
opacity: .8;
animation: dsp 5.0s infinite; /* ここで下のdspを指定 */
}
@keyframes dsp {
0%,100% {
box-shadow: 0 0 0 0 #c8e2f1;
}
50% {
box-shadow: 0 0 15px 2px #c8e2f1;
}
}
クリスマスモード突入時
.active .dsp {
animation: active-dsp 5.0s infinite; /* 別のアニメーションを指定 */
}
@keyframes active-dsp {
0%,100% {
box-shadow: 0 0 4px 2px #8FFFCF;
background-color: #0bfaca;
}
25%{
box-shadow: 0 0 4px 2px #f8d7d4;
background-color: #f872e6;
}
50% {
box-shadow: 0 0 8px 2px #eec71b;
background-color: #f1c40f;
}
75% {
box-shadow: 0 0 4px 2px #8FFFCF;
background-color: #0bfaca;
}
}
改善点
- 一度配置すると削除出来ません。個別に削除出来るようにしたいです
- ラック外に配置できてしまうので、制御出来るようにしたいです
- コンポーネント毎に光る設定が固定のため、ランダムに光ると尚良いです
- 各機器の幅や光る部分は正確ではありません
- もう少し機器の種類を充実させたかったです
終わりに
思い出の中のサーバーたちが、Web上に再現出来…た気がします、多分。
だいたいこんな感じだったはず…
折角なので緑やオレンジ以外に光って欲しい願望も叶いました。
正常なのか異常なのか分かりづらいので、いつもの色が良いなと思いました。
沢山詰め込んだ時のクリスマスモードの荒ぶりがすごい…!
(オマケ)去年のクソアプリ
去年のクソアプリはペンギンしてました。
ヒゲペンギン推しの同士を増やすべく、リンクを貼っておきます。
素材と資料の再掲
ラックやサーバーなどの素材は以下サイトからお借りしました。
ありがとうございます。