VueはCanvasを使用してランダムなサイズで重なり合わない円を生成します

VueはCanvasを使用してランダムなサイズで重なり合わない円を生成します

キャンバス関連文書

  • キャンバスAPI
  • CANVAS クイックチェックテーブル

エフェクト画像表示

1つ目はランダムな色とランダムなサイズを組み合わせた効果です

2 つ目は、ランダムなサイズ分散効果を持つランダムな背景画像です (ここで使用した画像はすべて同じなので、異なる画像は表示されません)

ケースの完全なコード

  • この例は Vue を使用して実装されています。その他の方法は Vue と同様です。対応する構文を変更することで効果を実現できます。
  • このケースではVueの親子コンポーネントの値転送を使用しています

親コンポーネントコード

<テンプレート>
  <div id="ホーム">
      <div class="タグ" ref="タグ">
        <circle-box :parentClientWidth="親クライアントの幅" :parentClientHeight="親クライアントの高さ" :dataList="データリスト"></circle-box>
      </div>
  </div>
</テンプレート>
<スクリプト>
'@/components/content/circle/Circle.vue' から CircleBox をインポートします。
エクスポートデフォルト{
  コンポーネント: { CircleBox },
  データ() {
    戻る {
      親クライアント幅: 0,
      親クライアントの高さ: 0,
      // キャンバスシミュレーションデータ dataList: [
       {
          フォロー: 1,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 2,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 3,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 4,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 5,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 6,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 7,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 8,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 9,
          画像: 'http://39.99.139.115/demo/RB5.png'
        },
        {
          フォロー: 10,
          画像: 'http://39.99.139.115/demo/RB5.png'
        }
      ]、
    };
  },
  
  作成された() {},
  
  マウント() {
    this.getWidth();
  },
  
  メソッド: {
    // 親ボックスの幅と高さを取得する getWidth() {
      this.parentClientWidth = this.$refs.tags.clientWidth;
      this.parentClientHeight = this.$refs.tags.clientHeight;
      console.log(this.$refs.tags.clientWidth);
    }
  },
};
</スクリプト>

サブコンポーネントコード

<テンプレート>
  <div>
    <canvas id="myCanvas" :width="親クライアントの幅 + 'px'" :height="親クライアントの高さ + 'px'"></canvas>
  </div>
</テンプレート>
<スクリプト>
エクスポートデフォルト{
  // データを受け取る props: ['parentClientWidth', 'parentClientHeight', 'dataList'],

  データ() {
    戻る {
      dataListコピー: this.dataList
    }
  },
  
  作成された() {
    this.$nextTick(() => {
      // this.circleInfo() を初期化する
    })
  },
  
  マウント() {},
  
  メソッド: {
    サークル情報() {
      それを = これとする
      クラス Circle {
        コンストラクタ(x, y, r, 色) {
          this.x = x
          this.y = y
          r = r です
          this.c = 色 ? 色: this.getRandomColor()
        }

        // ランダムカラー getRandomColor() {
          r = Math.floor(Math.random() * 100) + 155 とします。
          g = Math.floor(Math.random() * 100) + 155 とします。
          b = Math.floor(Math.random() * 100) + 155 とします。
          `rgb(${r},${g},${b})` を返す
        }
      }

      クラス RandomCircle {
        コンストラクタ(obj) {
          this.c = document.getElementById(obj.id)
          コンソールログ(this.c)

          this.ctx = this.c.getContext('2d')
          this.dWidth = this.c.width
          this.dHeight = this.c.height
          this.fix = obj.fix || 真

          this.minMargin = obj.minMargin || 20
          this.minRadius = obj.minRadius || 30
          this.radiuArr = obj.radiuArr || [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30]

          this.total = obj.total || 10

          this.circleArray = []
          this.circleNumber = 1
        }

        1つの円を描画します(c, インデックス) {
          // コンソール.log(c, インデックス)
          ctx = this.ctx とします。

          ctx.beginPath()

          ctx.strokeStyle = cc
          ctx.fillStyle = cc
          // 円を描く ctx.arc(cx, cy, cr, 0, 2 * Math.PI)

          ctx.ストローク()
          ctx.fill()

          // ctx.textAlign = 'center'
          // ctx.textBaseline = 'middle'

          // ctx.fillStyle = '黒'
          // ctx.font = '1rem Microsoft YaHei'
          // ctx.fillText(that.dataListCopy[index].follow, cx, cy - 10) // 円内のテキスト let img = new Image()
          img.src = that.dataListCopy[インデックス].image
          ctx.drawImage(img, cx - cr, cy - cr, cr * 2, cr * 2)

          this.circleNumber++
        }

        チェック(x, y, r) {
          戻り値 !(x + r > this.dWidth || x - r < 0 || y + r > this.dHeight || y - r < 0)
        }

        // 新しい円の半径を取得します。主に半径と最も近い円の間の距離を決定します。getR(x, y) {
          if (this.circleArray.length === 0) は Math.floor(Math.random() * 20 + 20) を返します

          lenArr = this.circleArray.map((c) => { とします。
            xSpan = cx - x とします。
            ySpan = cy - yとします

            Math.floor(Math.sqrt(Math.pow(xSpan, 2) + Math.pow(ySpan, 2))) - cr を返す
          })

          minCircleLen = Math.min(...lenArr) とします。
          minC = this.circleArray[lenArr.indexOf(minCircleLen)]とします。
          tempR = this.fix ? this.radiuArr[this.circleArray.length] : minCircleLen - this.minMargin とします。
          bool = this.fix ? tempR <= minCircleLen - minC.r : tempR >= this.minRadius とします。

          bool を返す ? tempR : false
        }

        // ランダムに生成された中心を持つ円を生成します。
        // 200回連続生成しても半径が適切でない場合は、プロセスを終了します createOneCircle() {
          x、y、rとします
          createCircleTimes = 0 とします

          (真)の間{
            サークルタイムを作成++
            x = Math.floor(Math.random() * this.dWidth)
            y = Math.floor(Math.random() * this.dHeight)

            TR = this.getR(x, y) とします。
            もし(!TR){
              続く
            } それ以外 {
              r = TR
            }
            if (this.check(x, y, r) || createCircleTimes > 200) {
              壊す
            }
          }

          this.check(x, y, r) && this.circleArray.push(新しいCircle(x, y, r))
        }

        // 新しい円の生成が 100 回失敗した場合は、スキームを終了します。
        // 生成された 100 個のソリューションのいずれも適切でない場合は、プロセスを終了します。
        初期化() {
          n = 0とする

          (this.circleArray.length < this.total) の間 {
            this.circleArray = []

            i = 0とする
            (this.circleArray.length < this.total) の間 {
              this.createOneCircle()
              私は++
              (i >= 100) の場合 {
                壊す
              }
            }

            ++ いいえ

            (n > 100)の場合{
              壊す
            }
          }

          // 半径に応じて大きい円から小さい円まで描きます。
          this.circleArray
            .sort((a, b) => br - ar)
            .forEach((c, インデックス) => {
              this.drawOneCircle(c, インデックス)
            })
        }
      }
      // コンソールにログ出力します。

      const p = 新しいランダムサークル({
        id: 'myCanvas',
        total: that.dataListCopy.length //構成数量})

      p.init()
      コンソールログ(p)
      コンソールログ(p.circleArray)
    }
  }
}
</スクリプト>

