viewBox のパラメータをすぐに理解する
viewBox 属性は、ユーザーの SVG 画像の座標系の原点とサイズを指定するために使用されます。 SVG 内で描画されるすべてのコンテンツは、この座標系を基準にして行われます。 SVG キャンバスは全方向に無限に拡張されるため、この座標系の境界の外側にグラフィックスを描画することもできますが、SVG ビューポートに対するこれらのグラフィックスの位置は、ユーザー座標系の位置によって制御することもできます。
viewBox 属性は、4 つのパラメーターを使用して、座標系の原点の位置とその寸法 (x y 幅、高さ) を指定します。最初は、この座標系は初期化されたビューポート座標系 (SVG イメージの幅と高さによって決定される) と同等であり、その原点は (0, 0) (SVG の左上隅) にあります。
2つのパラメータxとyの値を変更することで、原点の位置を調整できます。幅と高さの値を変更すると、座標系のサイズを変更できます。 viewBox 属性を使用するだけで、SVG キャンバスを拡大またはトリミングすることができます。例と合わせてお読みください。
重要な注意: この記事では、SVG ビューポート内の viewBox のデフォルトの動作 (スケールと位置) を変更しません。これは、プロパティのデフォルトの動作に従って、viewBox のコンテンツが可能な限りビューポート内に完全に含まれ、中央に配置されるためです。ただし、preserveAspectratio 属性を使用すると、viewBox のサイズや位置を自由に変更できますが、この記事では必須のテクニックではないため、ここでは詳しく説明しません。
viewBox を使用して SVG をトリミングします。つまり、viewBox 属性を使用してアート ディレクション SVG を作成します
少し前に、私のクライアントの 1 人が、ウェブサイトの SVG アバターをさまざまな画面サイズに合わせて異なるサイズに設定して、小さな画面ではごく一部だけが表示され、中程度の画面では問題なく表示されるようにするよう要求しました。サイズを大きくして、大きな画面でコンテンツ全体を表示します。そのとき最初に頭に浮かんだのは、彼の要求は実際には viewBox 属性を使用して SVG 画像をトリミングし、さまざまな画面サイズに基づいて見たい画像の特定の部分を表示することであったということでした。
SVG 座標系のサイズと原点位置を変更することで、SVG を切り取って、ビューポートに表示したいコンテンツの部分を表示できます。
その方法を見てみましょう。
次のような完全な SVG 画像があり、それを小さな画面のサイズにトリミングしたいとします。この画像は、Freepik によって設計された、無料で使用できる家のベクター画像です。この画像は、クリエイティブ コモンズ表示 3.0 非移植ライセンスの下でライセンスされています。わかりやすくするために、以下に示すように、画像は小および中画面で表示するためにのみトリミングされ、大画面では完全なコンテンツが表示されると仮定します。
左側の図は、viewBox 属性を使用して切り取る完全な図であり、右側の図は、小さい画面に表示したい領域です。
次に、viewBox 属性の値を変更して SVG をトリミングします。考慮すべき点がいくつかありますが、それについては後ほど説明します。ただし、その前に、上の画像の破線の四角形の内容と一致するように座標系を変更する必要があります。 、システムの原点と幅と高さの値を調整することで、その初期パラメータ値 0 0 800 800 を変更できます。
しかし、新しい座標と次元はどうやって知るのでしょうか?重要なのは、何度も試行錯誤を繰り返さないことです。
方法はいくつかあります。すでにグラフィック エディターを使用しているため (私の例では AI を使用しています)、エディターのパネルを使用して要素の位置と寸法を取得できます。
この点線の長方形のボックスを描画するのは、小さな画面に表示したいコンテンツを表すためだけではなく、別の理由もあります。この長方形の位置とサイズを取得して、それらを値として使用できます。 viewBox を使用します。 AI の Transform パネル (下図) を使用して、必要な値を取得します。長方形を選択し、右上隅にある「変換」リンクをクリックすると、必要な x、y、幅、高さの値を含む以下のパネルが表示されます。
この AI の変形パネルを使用して、選択した四角形の位置とサイズを取得できます
上記の値は整数ではないことに気づいたかもしれません。そのため、手動で変更する必要があります。上記の情報に基づいて、viewBox の値を 0 200 512 512 に変更します。
新しい viewBox のアスペクト比は SVG ビュー ウィンドウのアスペクト比と同じ (どちらも正方形) であるため、viewBox 内のコンテンツは拡大され、選択された領域のみがビュー ウィンドウに表示されます。 viewBox の値を変更した後の結果は以下のようになります:
新しいトリミングされた SVG。 viewBox プロパティを使用して指定した場所のみがビューポートに表示されます。青い枠線は SVG のビューポートを示します。
この時点で、解決する必要がある問題があります:
トリミングされた領域 (つまり viewBox) のアスペクト比 != SVG ビュー ウィンドウのアスペクト比の場合はどうなるでしょうか?
この場合、大幅なオーバーフローが発生します。明らかなオーバーフローとは、SVG ビューポートの境界を超える拡張を意味するのではなく、新しいユーザー座標系を基準にして viewBox によって定義されるオーバーフローを意味します。次の図はこれを示しています。
viewBox のアスペクト比がビューポートのアスペクト比と異なる場合、SVG 内のコンテンツがユーザー座標系からはみ出して、このような結果になる可能性があります。
黒い枠は新しいユーザー座標系を表し、青い枠は SVG ウィンドウを表します。
上の右の図の黒い境界線は、viewBox によって定義された領域です。ウィンドウ内の viewBox のデフォルトの動作に従って、コンテンツがウィンドウ (青い境界線) にできるだけ収まるように、viewBox は中央に配置され、可能な限り拡大されます。
SVG キャンバスは概念的に全方向に無限であるため、ユーザー座標系の境界の外側にグラフィックスを描画することができ、上の図に示すように、コンテンツが直接オーバーフローして移動します。
SVG ビューポートのアスペクト比 (SVG の幅と高さ) を viewBox のアスペクト比に合わせて変更すると、viewBox はビューポートに合わせて拡大縮小されるため、オーバーフローは発生しません。前の例と同じです。 。
ただし、場合によっては、SVG のアスペクト比を変更できない、または変更したくない場合があります。たとえば、ページ上に画像を表示するために SVG スプライトを画像のセットとして使用している場合です。ほとんどの場合、画像のアスペクト比は固定されており、画像内の小さな画像の内容に合わせて画像のサイズを変更する必要はありません。あるいは、アイコン システムを埋め込んで、すべてのアイコンを同時に同じサイズにしたい場合もあります。
余分なもの (たとえば、ビューポートに表示されるスプライト上の他のアイコン) を切り取るには、
ただし、もう 1 つ覚えておくべきことがあります。rect が元の/初期化されたシステムの原点を基準にして配置される場合を除き、
もちろん、余分な部分をトリミングするということは、依然として異なるアスペクト比を使用しており、コンテンツの両側にある余分な空白を処理する必要があることを意味します。前の例のように SVG が連続シーンである場合、ビューポートのアスペクト比を調整する必要があるため、これは必要ありません。 SVG がアイコンのセットであり、それを別のビューポートで 1 回だけ使用する場合、これは問題にならない可能性があります。
ここで覚えておくべき重要なことの 1 つは、viewBox のアスペクト比はビューポートのアスペクト比と一致するように保つのが最適であるということです。さらに、SVG 内に未定義の余分な空白が存在しないように修正を設定する必要があります。
したがって、必要に応じて viewBox を使用して SVG をトリミングし、SVG の特定の部分だけを表示することができます。しかし、それはインスタンスにどのように適用されるのでしょうか?
レスポンシブ デザインでのアート ディレクション SVG
この部分には、実際のプロセスのコード以外に追加するものは何もありません。たとえば、上に示した SVG があり、それをアバターとして使用したいとします。たとえば、中小規模の画面では切り取られた部分のみを表示し、大きな画面では完全なアバターを表示したいとします。画面。
SVG ウィンドウの幅と高さの値を変更するには、CSS を使用できます。ただし、viewBox の値を変更するには、現時点では JavaScript を使用する必要があります。
すべての SVG 属性と CSS 属性を同等に使用できるわけではありません。CSS では、CSS 属性と同じ効果を持つ一連の属性のみを設定できます。この表では、CSS プロパティとして使用できる SVG プロパティのセットの概要を確認できます。 SVG2 では、多くの属性 (x、y、cx、cy、r など) をこのリストに追加できますが、現在使用できるのはこれらの属性です。
SVG のさまざまな部分を表示するには、さまざまなメディア クエリに基づいて viewBox の値を変更する必要があります。Modernizr を使用してメディア クエリの条件を見つけ、それに応じて JavaScript で viewBox の値を変更します。例は次のとおりです:
免責事項: この記事の執筆時点では、CSSviewBox プロパティはありません。これは、このプロパティがなぜ役立つのか、またどのように使用できるかを説明するための単なる例です。
理想的には次のように使用します:
これらのスタイルは SVG に組み込まれ (または SVG から取り出され)、SVG はビューポートのサイズに応じて viewBox 値を調整します。これをページ ビューポート (インライン
ただし、CSS にはまだ viewBox 属性がないため、これは現時点では不可能です。
少し前に、SVG 仕様の編集者にこの問題について尋ねたところ、実際の使用法や例に基づいて SVGWG に提案できると言われました。 Twitter で議論した結果、数年前にも同様の SVGWG 提案スレッドがあったことがわかりました。当初の提案は現在も残っており、いくつかの実用例を参考にして、近い将来にこの提案が前進し、実行されることを期待しています。 CSS で viewBox プロパティも表示したい場合は、この提案を推進し、コメントして実現にご協力ください。
viewBox を使用して SVG アートディレクションを完成させる際に覚えておくべきこと
クライアントのプロジェクトに取り組んでいたとき、クライアントの要件に従ってアバターをアートディレクションするのに 1 分もかかりませんでした。ただし、これは、異なる画面サイズの同じ SVG の異なる viewBox ではなく、3 つの別々の SVG に分岐することになります。
3 つの SVG を選択した理由は、完全な SVG のサイズが大きすぎて、モバイルでは 100kb 以上に達するためです。元の SVG は約 200kb で、SVG を最適化することでファイルを半分近くのサイズに圧縮することができましたが、それでも画像がモバイル デバイスには大きすぎるため、最終的にサイズの異なる 3 つの画像を使用することになりました。 SVG のアート ディレクションを行う場合は、パフォーマンスの問題を念頭に置く必要があります。 SVG が大きすぎる場合は、viewBox を使用してアート ディレクションを行わないでください。
3 つの異なる SVG 画像を使用することを選択した場合、考えられる方法は多数あります。それは、SVG をどのように埋め込むか、また、何を達成したいのか、何を望まないのかによって異なります。達成するために。
ただし、前述したように、アニメーションやインタラクティブな効果を備えた SVG が必要な場合、
私はいつもこう言います。SVG は、トレードオフ、優先順位、場合によっては妥協する必要があるほとんどすべてのことを実現し、それに基づいて最適な決定を下すことを可能にする多くのオプションを提供します。しかし、パフォーマンスに関しては、決して妥協しないことが開発にとって良いことです。
終了する前に、SVG キャンバスのサイズを変更するために viewBox 属性を使用する問題について触れたので、この属性を使用して SVG を扱う際の時間とエネルギーを節約できる別の例を見てみましょう。
viewBox を使用して SVG キャンバスを拡張します
viewBox 属性を使用して SVG を拡大縮小できるのと同じように、SVG キャンバスを拡張することもできます。
数週間前、私は SVG 放射状メニューを生成できるツールを作成しました。 JavaScript を使用して生成されたメニューをアニメーション化する方法を示すために、いくつかの例を作成しました。デモは、
「境界の外側」とは、SVG のコンテンツを指すことに注意してください。これはまだ無限の SVG キャンバス上にありますが、ビューポートによって定義された無限の長方形を超えています。
翻訳者注: SVG キャンバスとウィンドウについては、w3cplus の関連記事を参照してください。
メニュー用に作成された SVG のサイズは、それ以上大きくせずにメニューを含めるのに十分なサイズです。メニューの周囲の余分な空白は避けられます。
メニューアニメーションの例として、メニューにバウンスアニメーションを適用してみました。このバウンス効果によりメニュー項目が「引き伸ばされ」、メニュー項目がバウンスするときに個別に切り取られます (つまり、オーバーフローします)。
最初、SVG ビューポートは
これらのかわいいバウンス アニメーションは、バウンス時間関数を使用して 0 から 100% までズームするアイテムに適用されます (つまり、アイテムは最初は非表示でズームアウトされます)。この効果は、アイテムが 100% のサイズを超えてバウンスした場合に発生します。 100%に戻ります。この効果により、項目が SVG の境界を超えて跳ね返ったときにオーバーフローが発生します。
下の図は、
上の図は、メニュー項目が SVG ウィンドウの境界を超えるように拡大された場合の効果を示しています。灰色の境界線は、SVG ウィンドウの境界線 (つまり、
SVG キャンバスを拡張するには、その寸法を大きくするだけです。したがって、この SVG メニューでは、元のサイズ 500 x 250 の代わりに 700 x 500 ピクセルのサイズを使用します。これにより、ビューポートに表示されるキャンバスの高さが 100 ピクセル増加し、ビューポートのキャンバスの幅が 200 ピクセル増加します。これらの値は、バウンス効果のためにこれらのメニュー項目を展開するために必要なスペースに基づいて決定しました。 SVG と具体的に何を達成しようとしているかに応じて、これらの値は一貫している必要はありません。
メニューがウィンドウの中央に配置されるようにするには、座標系の位置を負の方向 (つまり、上と左) に 100 ピクセル移動する必要があります。この動きを座標系の原点に適用することは、システム内のメニューに移動変換を適用することと同じです。その結果、メニューはビューポートの中央に留まります。
この図では、青い境界線は SVG ウィンドウの境界 (つまり、
ユーザー座標系のサイズを拡張すると、ビューポートに表示されるキャンバスの領域も増加します。この結果、キャンバスを拡大する量に応じて、キャンバスの内容がわずかに小さく表示されます。しかし、メニューに関しては、この結果は許容範囲です。
以下の画面記録は、SVG キャンバスを拡張した結果を示しており、SVG 境界内にメニュー アニメーション効果が含まれています。
SVG キャンバスが展開されると、メニュー項目には拡大縮小に十分なスペースがあり、バウンス効果を適用するときにオーバーフローによって切り取られることはなくなります。
viewBox 属性の 4 つのパラメーター値を変更して SVG キャンバスを拡張すると、すべての問題とメニュー項目がクリップされる問題が解決されます。 viewBoxは本当に素晴らしいです~~
結論
viewBox 属性は優れており、SVG の拡張バージョンです。この属性を使用すると、SVG で作業する時間を大幅に節約でき、グラフィック エディタを使用せずに SVG の問題を迅速に解決できます。全体として、これは SVG を編集するのに非常に便利です。
この特性についてすべて学び、それをあなたの仕事に活かすことを強くお勧めします。アートダイレクト SVG に使用したい場合は、パフォーマンスが鍵であることを忘れないでください。