145
104

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 3 years have passed since last update.

macOSのスクリーンセーバーをHTML・CSS・JSで作る (Swiftスキル不要)

Last updated at Posted at 2020-05-01

この投稿では、HTMLでmacOSのオリジナルのスクリーンセーバを作れる方法を紹介します。

macOSのスクリーンセーバを作ってみたいけど、SwiftもObjective-Cも分からない、分かるのはHTMLやCSS、JavaScriptなどウェブ関連技術だけ、というウェブ系プログラマむけの解説です。

ちなみに僕は、この投稿で紹介する方法で、JavaScriptの人気ライブラリをひたすら紹介するスクリーンセーバを作りました:

Swiftなどを知らなくても、CSSやJavaScriptでアニメーションを頑張れば、こういった動きのあるスクリーンセーバが作れるわけです。

スクリーンセーバをHTMLで作る手順

Xcodeで新規プロジェクトを作る

まず最初に、スクリーンセーバのプロジェクトの下準備をしていきます。

Xcodeを起動して、新規プロジェクトを作ります。

Blank_Skitch_Document.png

その際、「Screen Saver」のテンプレートを選びます:

Screenshot_2020_04_29_13_45.png

「Product Name」「Organization Name」「Organization Identifier」は適当に:

Screenshot_2020_04_29_13_48.png

Swiftの接着剤コードを準備する

macOSは標準でHTMLだけでスクリーンセーバが作れるわけではないので、HTMLをスクリーンセーバ上に描画するためのコードは、Swiftで書いておく必要があります。

ここでは、スクリーンセーバとHTMLの接着剤となるSwiftのコードを用意する手順を説明していきます。

まず、先程新規作成したプロジェクトから、不要なObjective-Cのファイルを消します:

MyScreenSaverView_h.png

代わりに、消したファイルと同じファイル名 + .swiftで空のファイルを作ります。「MyScreenSaver」を右クリックして「New File」をクリックします。

Screen Shot 2020-05-01 at 15.56.17.png

ファイル形式は「Swift File」にします:

Screenshot_2020_05_01_15_57.png

ファイル名は「MyScreenSaverView.swift」にします:

Banners_and_Alerts.png

作成時に↓と聞かれますが、「Don't Create」を選びます:

Screenshot_2020_05_01_16_00.png

Swiftファイルが作成されたら、デフォルトで入っているコードは消し、下記コードをコピペして上書き保存します:

MyScreenSaverView.swift
import ScreenSaver
import WebKit

class MyScreenSaverView: ScreenSaverView, WKNavigationDelegate {
    private var webView: WKWebView!

    convenience init() {
        self.init(frame: .zero, isPreview: false)
    }

    override init!(frame: NSRect, isPreview: Bool) {
        super.init(frame: frame, isPreview: isPreview)
        setupWebView()
    }

    required public init?(coder: NSCoder) {
        super.init(coder: coder)
        setupWebView()
    }

    private func setupWebView() {
        let webConfiguration = WKWebViewConfiguration()
        // webkitがローカルファイルを参照できるようにする設定
        webConfiguration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")
        // webViewをスクリーンの大きさに合わせる
        webView = WKWebView(frame: NSRect(x: 0, y: 0, width: frame.width, height: frame.height), configuration: webConfiguration)
        webView.navigationDelegate = self
        // webViewの背景を透明にする
        webView.setValue(false, forKey: "drawsBackground")
        // スワイプでの戻る/進むを無効にする
        webView.allowsBackForwardNavigationGestures = false
        // ピンチで拡大/縮小できる機能を無効にする
        webView.allowsMagnification = false

        // ローカルのHTMLを読み込む
        if let htmlPath = Bundle(for: type(of: self)).path(forResource: "html", ofType: nil) {
            let htmlUrl = URL(fileURLWithPath: htmlPath, isDirectory: true)
            let indexUrl = URL(fileURLWithPath: htmlPath + "/index.html", isDirectory: false)
            webView.loadFileURL(indexUrl, allowingReadAccessTo: htmlUrl)
        }
    }

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        // ページが遷移したタイミングでwebViewをスクリーンセーバに表示する
        self.addSubview(webView)
    }

    // マウスが動いたときにスクリーンセーバが解除されるようにする(その1)
    override func hitTest(_ aPoint: NSPoint) -> NSView? {
        self
    }

    // マウスが動いたときにスクリーンセーバが解除されるようにする(その2)
    override var acceptsFirstResponder: Bool {
        true
    }
}

このSwiftコードが何をしているか簡単に説明すると、スクリーンセーバが起動したらWebView(埋め込み版のSafariのようなもの)を起動し、html/index.htmlを読み込み、それをスクリーンセーバ上に表示するといった処理が書かれています。

Swift側の準備は以上です。

HTMLファイルを作る

次に、スクリーンセーバのグラフィックデザインを実装していく場所であるindex.htmlを作っていきます。

