ホームページ >ウェブフロントエンド >CSSチュートリアル >マスクを使用してネストされた正方形のアニメーションチャートを作成する方法

マスクを使用してネストされた正方形のアニメーションチャートを作成する方法

Lisa Kudrow
Lisa Kudrowオリジナル
2025-03-18 11:03:23835ブラウズ

マスクを使用してネストされた正方形のアニメーションチャートを作成する方法

多くの有名なチャートタイプがあります:バー、ドーナツ、ライン、パイ、あなたはそれに名前を付けます。すべての一般的なチャートライブラリはこれらをサポートしています。次に、名前さえ持っていないチャートタイプがあります。相対サイズを視覚化するのに役立つ積み重ねられた(ネストされた)正方形でこの夢のチャートをチェックしてください。

私たちが作っているもの

対話性がなければ、このデザインの作成はかなり簡単です。それを行う1つの方法は、要素(例:SVG 要素、さらにはHTML DIVSなど)をサイズを減らすことです。ここでは、左下角がすべて同じポイントに触れることです。

しかし、私たちがいくつかのインタラクティブ性を紹介すると、物事はよりトリッキーになります。マウスを形状の1つに移動すると、他の人がフェードアウトして離れて移動したいと考えています。

これらの不規則な形状は、長方形とマスクを使用して作成します。および要素を備えたリテラル。マスクがまったく慣れていない場合は、適切な場所にいます。これは紹介レベルの記事です。あなたがもっと味付けされているなら、おそらくこのカットアウト効果はあなたがあなたと一緒に取ることができるトリックです。

さて、開始する前に、カスタムシェイプを使用するためのSVGのより良い代替手段であるかどうか疑問に思うかもしれません。それは間違いなく可能性です!しかし、で形を描くことは威圧的であるか、乱雑になることさえあります。そのため、「より簡単な」要素を使用して、同じ形と効果を得ています。

たとえば、A

 <svg viewbox="0 0 320 320">
  <path d="M320 0H0V56H264V320H320V0Z" fill="#264653"></path>
</svg>

0H0V56が意味がない場合は、構文の徹底的な説明については、「SVG Path Syntax:Illustrated Guide」をチェックしてください。

チャートの基本

このようなデータセットが与えられます:

タイプDataSeTentry = {
  ラベル:文字列;
  値:番号;
};

タイプデータセット= dataSeTentry [];

const rawdataset:dataset = [
  {label: 'bad'、value:1231}、
  {label: 'beginning'、value:6321}、
  {ラベル:「開発」、価値:10028}、
  {ラベル:「完成」、価値:12123}、
  {label: 'exemplary'、value:2120}
];

…私たちはこのようなSVGになりたいです:

 <svg viewbox="0 0 320 320">
  <rect width="320" height="320" y="0" fill="..."> </rect>
  <rect width="264" height="264" y="56" fill="..."> </rect>
  <rect width="167" height="167" y="153" fill="..."> </rect>
  <rect width="56" height="56" y="264" fill="..."> </rect>
  <rect width="32" height="32" y="288" fill="..."> </rect>
</svg>

最高値を決定します

一瞬で、なぜ最高の価値が必要なのかが明らかになります。 Math.max()を使用して取得できます。それは任意の数の引数を受け入れ、セットの最高値を返します。

 const dataseTheSteStValue:number = math.max(
  ... rawdataset.map((entr:datasetentry)=> entry.value)
);

小さなデータセットがあるので、12123を取得することを知ることができます。

長方形の寸法を計算します

デザインを見ると、最高値(12123)を表す長方形がチャートの領域全体をカバーします。

SVGディメンションのために320を任意に選びました。長方形は正方形であるため、幅と高さは等しくなります。 12123を320に等しくするにはどうすればよいですか? 「特別な」価値はどうですか? 6321長方形の大きさはどれくらいですか?

別の言い方をすれば、1つの範囲([0、12123])から別の範囲([0、320])に数値をどのようにマッピングするのでしょうか?または、より数学的な用語では、[a、b]の間隔に変数をどのように拡張しますか?

私たちの目的のために、次のような関数を実装します。

 const remapvalue =(
  値:番号、
  frommin:number、
  frommax:number、
  トミン:番号、
  Tomax:番号
):number => {
  return((value -min) /(frommax -min)) *(Tomax -Tomin)Tomin;
};

RemapValue(1231、0、12123、0、320); // 32
RemapValue(6321、0、12123、0、320); // 167
RemapValue(12123、0、12123、0、320); // 320

値をコード内の同じ範囲にマッピングするため、最小値と最大値を何度も渡す代わりに、ラッパー関数を作成できます。

 const valeremapper =(
  frommin:number、
  frommax:number、
  トミン:番号、
  Tomax:番号
)=> {
  return(value:number):number => {
    REMAPVALUE(Value、FromMin、FromMax、Tomin、Tomax);
  };
};

