[{"data":1,"prerenderedAt":69},["ShallowReactive",2],{"project:dreamos:ja":3,"i-tabler:app-window":62,"i-tabler:radio":65,"i-tabler:language":67},{"slug":4,"name":5,"summary":6,"role":-1,"updateNote":-1,"meta":7,"coverUrl":19,"lang":22,"isFallback":23,"featuredRank":24,"badge":25,"lastActivity":18,"tapeNumber":26,"blocks":27},"dreamos","夢 -ヴェイパーウェーブ- 2.0","ヴェイパーウェイヴ風の仮想 OS。ウィンドウ形式のインターフェースで、経歴と作品を紹介します。",{"origin":8,"categories":9,"tags":11,"released":18,"cover":19,"links":20},"personal",[10],"frontend",[12,13,14,15,16,17],"nuxt","unocss","pinia","vueuse","animejs","interactjs","2025-09-06","\u002F_nuxt\u002Fcover.BAlcmKfk.webp",{"demo":21},"https:\u002F\u002Fdreamos.net","ja",false,0,null,4,[28,43,50,56],{"type":29,"items":30},"features",[31,35,39],{"title":32,"description":33,"icon":34},"ウィンドウ形式のインターフェース","OS の操作感を再現し、各紹介ページがそれぞれ操作できる独立したウィンドウになっています。","tabler:app-window",{"title":36,"description":37,"icon":38},"ラジオ","ブラウザ標準の Audio API で実装した音楽プレーヤー。曲を切り替えながら、音楽を聴きつつサイトを巡れます。","tabler:radio",{"title":40,"description":41,"icon":42},"3 言語対応","システムの言語を繁体字中国語・簡体字中国語・英語から切り替えられます（日本語は非対応）。","tabler:language",{"type":44,"title":45,"problem":46,"solution":48},"challenge","ウィンドウを表示範囲の外に出さない",[47],"ウィンドウをドラッグする際は、位置と画面の境界を計算し、表示範囲の外へ出ないようにする必要がある。",[49],"境界の計算とパラメータ調整に AI を活用し、計算ミスのリスクを抑えた。ドラッグで見落としがちな低レベルの処理は interact.js に任せた。",{"type":44,"title":51,"problem":52,"solution":54},"ブラウザのリサイズ後に位置がずれる",[53],"ブラウザのサイズを変えたあとウィンドウを再計算しないと、新しいサイズで正しく配置できず、ドラッグ時に予期しない不具合が起きる。",[55],"debounce でリサイズが止まるのを待ち、:key でウィンドウを作り直して中央に配置し、位置はユーザーに戻してもらう。リサイズを繰り返すことはまれなので、比率で位置を換算するより単純で確実。",{"type":44,"title":57,"problem":58,"solution":60},"クリックしたウィンドウを最前面に",[59],"OS と同じように、クリックしたウィンドウが最前面に来るようにしたい。",[61],"使用中の最大の z-index を記録し、クリックされたウィンドウにその値に 1 を足して設定する。z-index の上限は 2147483647 で、通常の利用ではまず到達しない。",{"left":24,"top":24,"width":63,"height":63,"rotate":24,"vFlip":23,"hFlip":23,"body":64},24,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2zm3 1h.01M9 8h.01\"\u002F>",{"left":24,"top":24,"width":63,"height":63,"rotate":24,"vFlip":23,"hFlip":23,"body":66},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 3L4.629 6.749A1 1 0 0 0 4 7.677V19a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1H4.5M4 12h16M7 12v-2m10 6v.01M13 16v.01\"\u002F>",{"left":24,"top":24,"width":63,"height":63,"rotate":24,"vFlip":23,"hFlip":23,"body":68},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M9 6.371C9 10.789 6.761 13 4 13m0-6.629h7\"\u002F>\u003Cpath d=\"M5 9c0 2.144 2.252 3.908 6 4m1 7l4-9l4 9m-.9-2h-6.2M6.694 3l.793.582\"\u002F>\u003C\u002Fg>",1793955809500]