白猫のメモ帳 (original) (raw)
エンジニアなので仕事中はずっと画面を、本を読むときはiPadをずっと見ています。
さすがにずっと近くばかり見ているので、遠くを見るときにピントが合いづらい感じがしてきました。
部屋の窓から遠くの山とかが見えればいいのですが、残念ながらそんな景色ではないので擬似的に遠くを見る効果が得られる簡単なサイトを作ってみました。
PCでも見れますが、慣れないうちはスマホやタブレットがおすすめです。
立体視が良いらしい
2枚の同じような絵を寄り目で見ると文字が浮き出るような画像を見たことはありますか。簡単に言うとあれが立体視です。
脳は左右の目の微妙な見え方の違いから立体感や奥行きを感じるようになっているため、微妙に差異のある2つの画像を重ね合わせると立体に見えます。
この立体視のうちの平行法という見方をすると、近くを見ているのに遠くを見ているような効果があります。
視力回復しているかというとちょっとまだわからないですが、ピントは合いやすくなるような気はします。たぶん…。
ということでネットで調べてときどき眺めていたんですが、同じ画像を見ているとだんだん飽きてきます。
しかも文字が浮き出る系とかはむしろ目が疲れる気がするので、いい感じに立体視ができる風景画像とかがランダムで出てくると良いなという気持ちになってきました。
しょうがない、自分で作るか。
※サイトの方に説明はもう少し詳しく書いてあるので良かったら見てみてください
immersity AIで立体視画像が作れる
そもそも立体視の画像ってどうやって作るんだろうと思っていたのですが、全部自動でやってくれるサービスがありました。
無料版だとウォーターマーク(透かし)が入って商用利用もできないのですが、課金をすれば商用利用ができます。月額とかではなくクレジット制なのもありがたいですね。
ちなみに画像の奥行きを解析するサービスなので、2D画像から簡易な3Dモーションに変換するのとかがメインっぽいです。
ChatGPT Plusに加入すれば画像生成ができるので、Dall-E 3で画像を作成→ immersity AIで立体視画像化という流れです。
Cloudflareは便利だぞ
画像さえ作ってしまえば普通に画像アプリとかで眺めても良いのですが、ランダム表示にしてWebサイトにしてもペラ1枚でできてしまうので、せっかくだし公開してみることにしました。
サイトをどこに置こうかな、レンタルサーバとかかなと考えていたのですが、それなりのアクセスでも無料で色々とオールインワンなのでCloudflareを選んでみました。
結論から言うととても便利でした。
ざっくり手順
ここからはこんなことをやったというのを簡単にメモします。詳しい設定方法などは書きません。
Cloudflareのアカウントを作る
メールアドレスで登録できます。登録時点ではクレカの情報とかも特にいりません。
ドメインを取る
Cloudflareのドメイン登録から簡単にドメインが購入できます。
仲介手数料みたいなのはないみたいなので良心的です。
ちなみにドメインは登録情報が公開されますが、見えるのは住所のうちの都道府県だけで他はCloudflare名義になるので個人情報の観点でも良いですね。
ページを作る
Pagesで新しいサイトを作ります。
Gitに接続というボタンがとてもわかりやすく表示されているので、これに従って作ったリポジトリと連携します。
CI/CDの設定は変更できますが、普通にポチポチしていけばmainにプッシュ(もしくはマージ)すると勝手にデプロイしてくれます。便利だなー。
サイト名は別になんでもいいんですが、「【名前】.pages.dev」っていうドメインが勝手に公開されるのであんまり推測しやすいと変なルートで入ってくるかも…?
サイトを作る
今回はHTML+CSS+JSのシンプルなページです。特に変わったこともないですが、メタタグはちゃんと書いたほうが良いかなくらいです。
画像はサイト上で表示するロゴ、アイコン、OGP画像あたりが必要になります。
Google Analyticsのタグを埋め込む
アクセス解析がしたいので、GoogleAnalyticsにアナリティクスアカウントを作ってタグを埋め込みます。
詳しく書いてくれているページがたくさんあると思うので手順は省略。
GitHubにプッシュする
連携が済んでいれば勝手にデプロイしてくれます。
ドメインと紐づける
pagesのカスタムドメインのタブから取得したドメインとの紐づけを行います。
ポチポチするだけでCNAMEがプロキシされるようになって、もうできたの?と不安になる簡単さです。
これでもうサイトとしては普通に公開されています。
メールアドレスを作る
一応お問い合わせ用のメールアドレスを作ります。
Email Routingでアドレスを作成して、宛先を指定するだけで転送されるようになります。とても楽で良い。
SSLの設定
エッジ証明書の「常に HTTPS を使用」を有効にしておくとhttpsにリダイレクトされるので有効にしておきます。
ついでに「HTTP Strict Transport Security (HSTS)」も有効にしておくと良い気がします。
その他
今回特に設定していないですが、Cache Rulesの設定をしたり、DDoSのブロック設定をしたり、URLリライトをしたり、HTTPヘッダの設定をしたり、わりと何でも揃っています。さすが。
わりとサクッと公開できたぞ
というわけでサイト公開できました。
面倒なことはだいたいCloudflareがなんとかしてくれるのがとてもありがたいです。
画像を増やすのはそんなに大変ではないので、ときどき追加しようかな。
目を休めるサイトなので、広告とかを貼るのも違うよなと思ってマネタイズができていません。
アクセスが多くなれば来る人は画像をじっと見てくれると思うので、ウォーターマークのところにロゴとかを出すのも面白いかなとも思いますが。
現時点ではサイトの一番下に気持ちばかりのAmazonのアフィリエイトリンクを貼りました。心優しい人がリンクから何かを買ってくれることを願ってみようかと思います。
そんなに収益を得るようなコンテンツではないですが、微妙にコストはかかっているので維持のためにプラマイゼロくらいにはなると嬉しいですね。
ちなみにCloudflareにはD1というSQLデータベースもあって、Next.jsやRemixなどの動的サイトもデプロイできるようになっています。
今回はサイト自体はかなりシンプルなものだったので、今度はもう少し凝ったものも作ってみたいですね。
それでは。
「システム」というワードが最近ちょっと引っかかっているので、まとまりきっていないですが書いておこうと思います。
現代の企業において、デジタル技術はビジネスの中心的な役割を担っています。
業界によってもその進み具合は異なりますが多くの企業がデジタル化を進めていて、DX(デジタルトランスフォーメーション)という言葉も頻繁に耳にしますね。
パッケージソフトの導入やSIer(システムインテグレーター)によるシステム開発など、いわゆるアウトソーシングの形でデジタル化を行う企業も多いですが、一方で企業がその企業たるためのコアなシステムを内製することも最近は増えてきています。
こういった企業ではシステムを担当する組織を設けたり、システム専門のグループ会社を設立するなど、いわゆるシステムの専門家を企業の内部に置くという手段を取ります。
ちなみに、ソフトウェアファースト第2版 あらゆるビジネスを一変させる最強戦略においては「手の内化」というワードが使われていますね。
システムとは何なのか
さて、ここまでの文章の中でも何度か「システム」という言葉が出てきましたが、改めてその意味を考えてみましょう。
「システム」という言葉はかなり抽象度の高い言葉で、その意味は多岐にわたります。
系、制度、方式、機構などさまざまな訳を充てることができますが、これらに共通するのは「複数の要素が互いに影響を及ぼす集合」ということです。
システムとは、何かが集まったものです。人でも、細胞でも、分子でも、何であっても、時間の経過とともにその独自のパターンを創り出すようなやり方で相互につながっている何かが集まったものです。
システムとは、「複数の要素が情報やモノ、エネルギーなどの流れでつながり、相互に作用し合い、全体として目的や機能を有する集合体」です。
改めて考えてみれば当たり前のことではあるのですが、「システム」という言葉がデジタル技術やコンピュータに限定されるものなのかというと、そうではありません。デジタル化が進むもっとずっと前から「システム」は存在しているわけです。
ところが最近のビジネスの場においては「システム」という言葉は「コンピュータシステム」とイコールのように扱われがちで、いかにしてソフトウェアを開発・導入するのかという点にばかり目が行っているように思えてしまいます。
システム部門の役割
では、企業におけるシステム部門の役割を改めて考えてみます。
シンプルに言えば、目的を達成するための仕組みやプロセスを作り、維持するといったところでしょうか。
システム部門の本来の役割は、単にソフトウェアを開発・導入することではなく、企業全体の「仕組み」を整備したり見直すことです。
この「仕組み」というのは、企業の業務フロー、組織間のコミュニケーションの方法、リソースの配分方法、業務を最適化するためのルールなど実に多くの要素があります。
ソフトウェアが現代のビジネスにおいて重要であることは間違いありませんが、良くない仕組みをどんなに頑張ってソフトウェアにしても良いシステムにはならないわけです。
ここを見誤って「なぜこの仕様かはわからないけど仕様通りです」というような開発をしてしまうと、せっかくのシステムがうまく機能しないことになりかねません。
全部システムかもしれない
システムは「複数の要素が互いに影響を及ぼす集合」ということを書きました。
AをするとBが起こり、結果としてCになる。つまりこれは立派なシステムです。これを「A→B→C」と表現しましょう。
組織変更を例にすれば「組織変更をする→組織の役割が明確になる→各組織が成果をあげやすくなる→企業全体のしての成果が増大する」などが考えられるでしょう。もちろんあくまで一例ですし、そう簡単に行けば苦労はしないのですが。
会社員という仕組みももちろんシステムです。
「仕事をする→価値が生まれる→価値にお金が払われる→会社が利益をあげる→報酬が支払われる」みたいなことですね。何故かはわからないけれど、お仕事をするとお金がもらえるというわけではないのです。
そう考えると仕事におけるありとあらゆることがシステムであると言えるかもしれません。
Cの結果を得るためには、どんなBが起こる必要があり、そのためにはAである何をすればいいのか、このストーリーを作ることがまさしくシステムを作るということに他なりません。
もちろん現実的には会社のシステムのすべてをシステム部門が作るわけではありません。適切な役割分担は必要でしょう。
ただ、「システム」の名を冠する以上は世界の複雑さをシステムとして捉える視点、つまりシステム思考を忘れないようにしたいものです。
小ネタです。
ブックマークレットはURLエンコードしよう
ブックマークレットは、ブラウザのブックマークから起動する簡易的なプログラムです。
例えば以下のようなブックマークレットを登録して、範囲選択をした状態でブックマークレットをクリックすればGoogleで検索ができます。
javascript:(() => { window.open("https://www.google.com/search?q=" + encodeURIComponent(window.getSelection())); })();
さて、ここで完全一致検索をするためにダブルクォートでくくることにします。
javascript:(() => { window.open("https://www.google.com/search?q=" + "%22" + encodeURIComponent(window.getSelection()) + "%22"); })();
これをクリックすると構文エラーだと怒られてしまいます。
ブックマークレットはあくまでURLなので、URLデコードを試みてこういう扱いになります。
javascript:(() => { window.open("https://www.google.com/search?q=" + """ + encodeURIComponent(window.getSelection()) + """); })();
正しくはこうです。
くっつけてからエンコードしなさいと言われたらその通りですが、意外と引っ掛かりがちな罠です。
javascript:(() => { window.open("https://www.google.com/search?q=" + "%2522" + encodeURIComponent(window.getSelection()) + "%2522"); })();
consoleにはlog以外もいろいろある
JSでデバッグ時にはconsole.logをよく使うと思いますが、実はlog以外にもいろいろとメソッドがあります。
たとえば、debug、info、warn、errorなどがあってログレベルの調整ができたりします。ちなみにlogのレベルはInfoです。
const obj = { hoge: "hoge", fuga: 1, piyo: true}; console.error(console); console.warn(console); console.info(console); console.debug(console);
DevToolsのこの辺りから変更できます。
dirはプロパティの対話的なリストを表示します。
DevToolsではlogでも結局は対話的に展開できてしまうのであまりメリットを感じませんが、node.jsの時にはよく使います。
第二引数に「{depth: null}」を渡すと一番深いところまで展開された状態で表示されるので、複雑な構造を表示したいときにはより便利です。
const obj = { hoge: "hoge", fuga: [{ piyo: [ 1, 2, 3] }, { piyo: [ 4, 5, 6] }] };
console.log(obj);
console.dir(obj, {depth: null});
tableはオブジェクトをテーブル形式で表示します。
複雑な構造だとかえって見づらいこともありますが、単純なオブジェクトや配列などを表示する場合には結構便利です。
const obj = { hoge: "hoge", fuga: 1, piyo: true}; console.table(obj);
他にもいろいろあるので見てみるといいかも。
developer.mozilla.org
mixinができる
ES6からJavaScriptではclass構文が使えるようになりました。
これは糖衣構文なので他の言語からするとなんだか違和感のある使い方ができてしまうのですが、これによってmixinを実現することができます。
例えばこんなクラス定義をしたとします。
class Hoge { name = "hoge"; }
const hoge = new Hoge(); console.log(hoge.name);
ここで型を引数で受けて継承したclassを返す関数を作るとmixinができます。return classの気持ち悪さよ…。
const mixin = (Base) => { return class Fuga extends Base { getName() { return this.name + this.name; } }; };
const Fuga = mixin(Hoge); const fuga = new Fuga(); console.log(fuga.getName());
ちなみにどうでもいいんですが個人的に気持ち悪いなと思っている文法はいくつかあって、例えばJavaのネストクラスのインスタンス生成あたりもちょっとキモいなと思っています。
なんというかスペースとドットの使われ方の問題でしょうか。
class Hoge { class Fuga { } }
var fuga = new Hoge().new Fuga();
似たようなもので、これは割とどの言語もだと思いますが、awaitの結果をメソッドチェーンにする場合には先に評価するためにカッコを求められるのに、
async function hoge() { return {name: "hoge"}; }
const hogeResult = (await hoge()).name; console.log(hogeResult );
否定の時にはそのままawaitの前に!を置いていい辺りがなんかキモさがあります。いやまぁなくても評価できるので正しいとは思うのですが。
async function fuga() { return true; } const fugaResult = !await fuga(); console.log(fugaResult);