const remapdatasetvaluetosvgdimension = valueremapper(
  0、
  DataSeThighestValue、
  0、
  svgdimension
);

このように使用できます。

 remapdatasetvaluetosvgdimension(1231); // 32
remapdatasetvaluetosvgdimension(6321); // 167
remapdatasetvaluetosvgdimension(12123); // 320

DOM要素の作成と挿入

DOMの操作と何が関係しているのか。 と5つの要素を作成し、属性を設定し、DOMに追加する必要があります。基本的なCreateElementNS、SetAttribute、およびAppendChild関数でこれをすべて行うことができます。

より一般的なCreateElementの代わりにCreateElementnsを使用していることに注意してください。これは、SVGを使用しているためです。 HTMLとSVG要素には異なる仕様があるため、異なる名前空間URIに該当します。 CreateElementがHTMLネームスペースを便利に使用していることがあります!したがって、SVGを作成するには、この冗長でなければなりません。

 document.createElementns( 'http://www.w3.org/2000/svg'、 'svg')svgsvgelement;

確かに、別のヘルパー関数を作成できます。

 const createsvgnselement =(要素:文字列):svgelement => {
  return document.createElementns( 'http://www.w3.org/2000/svg'、element);
};

長方形をDOMに追加している場合、彼らの注文に注意を払わなければなりません。それ以外の場合は、Zインデックスを明示的に指定する必要があります。最初の長方形は最大でなければならず、最後の長方形は最小でなければなりません。ループの前にデータをソートするのが最善です。

 const data = rawdataset.sort(
  (A:DataSetEntry、B:DataSetEntry)=> B.Value -A.Value
);

data.foreach((d:datasetentry、index:number)=> {
  const rect:svgrectelement = createSvgnselement( 'rect')as svgreectelement;
  const rectdimension:number = remapdatasetvaluetosvgdimension(d.value);

  rect.setattribute( 'width'、 `$ {rectdimension}`);
  rect.setattribute( 'height'、 `$ {rectdimension}`);
  rect.setattribute( 'y'、 `$ {svgdimension -rectdimension}`);

  svg.appendChild(rect);
});

座標系は左上から始まります。それが[0、0]です。私たちは常に左側から長方形を描くつもりです。水平位置を制御するX属性はデフォルトであるため、設定する必要はありません。 y属性は垂直位置を制御します。

すべての長方形が左の角に触れるのと同じポイントから生まれているという視覚的な印象を与えるために、いわば長方形を押し下げなければなりません。いくらですか?長方形が埋められない正確な量。そして、その値は、チャートの次元と特定の長方形の違いです。すべてのビットをまとめると、これに終わります。

CSSを使用して、このデモにアニメーションのコードをすでに追加しました。

カットアウト長方形

長方形を不規則な形に変える必要があります。そのようなものは7番のように見えます。

「不足している部品」に焦点を合わせると、すでに取り組んでいるのと同じ長方形の切り欠きがわかります。

私たちはそれらの切り抜きを隠したいです。それが、私たちが望むL字型で終わる方法です。

マスキング101

マスクはあなたが定義し、後で要素に適用するものです。通常、マスクは属する要素にインラリングされています。そして、一般的に、マスクを要素に適用するためにそれを参照する必要があるため、一意のIDが必要です。

 <svg>
  
    
  
</svg>

タグでは、実際のマスクとして機能する形状を配置します。また、要素にマスク属性を適用します。

 <svg>
  
    
  
  <rect mask="url(#mycleverlynamedmask)"> </rect>
</svg>

マスクを定義または適用する唯一の方法ではありませんが、このデモにとって最も簡単な方法です。マスクを生成するためにコードを作成する前に、少し実験をしましょう。

既存の長方形のサイズに合った切り抜き領域をカバーしたいと言いました。最大の要素を取得し、以前の長方形をマスクとして適用すると、このコードになります。

 <svg viewbox="0 0 320 320">
  
    <rect width="264" height="264" y="56" fill=""> </rect>
  
  <rect width="320" height="320" y="0" fill="#264653" mask="url(#themask)"> </rect>
</svg>

マスク内の要素には充填値が必要です。それはどうあるべきですか?選択した充填値(色)に基づいて、まったく異なる結果が表示されます。

白い塗りつぶし

塗りつぶしに白い値を使用する場合、これを取得します。

さて、私たちの大きな長方形は、マスキング長方形と同じ次元です。私たちが望んでいたものではありません。

黒い塗りつぶし

代わりに黒い値を使用する場合、次のように見えます。

何も見えません。それは、黒で満たされているものが目に見えないものだからです。白と黒の詰め物を使用してマスクの可視性を制御します。破線は、目に見えない領域の寸法を参照するための視覚援助としてあります。