まず、htmlフォルダを作りたいので、「MyScreenSaver」フォルダを右クリックして「Add Files to "MyScreenSaver"」をクリックします:

Screen Shot 2020-05-01 at 16.09.56.png

すると、Finderのダイアログが出てくるので、「New Folder」をクリックし、「html」フォルダを作ったら「Add」をクリックして閉じます。

Screenshot_2020_05_01_16_11.png

次に、index.htmlを作るために、htmlフォルダを右クリック、メニューから「New File」を選びます:

Screen Shot 2020-05-01 at 16.13.26.png

「File」というファイルが作られるので、「index.html」に名前を変えておきます。

index.htmlの中身は適当に何か書いておきます:

html/index.html
<style>
h1 {
  color: black;
  background: white;
  font-size: 30vh;
  animation: blink 1s step-end infinite;
}
@keyframes blink {
  75% { opacity: 0.0; }
}
</style>
<h1>Hello World</h1>

以上でHTMLファイルの準備は完了です。

スクリーンセーバを実行できるように設定する

続いて、スクリーンセーバを実行するための設定をしていきます。

Xcodeのメニューバーにある「MyScreenSaver」をクリックするとメニューが出るので、そこから「Edit Scheme」を選びます:

Screen Shot 2020-05-01 at 16.21.09.png

「Run」の「Info」タブの「Executable」セレクトメニューから「Other」を選び、ScreenSaverEngine.appに設定します:

Screenshot_2020_05_01_16_25.png

ScreenSaverEngine.appは/System/Library/CoreServices/ScreenSaverEngine.appにあります。macOSのバージョンによって、ありかが異なる場合があります。

次に、「Arguments」タブを開き、

  • -window
  • -module "$(EXECUTABLE_NAME)"

の引数設定を追加します:

Screenshot_2020_05_01_16_27.png

更に、実行ごとにスクリーンセーバを自動的にインストールするように設定します:

Screen_Shot_2020-05-01_at_16_39_12.png
open -W "${CODESIGNING_FOLDER_PATH}"

以上で、スクリーンセーバを実行するための設定は完了です。

スクリーンセーバを実行してみる

準備が整ったので、スクリーンセーバを実行してみましょう。

スクリーンセーバを実行するには、Command+Rを押すか、XcodeのRunボタン(▶アイコン)を押します。

実行が開始すると、設定アプリが立ち上がり、スクリーンセーバをインストールするか聞かれるので「Install」を選択します:

Screen Shot 2020-05-01 at 16.46.30.png

すると、スクリーンセーバがインストールされ、スクリーンセーバの選択画面にプレビューが表示されるようになります。

Screen Shot 2020-05-01 at 16.47.23.png

この状態で、設定アプリを閉じると、今度はスクリーンセーバを確認するためのウィンドウが表示されます:

saver_window.png

index.htmlに書いた内容が表示されるはずです。

あとは、index.htmlを作り込んでいくと、オリジナルのスクリーンセーバが作れます。

ちなみに、実行したときに、インストールされたスクリーンセーバは、実行が終了しても残るので、設定アプリで自分が作ったスクリーンセーバを選択しておけば、Xcodeを閉じてもそのスクリーンセーバが使われるようになります。

Safariを使った動作確認がおすすめ

HTMLを直してはXcodeの「Run」でスクリーンセーバをインストールし直して確認する、というのは開発体験としてかったるいので、HTML側にごりごり書いていくときはSafariで動作確認するのをおすすめします。Safariを使うと、ウェブインスペクタも使えるのでデバッグがはかどります。

ChromeやFirefoxではなくSafariを使う理由は、Swiftのコードで使っているWKWebViewが他ブラウザの環境よりSafariに近いからです。

普段、Swiftを書かない人は、Xcodeも慣れていないと思うので、HTMLをいじるときはVSCodeなど自分の好きなエディタを使ってもいいです。

Safariで動作確認するときは、html/index.htmlを開くだけです。HTMLを直したら、リロードする。普段のウェブアプリの開発と同じ要領です。

スクリーンセーバの作りにもよりますが、fetch()などで外部APIを叩いたりするときは、Same Origin Policyにひっかかってしまうことがあります。その場合は、Safariの「Devloper」→「Disable Cross-Origin Restrictions」をオンにしておくと良いです:

Screen Shot 2020-05-01 at 16.56.30.png

また、フルスクリーンでの動作確認をするときは、「View」→「Always Show Toolbar in Full Screen」のチェックを外しておくと良いです:

Screen Shot 2020-05-01 at 16.59.46.png

おわり

macOSのスクリーンセーバを作るのに、Swiftの知識はほぼ不要です。

慣れ親しんだHTMLやJavaScriptを駆使して、自分だけのスクリーンセーバを作ってみてはいかがでしょうか。


最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローしてもらえると嬉しいです:relieved:Twitter@suin

145
104
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
145
104

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?