# Retina で canvas が2倍の大きさになる：inset:0 では広がらない（押すと弾けるロゴの不具合）

> 押して弾ける動きの粒が「変なところから出る」。原因は、Retina で canvas の CSS 上の大きさが2倍になること（inset:0 では広がらない）と、GSAP が位置を書き換えること。三段階で直した記録。

- URL: https://koshinstudio.com/notes/logo-pop/
- 公開: 2026-10-08
- 書いた人: Koshin（https://koshinstudio.com/about/）
- サイト: Koshin Studio

  English version (https://koshinstudio.com/en/notes/logo-pop/)

Koshin Studio 開発の記録 ／ 2026年10月

  このサイトのトップには、大きなロゴがあります。字を押すと、その字がぽんと弾けて、粒が散ります。ロゴを、自分で作った書体「恒紳ポップ」で作り直したあと、この動きについて、「粒が、字ではない変なところから出る」「まだ、右に寄っている」と指摘を受けました。直すまでに三段階かかったので、何が原因で、どう見つけたのかを、測った数字で書きます。

## ロゴを、自作の書体で作り直す

  それまでのロゴは、明朝体の骨で欧文を組んだものでした。これを、自分で作った書体「恒紳ポップ」（欧文は、骨格から描き起こした、丸みのある字形）に替えました。書体のライセンスは、SIL Open Font License 1.1 で、ロゴへの利用に問題はありません。

  作り方は、書体のファイルから、K O S H I N T U D の 9 文字の輪郭を取り出して、SVG の path にします（tools/logotype_pop.py）。ロゴは「絵」として配るので、サイトは書体のファイルを配りません。この書体は、同じ字でも「基本形」「pop1」「pop2」と、跳ね方の違う形を持っているので、3 通りの組み合わせを並べて見比べて、リズムのよい 1 つを選びました。「U」の右側に出た細い継ぎ目の線は、輪郭に、ごく細い線（3 単位）を足して消しました。

## 一段階目：押したあと、字がずれたまま戻らない

  まず、字を押したあとの位置を、時間を追って記録しました。すると、字が元の位置に戻っていませんでした。

    字 | 押す前の中心 | 押したあと（2 秒後）

    K（上段の左端） | (327, 306) | (320, 313)

    S（下段の左端） | (331, 442) | (323, 435)

  約 7px のずれです。押したあとの変形を見ると、matrix(1, 0, 0, 1, -46, -42) が残っていました。大きさは 1 倍に戻っているのに、位置のずれだけが残っている状態です。

  原因：弾ける動きに使っていたアニメーションの部品（GSAP）が、字の SVG の <g> に、もともと付いていた位置の指定（transform="translate(x,0)"）を、自分の計算で書き換えて、その補正の一部が、終わったあとも残っていました。

  直し方：位置を持つ層（外側の <g transform>）と、動かす層（内側の <g class="ks-ch">）を分けました。動きは、ブラウザ標準の Web Animations に替えました（終わると、効果が消えて、元の状態に戻ります）。確かめると、12 文字すべてで、字の中心は動かず、動きの終わりの変形は none に戻りました。

## 二段階目：「まだ右に寄っている」

  ところが、直したあとも、「まだ、アニメーションが右に寄っている」と言われました。私の測定では、粒は字の中心から 2〜13px 以内に出ていました。測った結果と、見えたものが、食い違っていました。

  私の測定は、倍率 1 倍の画面で、粒の位置を「画面上の座標」で数えたものでした。Retina ディスプレイ（倍率 2 倍）や、スマホ（3 倍）でも測ってみると、粒を描く画面（#burst）の、CSS 上の大きさが、おかしいことが分かりました。

    画面 | 画面の幅 | 粒の画面の幅（前） | （後）

    1280px・倍率 1 | 1280 | 1280 | 1280

    1440px・倍率 2 | 1440 | 2880 | 1440

    390px・倍率 3（スマホ） | 390 | 780 | 390

  原因：粒を描く canvas は、CSS で inset:0 と指定していましたが、canvas のような部品は、inset:0 だけでは、画面いっぱいに広がりません。元の大きさ（描く画素数）のままです。倍率 2 の画面では、画素数が 2 倍なので、CSS 上の大きさも 2 倍になり、粒が、座標の 2 倍の位置（右下）に表示されていました。倍率 1 の画面では、同じ大きさなので、気づけません。

  直し方：幅と高さを、100% と明示しました。確かめると、どの倍率の画面でも、粒の画面は、画面と同じ大きさになりました。

## 三段階目：字そのものから出す

  最後に、「字自体から出るようにできないか」という要望がありました。それまでは、字の枠の中心から出していたので、「O」のように真ん中が空いた字では、字ではない所から出たように見えます。

  そこで、字の形（path）の輪郭に沿って点を選び（getPointAtLength）、その画面上の位置から、字の中心と反対の向き（ばらつきあり）へ、粒を飛ばすようにしました。下段の字は「字＝マスク」で描いているので、矩形が指しているマスクの中の path を探して使います。押して撮ると、「O」は輪の周りから、「U」は形に沿って、粒が出ています。

## 分かったこと

> 測った数字と、見えたものが食い違ったら、測り方の条件を疑う。

- 見る人の画面は、自分の画面と違う。倍率 1 倍の画面だけで測って、「ずれは小さい」と判断しました。実際は、倍率 2 倍の画面で、粒が 2 倍の場所に出ていました。

- 測る空間を、見る空間に合わせる。私の測定は、粒の「論理的な座標」を数えていたので、画面に出た位置のずれは、そもそも見えませんでした。

- 動きは、終わったあとの状態も測る。字が元に戻らないことは、動いている間だけを見ていたら、気づけませんでした。

- 位置と動きは、別の層に置く。同じ要素に両方を持たせると、片方がもう一方を上書きします。

  この記事の数字は、2026年10月8日に、このサイトのトップを、実際のブラウザ（Chrome）で操作して測ったものです。実際の Retina ディスプレイの実機で、直ったことは、まだ確かめていません（倍率 2 倍と 3 倍の状態を、ブラウザの設定で再現して確かめました）。

  この話に出てくるもの

- 手元では動くのに、配ると壊れる (https://koshinstudio.com/notes/deploy-gotchas/) — このサイトの、別の記録

- アプリを完全に終了すると、サインインが消えた (https://koshinstudio.com/notes/apple-signin/) — 「終わったあとの状態」に出る問題の、別の記録
