15
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

思い出のイルミネーション(?)

Posted at

この記事は クソアプリ Advent Calendar 2021 の12日目の記事です。

作ったもの

Web上で選択した画像を配置して光らせるクソアプリを作りました。
サイズ調整が間に合わなかったため、スマホでは表示出来ません。(ごめんなさい)

アプリはこちら

作った背景(読み飛ばして良いポエム)

あれは10年ほど前のこと…

クリスマス時期にサーバー室での作業を終え、電気を消灯した時。
私の目に無数の光が飛び込んできたのでした。

それは、サーバーたちのLEDの灯火。
たしかに稼働していることを示す光。

その時私は思いました。

「うほっ、これは良いイルミネーション」

時は過ぎ、もうサーバー室で作業することはありませんが、
たまにあの時の光を思い出します。

良い機会ですので、思い出が風化する前に再現してみることにしました。

…そして2021/12/12、出来上がったのがこちらのクソアプリです。

ezgif.com-gif-maker.gif

コンセプト

Web地図用のライブラリを使用してみたかったので、Leafletを使用します。

使用ライブラリ

作業環境

  - Windows 10
  - react@17.0.2
  - react-leaflet@3.2.2
  - leaflet@1.7.1

作成のポイント

地図以外の画像を背景にする

地図ではなく自前の画像を使用する場合は、位置情報は緯度経度ではないため
「CRS.Simple」を利用するようです。
ImageOverlayで背景画像(ラック図)を表示しました。

参考

App.tsx
// ラック図の画像を読み込む
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タグを付けておきます。

srv2u.tsx
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

App.tsx
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アニメーションに挑戦!色が移り変わる背景を実装しよう

通常時

style.css
.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;
  }
}

クリスマスモード突入時

style.css
.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上に再現出来…た気がします、多分。
だいたいこんな感じだったはず…

折角なので緑やオレンジ以外に光って欲しい願望も叶いました。
正常なのか異常なのか分かりづらいので、いつもの色が良いなと思いました。

沢山詰め込んだ時のクリスマスモードの荒ぶりがすごい…!

owarini.gif

(オマケ)去年のクソアプリ

去年のクソアプリはペンギンしてました。
ヒゲペンギン推しの同士を増やすべく、リンクを貼っておきます。

素材と資料の再掲

ラックやサーバーなどの素材は以下サイトからお借りしました。
ありがとうございます。

素材

Leaflet

React-Leaflet

CSS

15
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?