最近、自分の一部としてレンガの壁のパターンを作成しました #プチパターン シリーズ、560バイト(または約XNUMXツイートのサイズ)以内にSVGで有機的なパターンまたはテクスチャを作成するチャレンジ。 この制約に合わせるために、全体的な画質に影響を与えることなく、SVGパターンに含まれるコードをできるだけ少なくするために、SVGパターンを最適化するいくつかの根本的な方法を教えてくれました。
プロセスを順を追って説明し、197バイトからわずか44バイトまでのSVGパターンを取得する方法を示します。これは77.7%の大幅な削減です。
SVGパターン
これは、いわゆる「ランニングボンド」ブリックパターンです。 これは、世の中で最も一般的なレンガのパターンであり、確かに前に見たものです。レンガの各行は、レンガの長さの半分だけオフセットされ、繰り返し千鳥状のパターンを作成します。 配置は非常にシンプルで、SVGを作成します <pattern>
要素は、コードでそれを再現するのに最適です。
SVG <pattern>
elementは、水平軸と垂直軸に沿って一定の間隔で複製(または「並べて表示」)できる事前定義されたグラフィックオブジェクトを使用します。 基本的に、長方形のタイルパターンを定義し、それを繰り返して塗りつぶし領域をペイントします。
まず、レンガの寸法と各レンガ間のギャップを設定しましょう。 簡単にするために、きれいな丸い数字を使用しましょう:幅 100
との高さ 30
レンガのために、そして 10
それらの間の水平方向と垂直方向のギャップ。
次に、「ベース」タイルを特定する必要があります。 そして、「タイル」とは、レンガと混同しないように、物理的なタイルではなくパターンタイルについて話します。 上の画像の強調表示された部分をパターンタイルとして使用しましょう。最初の行にXNUMXつのレンガ全体があり、XNUMX番目の行にXNUMXつの半分のレンガの間にXNUMXつの全体が挟まれています。 ギャップが繰り返されるパターンタイルに含まれる必要があるため、ギャップが含まれる方法と場所に注意してください。
使用時 <pattern>
、パターンを定義する必要があります width
& height
、ベースタイルの幅と高さに対応します。 寸法を取得するには、少し計算が必要です。
Tile Width = 2(Brick Width) + 2(Gap) = 2(100) + 2(10) = 220
Tile Height = 2(Bright Height) + 2(Gap) = 2(30) + 2(10) = 80
了解しました。パターンタイルは 220✕80
。 また、設定する必要があります patternUnits
属性、ここで値 userSpaceOnUse
本質的にピクセルを意味します。 最後に、 id
パターンに別の要素をペイントするときに参照できるようにするために必要です。
<pattern id="p" width="220" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
タイルの寸法を設定したので、課題は、可能な限り最小のバイト数でグラフィックをレンダリングする方法でタイルのコードを作成することです。 これが私たちが最後に終わらせたいと思っていることです。
初期マークアップ(197バイト)
私の頭に浮かぶこのパターンを再現するための最も簡単で宣言的なアプローチは、XNUMXつの長方形を描くことです。 デフォルトでは、 fill
SVG要素のは黒であり、 stroke
透明です。 これは、コードで明示的に宣言する必要がないため、SVGパターンを最適化するのに適しています。
以下のコードの各行は、長方形を定義しています。 ザ width
& height
常に設定され、 x
& y
位置は、長方形がオフセットされている場合にのみ設定されます。 0
位置。
<rect width="100" height="30"/>
<rect x="110" width="100" height="30"/>
<rect y="40" width="45" height="30"/>
<rect x="55" y="40" width="100" height="30"/>
<rect x="165" y="40" width="55" height="30"/>
タイルの一番上の行にはXNUMXつの全幅のレンガが含まれ、XNUMX番目のレンガは次の位置に配置されます。 x="110"
許可 10
レンガの前のギャップのピクセル。 同様にあります 10
レンガがで終わるため、ギャップのピクセル 210
ピクセル(110 + 100 = 210
)横軸は <pattern>
幅は 220
ピクセル。 少し余分なスペースが必要です。 そうしないと、XNUMX番目のブリックが隣接するタイルの最初のブリックとマージされます。
XNUMX番目(下)の行のブリックはオフセットされているため、行にはXNUMXつの半分のブリックとXNUMXつの全体のブリックが含まれます。 この場合、半分の幅のレンガをマージして、開始または終了にギャップがないようにし、隣接するパターンタイルのレンガとシームレスに流れるようにします。 これらのブリックをオフセットするときは、半分のギャップも含める必要があります。 x
値は 55
& 165
それぞれ。
要素の再利用、(-43B、合計154B)
各ブリックをそれほど明示的に定義するのは非効率的なようです。 代わりに形状を再利用してSVGパターンを最適化する方法はありませんか?
SVGが <use>
エレメント。 それを使用して別の要素を参照し、その参照された要素をどこにでもレンダリングできます <use>
使用されている。 これにより、最初のブリックを除いて、各ブリックの幅と高さの指定を省略できるため、かなりの数のバイトが節約されます。
いえ、 <use>
少しの価格が付属しています。 つまり、追加する必要があります id
再利用したい要素について。
<rect id="b" width="100" height="30"/>
<use href="#b" x="110"/>
<use href="#b" x="-55" y="40"/>
<use href="#b" x="55" y="40"/>
<use href="#b" x="165" y="40"/>
一番短い id
可能性はXNUMX文字なので、レンガには「b」を選びました。 ザ <use>
要素は次のように配置できます <rect>
、 とともに x
& y
オフセットとしての属性。 各ブリックは全幅なので、に切り替えました <use>
(パターンタイルのXNUMX行目のレンガを明示的に半分にしたことを思い出してください)、ネガティブを使用する必要があります x
XNUMX行目の値を確認し、最後のブリックがタイルからオーバーフローして、ブリック間のシームレスな接続を確認します。 ただし、パターンタイルの外側にあるものはすべて自動的に切り取られるため、これらは問題ありません。
より効率的に書くことができるいくつかの繰り返し文字列を見つけることができますか? 次はそれらに取り組みましょう。
パスへの書き換え(-54B、合計100B)
<path>
おそらくSVGで最も強力な要素です。 「コマンド」を含むほぼすべての形状を描くことができます d
属性。 使用可能なコマンドは20ありますが、必要なのは長方形の最も単純なコマンドだけです。
これが私が着陸した場所です:
<path d="M0 0h100v30h-100z M110 0h100v30h-100 M0 40h45v30h-45z M55 40h100v30h-100z M165 40h55v30h-55z"/>
私は知っている、超奇妙な数字と文字! それらはすべて意味があります、 もちろん。 この特定のケースで何が起こっているかを次に示します。
M{x} {y}
: 座標に基づいてポイントに移動します。z
: 現在のセグメントを閉じます。h{x}
: 現在のポイントから水平線を描画します。x
の記号によって定義される方向にx
。 小文字x
相対座標を示します。v{y}
: 現在のポイントから、次の長さの垂直線を描画します。y
の記号によって定義される方向にy
。 小文字y
相対座標を示します。
このマークアップは、前のマークアップよりもはるかに簡潔です(改行とインデントの空白は、読みやすくするためだけのものです)。 そして、ねえ、私たちはなんとか初期サイズの半分を切り取って、100バイトに到達しました。 それでも、何かが私にこれがもっと小さいかもしれないように感じさせます…
タイルの改訂(-38B、合計62B)
パターンタイルには繰り返し部分がありませんか? 最初の行でレンガ全体が繰り返されていることは明らかですが、XNUMX番目の行はどうですか? 少し見づらいですが、真ん中のレンガを半分に切るとわかりやすくなります。
まあ、真ん中のレンガは正確に半分にカットされていません。 ギャップも考慮する必要があるため、わずかなオフセットがあります。 とにかく、より単純なベースタイルパターンが見つかりました。これは、バイト数が少ないことを意味します。 これはまた、私たちが半分にする必要があることを意味します width
私たちの <pattern>
220から110までの要素。
<pattern id="p" width="110" height="80" patternUnits="userSpaceOnUse"> <!-- pattern content here -->
</pattern>
次に、簡略化されたタイルがどのように描画されるかを見てみましょう。 <path>
:
<path d="M0 0h100v30h-100z M0 40h45v30h-45z M55 40h55v30h-55z"/>
サイズは62バイトに縮小されており、これはすでに元のサイズのXNUMX分のXNUMX未満です。 しかし、私たちにできることがもっとあるのに、なぜここでやめるのですか?
パスコマンドの短縮(-9B、合計53B)
少し深く掘り下げる価値があります <path>
SVGパターンを最適化するためのより多くのヒントを提供するためです。 一緒に仕事をしているときに私が持っていたXNUMXつの誤解 <path>
どのように fill
属性は機能します。 子供の頃にMSペイントでたくさん遊んだことがありますが、無地で塗りつぶしたい図形はすべて閉じなければならない、つまり開いた点がないことを学びました。 そうしないと、塗料が形から漏れてすべてにこぼれます。
ただし、SVGではこれは当てはまりません。 引用させてください スペック 自体:
塗りつぶし操作は、サブパスの最後のポイントをサブパスの最初のポイントに接続するために追加の「closepath」コマンドがパスに追加されたかのように塗りつぶし操作を実行することによって、開いているサブパスを塗りつぶします。
これは、パスを閉じるコマンドを省略できることを意味します(z
)、サブパスは入力時に自動的に閉じられたと見なされるためです。
パスコマンドについて知っておくと便利なもうXNUMXつの点は、大文字と小文字のバリエーションがあることです。 小文字は、相対座標が使用されることを意味します。 大文字は、代わりに絶対座標が使用されることを意味します。
それはそれよりも少しトリッキーです H
& V
コマンドにはXNUMXつの座標しか含まれていないためです。 これらのXNUMXつのコマンドを説明する方法は次のとおりです。
H{x}
: 現在のポイントから座標に水平線を描画しますx
.V{y}
: 現在のポイントから座標に垂直線を描画しますy
.
パターンタイルに最初のレンガを描くときは、 (0,0)
座標。 次に、水平線を描画します (100,0)
と垂直線 (100,30)
、そして最後に、水平線を引きます (0,30)
。 使用しました h-100
最後の行のコマンドですが、これは H0
、これはXNUMXバイトではなくXNUMXバイトです。 XNUMXつの類似したオカレンスを置き換えて、コードを比較することができます <path>
これまで:
<path d="M0 0h100v30H0 M0 40h45v30H0 M55 40h55v30H55"/>
さらに9バイトが削られました—どれだけ小さくできますか?
ブリッジング(-5B、合計48B)
完全に最適化されたSVGパターンの邪魔になる最長のコマンドは、それぞれ4、5、および6バイトを占める「移動」コマンドです。 私たちが持っているXNUMXつの制約は次のとおりです。
パスデータセグメント(存在する場合)は、「moveto」コマンドで開始する必要があります。
しかし、それは大丈夫です。 最初のものはとにかく最短です。 行を入れ替えると、ブリック間を水平方向または垂直方向に移動するだけでよいパス定義を思いつくことができます。 を使用できるとしたらどうでしょうか h
& v
代わりにそこにコマンド M
?
上の図は、XNUMXつの形状をXNUMXつのパスで描画する方法を示しています。 私たちは、 fill
操作は、間の開いている部分を自動的に閉じます (110,0)
& (0,0)
。 この再配置により、XNUMX列目の全幅ブリックの左側にもギャップを移動しました。 コードは次のようになりますが、XNUMX行にXNUMXつのブリックに分割されています。
<path d="M0 0v30h50V0 h10v30h50 v10H10v30h100V0"/>
確かに、48バイトになったことで、絶対最小のソリューションが見つかりましたね。 良い…
数字のトリミング(-4B、合計44B)
寸法に少し柔軟性がある場合は、SVGパターンを最適化する別の小さな方法があります。 私たちはレンガの幅で作業してきました 100
ピクセルですが、それはXNUMXバイトです。 に変更する 90
書き込む必要があるときはいつでもXNUMXバイト少ないことを意味します。 同様に、 10
ピクセル—ただし、次のように変更すると 8
代わりに、これらの発生ごとにXNUMXバイトを保存します。
<path d="M0 0v30h45V0 h8v30h45 v8H8v30h90V0"/>
もちろん、これはパターンの寸法をそれに応じて調整する必要があることも意味します。 最終的に最適化されたSVGパターンコードは次のとおりです。
<pattern id="p" width="98" height="76" patternUnits="userSpaceOnUse"> <path d="M0 0v30h45V0h8v30h45v8H8v30h90V0"/>
</pattern>
上記のスニペットのXNUMX行目(インデントはカウントされていません)は 44バイト。 197回の反復でXNUMXバイトからここに到達しました。 それは分厚いです 77.7%のサイズ縮小!
でも気になりますが…これは本当に可能な限り小さいサイズですか? SVGパターンを最適化するためのすべての可能な方法を検討しましたか?
このコードをさらに縮小するか、SVGパターンを最適化するための代替方法を試してみることをお勧めします。 群衆の叡智で真のグローバルミニマムを見つけられるかどうか見てみたいです!
SVGパターンの作成と最適化の詳細
SVGパターンの作成と最適化について詳しく知りたい場合は、私の記事を読んでください。 SVGフィルターを使用したパターンの作成。 または、60以上のパターンのギャラリーをチェックしたい場合は、 PetitePatternsCodePenコレクション。 最後に、あなたは見ることを歓迎します YouTubeの私のチュートリアル SVGパターンをさらに深く理解するのに役立ちます。
SVGパターンを最小サイズに最適化 最初に公開された CSSトリック。 あなたがすべき ニュースレターを入手する.
- "
- 10
- 100
- 77
- 9
- 98
- 私たちについて
- 絶対の
- NEW
- すべて
- 許可
- 既に
- 別の
- アプローチ
- AREA
- 記事
- 属性
- 利用できます
- 軸
- ビット
- ブラック
- 挑戦する
- 変化する
- 閉まっている
- コード
- コマンドと
- 接続
- 含まれています
- コンテンツ
- 調整する
- 可能性
- 作成
- 電流プローブ
- データ
- より深い
- ダウン
- 終了
- 設立
- すべてのもの
- 例
- 除く
- 実験
- 最後に
- 名
- フィット
- フロー
- 発見
- さらに
- ギャップ
- 受け
- グローバル
- 持って
- 高さ
- 助けます
- こちら
- 強調表示された
- 認定条件
- HTTPS
- 識別する
- 画像
- include
- 含まれました
- IT
- 自体
- 既知の
- 漏れ
- LEARN
- 学んだ
- 活用
- LINE
- 少し
- 見
- 愛
- 作る
- 作成
- マネージド
- math
- マインド
- 他には?
- 最も
- MS
- 数
- 番号
- オフセット
- 良い
- 開いた
- 最適化
- さもないと
- パターン
- 物理的な
- ポイント
- 配置された
- 可能
- 強力な
- かなり
- ブランド
- プロセス
- は、大阪で
- 品質
- 円形
- ランニング
- 前記
- シームレス
- シリーズ
- セッションに
- シェイプ
- 同様の
- 簡単な拡張で
- SIX
- サイズ
- So
- 溶液
- 何か
- スペース
- Spot
- start
- 開始
- サポート
- 会話
- 介して
- top
- トランスペアレント
- チュートリアル
- つかいます
- 値
- 詳しく見る
- W3
- よく見る
- 歓迎
- この試験は
- 以内
- 無し
- 仕事
- ワーキング
- 作品
- 価値
- ユーチューブ