ElectronでWindows98風のGUIをMacで動かす
懐かしのWindows98
こんにちは。カズ之助です。
唐突ですが、私の初めてのPCはWindows95で、二代目のPCはWindows98でした(自分語り)。
私が幼稚園児のときの誕生日プレゼントで父親からのお下がりでVAIO PCG-C1XFをもらいました。幼稚園の年中さんのときにもらって、小学3年くらいまで使ってた記憶があります。
現在はMacを使っていますが「MacでもWindows98の落ち着いた懐かしのGUIを動かしたい!」というわけで、ElectronとReactと98.cssを使ってサクッと作っていきたいと思います。
ちなみにElectronでOS独自の機能を使用しているわけじゃないのでMacじゃなくても、最新のWindowsやLinuxでも動きます。たぶんね。
(Macって書くとタイトル映えすると思ったんや……許してクレメンス……)
最新のWindows10で98風のウインドウがあったらそれはそれで面白いかもね!
できたもの
どうですか?Mac特有の角丸ウインドウではあるものの、それっぽくないですか???
ちゃんと右上の[x]
を押すとウインドウが閉じられます。
Electronの準備
Electronは数々の先駆者の人たちの知恵を集めてElectronでReactを動かすためのテンプレート的なものを(個人用に)作成しました。ご自由にお使いください……。先駆者の方々マジでありがとう。
98.cssを読み込む
public/index.html
のhead
で98.cssを読み込みましょう。
<link
rel="stylesheet"
href="https://unpkg.com/98.css"
>
これで98.cssが使えるようになります(それはそう)。やったね!
ウインドウの設定をする
ウインドウの設定をしましょう。フレームは非表示で作ります。
テンプレートのelectron.js
のウインドウの設定を変更します。
mainWindow = new BrowserWindow({
frame: false,
width: 900,
height: 680,
webPreferences: {
nodeIntegration: false
preload: `${__dirname}/preload.js`,
},
})
preload.js
にはこれを書いてください。
const { ipcRenderer } = require('electron')
window.ipcRenderer = ipcRenderer
これを書くことで、React側からipcRendererを使用することができます……
タイトルバーを作る
さて、ここからいよいよ本題です。まずはタイトルバーを作っていきましょう。
タイトルバーはドラッグ可能である必要があります。
src/components
内にTitleBar.js
とtitle.css
を作成しましょう。
本当はTitleBar.js内にコンポーネントCSSを書きたいんですが、-webkit
から始まるパラメータをコンポーネントCSSに書く方法がわからない……
さて、title.css
から書き始めていきましょう。
.title-bar {
-webkit-app-region: drag
}
.title-bar Button {
-webkit-app-region: no-drag
}
ここでは、title-bar
はドラッグ可能に指定しています。
こうすることでウインドウをドラッグして端っこに持っていったら最大化とか画面半分まで拡大とかもできるようになります。
でも、これだけだとボタンが押せなくなってしまいます(クリック時にOSに処理が持っていかれてしまうため)。なので、ボタンのところだけはドラッグを無効化してやりましょう。
次はTitleBar.js
です。
ウインドウを閉じるなどの処理はElectron側で行うため、Electronへの通信を行うipcRenderer
をwindow
から読み込んでおきます。
import './title.css'
const { ipcRenderer } = window
const TitleBar = (props) => {
return (
<div class="title-bar">
<div class="title-bar-text">{props.title}</div>
<div class="title-bar-controls">
<button aria-label="Close" onClick={exit}></button>
</div>
</div>
)
}
const exit = () => {
ipcRenderer.send('exit', 'exit')
}
export default TitleBar
今回はpropsを使ってタイトルバーのテキストを変更できるようにしてみました。
次はApp.jsx
の方を変更していきます。
import React from 'react';
import TitleBar from './components/TitleBar'
function App() {
const windowStyle = {
"height": "100%"
}
return (
<div className="App window" style={windowStyle}>
<TitleBar title="This is Title" />
</div>
);
}
export default App;
この状態でyarn start
をすると、
こんな感じのウインドウが立ち上がると思います。なつかしいですね!
でも、この状態で[x]
を押してもウインドウが閉じません。まだelectron側で閉じる処理を書いてないからね。ちゃちゃっと書いちゃいましょう。electron.jsの最後に追記する感じに書いちゃってください。
ipcMain.on('exit', () => {
mainWindow.close();
})
これを書いて保存したらもう一度yarn start
してみましょう。今度は[x]
を押すとウインドウが閉じると思います。やったね!
ウインドウのスタイルを当てる
タイトルバーができたので今回は7割ほど完成しました。
あとはウインドウの中身を書いていけばいいだけです。いいですね。楽ですね。
では、早速中身をかいていきたいのですが、その前にApp.jsx
を修正する必要があります。
import React from 'react';
import TitleBar from './components/TitleBar'
function App() {
// 追加!
const bodyStyle = {
"width": "calc(100% - 5px)",
"height": "calc(100vh - 45px)"
}
const windowStyle = {
"height": "100%"
}
return (
<div className="App window" style={windowStyle}>
<TitleBar title="This is Title" />
{/* 追加! */}
<div className="window-body" style={bodyStyle}>
</biv>
</div>
);
}
export default App;
追加したところにコメントを書いてあります。
bodyStyle
を定義して、空のdiv
を作成してwindow-body
というクラスを指定して、bodyStyle
を当てています。
これで実行してみましょう!
どうですか!?!?!?一気に昔懐かしのWindows感出てきませんでしたか????
下に少し隙間が空いているのが気になりますが、中身を書くと(なぜか)消えるので気にせず次行きましょう!
ウインドウの中身を書いていく
それではついにウインドウの中身を書いていきましょう。ここまでくれば9割方完成です!
src/pages
の中にTop.js
を作成しましょう。
今回もpropsから内容を受け取るように書いていきます。
function Top (props) {
return (
<div>
<p>{props.text}</p>
</div>
)
}
export default Top
では、App.jsx
から、このページを読み込んで表示しましょう。
import React from 'react';
import TitleBar from './components/TitleBar'
// 追加!
import Top from './pages/Top'
function App() {
const bodyStyle = {
"width": "calc(100% - 5px)",
"height": "calc(100vh - 45px)"
}
const windowStyle = {
"height": "100%"
}
return (
<div className="App window" style={windowStyle}>
<TitleBar title="This is Title" />
<div className="window-body" style={bodyStyle}>
{/* 追加! */}
<Top text="Hello World! Windows98"/>
</div>
</div>
);
}
export default App;
さて、ここまで書けたら実行しましょう!
どうですか!?いい感じじゃないですか??
違和感
#007e7d
で構成された壁紙の上にウインドウを置くとそれっぽい……!!
あとは98.cssのページからいろいろいじってみると面白いかもしれません。
サンプルコードをいろいろ追加してみた
なんかいい感じに98っぽくなるのでぜひぜひ試してみてくださいね!
追記
Zennの公式Twitterでピックアップされました!!(うれしい)
やったー!
Discussion