灰色の塗りつぶし

ここで、白と黒の中にあるものを使ってみましょう。

完全に不透明でも固体でもありません。それは透明です。そのため、ここでは、バックポケットに保管するための良いトリックである白と黒の値とは異なるものを使用することで、ここで「可視性の程度」を制御できることがわかりました。

最後のビット

これが私たちがこれまでにマスクについてカバーし、学んだことです:

  • 内部の要素は、マスクされた領域の寸法を制御します。
  • マスクされた領域の内容物を見える、見えない、または透明にすることができます。

マスクには1つの形状しか使用していませんが、汎用HTMLタグと同様に、必要なだけ多くの子供の要素をネストすることができます。実際、私たちが望むものを達成するためのトリックは、2つのSVG 要素を使用することです。私たちはそれらを他方の上に積み重ねなければなりません:

 <svg viewbox="0 0 320 320">
  
    <rect width="320" height="320" y="0" fill="???"> </rect>
    <rect width="264" height="264" y="56" fill="???"> </rect>
  
  <rect width="320" height="320" y="0" fill="#264653" mask="url(#maskw320)"> </rect>
</svg>

マスキングの長方形の1つは白で満たされています。もう1つは黒で満たされています。ルールを知っていても、可能性を試してみましょう。

 
  <rect width="320" height="320" y="0" fill="black"> </rect>
  <rect width="264" height="264" y="56" fill="white"> </rect>

は最大の要素の寸法であり、最大の要素は黒で満たされています。それは、その地域のすべてのものが目に見えないことを意味します。そして、より小さな長方形の下のすべてが見えます。

さて、黒い長方形が上にある場所をひっくり返しましょう:

 
  <rect width="320" height="320" y="0" fill="white"> </rect>
  <rect width="264" height="264" y="56" fill="black"> </rect>

これが私たちが望むものです!

最大の白で満たされた長方形のすべてのものが見えますが、小さな黒い長方形がその上にあり(Z軸上の私たちに近い)、その部分を隠しています。

マスクを生成します

私たちは何をしなければならないかを知ったので、比較的簡単にマスクを作成できます。そもそも色付きの長方形を生成した方法に似ています。マスクと2つの長方形を作成するセカンダリループを作成します。

今回は、rectsを直接SVGに追加する代わりに、マスクに追加します。

 data.foreach((d:datasetentry、index:number)=> {
  const mask:svgmaskelement = createsvgnelement( 'mask')as svgmaskelement;

  const rectdimension:number = remapdatasetvaluetosvgdimension(d.value);
  const rect:svgrectelement = createSvgnselement( 'rect')as svgreectelement;

  rect.setattribute( 'width'、 `$ {rectdimension}`);
  // ...残りの属性を設定します...

  mask.setattribute( 'id'、 `maskw $ {rectdimension.tofixed()}`);

  mask.appendChild(rect);

  // ...より小さな長方形の属性の作成と設定...

  svg.appendchild(マスク);
});

data.foreach((d:datasetentry、index:number)=> {
    // ...色付きの長方形を生成するためのコード...
});

インデックスをマスクのIDとして使用できますが、これは少なくとも私にとっては読みやすいオプションのようです。

 mask.setattribute( 'id'、 `maskw $ {rectdimension.tofixed()}`); // maskw320、masw240、...

マスクに小さな長方形を追加することに関して、長方形の値を以前に最高から最低まで注文したため、必要な値に簡単にアクセスできます。つまり、ループの次の要素は、長方形が小さいことを意味します。これは参照する必要があります。そして、私たちはそのインデックスによってそれを行うことができます。

 // ...マスクと長方形を作成した前の部分...

const smallerectindex = index 1;

//私たちが最小にいるときに次のものはありません
if(data [smallerrectindex]!== undefined){
  const smallerrectdimension:number = remapdatasetvaluetosvgdimension(
    データ[SmallerrectIndex] .Value
  );
  const smallerrect:svgrectelement = createSvgnselement(
    「長方」
  )svgreectelementとして。

  // ...長方形の属性の設定...

  Mask.AppendChild(Smallerrect);
}

svg.appendchild(マスク);

残っているのは、元のループの色付き長方形にマスク属性を追加することです。選択した形式と一致するはずです。

 rect.setattribute( 'mask'、 `url(#maskw $ {rectdimension.tofixed()})`); // maskw320、maskw240、...

最終結果

そして、私たちは終わりました!ネストされた正方形で作られたチャートを正常に作成しました。マウスホバーでもバラバラになります。そして、それがかかったのは、各正方形の切り抜き領域を描くために要素を使用したSVGだけでした。

以上がマスクを使用してネストされた正方形のアニメーションチャートを作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。