要約する

Vue が Canvas を使用してランダムなサイズの重なり合わない円を生成する方法については、これで終わりです。Vue が Canvas を使用してランダムな円を生成する方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Vueはキャンバスを使用して画像圧縮アップロードを実現します
  • vue+canvasでタイムラインを描く方法
  • VUE+CanvasはシンプルなGobangゲームの全プロセスを実現します
  • VUE+Canvasは、インゴットを受け取る富の神のゲームを実装します
  • VUE と Canvas を使用して Thunder Fighter タイピング ゲームを実装する方法
  • VUE+Canvasはデスクトップピンボールブロック破壊ゲームのサンプルコードを実装します
  • Vueはマウスを使ってキャンバス上に四角形を描きます
  • Vueはキャンバスを使用してモバイル手書き署名を実装します
  • Vue+canvasでパズルゲームを実現
  • Vueはキャンバスの手書き入力を使用して中国語を認識します

<<:  ボタンをクリックした後のCSS読み込み効果を実現する

>>:  MySQLでテーブルを作成し、フィールドコメントを追加する方法

推薦する

Alibaba Cloud Server Linux システムは Tomcat を構築して Web プロジェクトを展開します

私は全体のプロセスを 4 つのステップに分けます。 JDKをダウンロードしてインストールするTomc...

Vue+element はローカル検索機能付きのドロップダウン メニューを実装します

必要:バックエンドは配列オブジェクトを返し、それがフロントエンドで配列に結合されます。配列は名前に従...

mysql8.0.12 でルートパスワードをリセットする方法

データベースをインストールした後、誤ってインストール ウィンドウを閉じたり、長期間 root ユーザ...

ウェブサイトのAboutページの紹介コンテンツの書き方

公式、電子商取引、ソーシャル ネットワーキング、個人のいずれの Web サイトでも、訪問者に貴重な時...

順序再構築に関する簡単な説明: MySQL シャーディング

目次1. 目的2. 環境整備1. 基本情報2. データベース環境の準備3. データベースを構築し、サ...

MySQL 8.0.24 リリースノートのいくつかの改善点

目次1. 接続管理2. オプティマイザレベルでの改善3. 機能の改善4. パフォーマンススキーマの最...

JavaScript の手ぶれ補正とスロットリングの説明

目次安定スロットリング要約する安定自動ドアは人を感知してドアを開け、5 秒間のカウントダウンを開始し...

Mysql GTID Mha 設定方法

Gtid + Mha + Binlog サーバー構成: 1: テスト環境OS: CentOS 6.5...

ウェブデザイン:大量の素材の正確な配置と使用

3回の暗記により、大量の資材の正確な場所と目的を記憶でき、その使いやすさが向上します。 これは単なる...

Vue3 の組み合わせ API における setup、ref、reactive の完全な使用方法

1. セットアップを始める次のコード関数を簡単に紹介します。 ref 関数を使用して変数の変更を監視...

CSSの固定位置属性の詳細な説明

モバイル アプリを開発する場合、Web サイトが特定の高さまでスクロールしたときにコンテンツの一部を...

MySQL インデックスの最適化: ページング探索の詳細な紹介

目次MySQL インデックス最適化ページングの調査ケース1ケース2 MySQL インデックス最適化ペ...

シンプルなフロントエンドのページング効果を実現する js

比較的シンプルな業務のプロジェクトもありますが、フロントエンドのページングを多用します。プラグインの...

MySQL テーブルとデータベースでデータを分割する方法

目次1. 縦方向のスライス1.1 垂直データベース1.2 垂直テーブル分割2. 水平(横断)セグメン...