中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue怎么使用Canvas生成隨機大小且不重疊圓

發布時間:2021-11-03 17:12:56 來源:億速云 閱讀:301 作者:iii 欄目:開發技術

本篇內容介紹了“Vue怎么使用Canvas生成隨機大小且不重疊圓”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    案例完整代碼

    • 本實例是用 vue 來實現的,其他方法和 vue 類似,改為對應的語法即可實現效果。

    • 案例用到了 vue 父子組件傳值

    父組件代碼

    <template>
      <div id="home">
          <div class="tags" ref="tags">
            <circle-box :parentClientWidth="parentClientWidth" :parentClientHeight="parentClientHeight" :dataList="dataList"></circle-box>
          </div>
      </div>
    </template>
    <script>
    import CircleBox from '@/components/content/circle/Circle.vue'
    export default {
      components: { CircleBox },
      data() {
        return {
          parentClientWidth: 0,
          parentClientHeight: 0,
          // canvas 模擬數據
          dataList: [
           {
              follow: 1,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 2,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 3,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 4,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 5,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 6,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 7,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 8,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 9,
              image: 'http://39.99.139.115/demo/RB5.png'
            },
            {
              follow: 10,
              image: 'http://39.99.139.115/demo/RB5.png'
            }
          ],
        };
      },
      
      created() {},
      
      mounted() {
        this.getWidth();
      },
      
      methods: {
        // 獲取父盒子的寬度和高度
        getWidth() {
          this.parentClientWidth = this.$refs.tags.clientWidth;
          this.parentClientHeight = this.$refs.tags.clientHeight;
          console.log(this.$refs.tags.clientWidth);
        }
      },
    };
    </script>

    子組件代碼

    <template>
      <div>
        <canvas id="myCanvas" :width="parentClientWidth + 'px'" :height="parentClientHeight + 'px'"></canvas>
      </div>
    </template>
    <script>
    export default {
      // 接收數據
      props: ['parentClientWidth', 'parentClientHeight', 'dataList'],
    
      data() {
        return {
          dataListCopy: this.dataList
        }
      },
      
      created() {
        this.$nextTick(() => {
          // 初始化
          this.circleInfo()
        })
      },
      
      mounted() {},
      
      methods: {
        circleInfo() {
          let that = this
          class Circle {
            constructor(x, y, r, color) {
              this.x = x
              this.y = y
              this.r = r
              this.c = color ? color : this.getRandomColor()
            }
    
            // 隨機顏色
            getRandomColor() {
              let r = Math.floor(Math.random() * 100) + 155
              let g = Math.floor(Math.random() * 100) + 155
              let b = Math.floor(Math.random() * 100) + 155
              return `rgb(${r},${g},${b})`
            }
          }
    
          class RandomCircle {
            constructor(obj) {
              this.c = document.getElementById(obj.id)
              console.log(this.c)
    
              this.ctx = this.c.getContext('2d')
              this.dWidth = this.c.width
              this.dHeight = this.c.height
              this.fix = obj.fix || true
    
              this.minMargin = obj.minMargin || 20
              this.minRadius = obj.minRadius || 30
              this.radiuArr = obj.radiuArr || [30, 30, 30, 30, 30, 30, 30, 30, 30, 30]
    
              this.total = obj.total || 10
    
              this.circleArray = []
              this.circleNumber = 1
            }
    
            drawOneCircle(c, index) {
              // console.log(c, index)
              let ctx = this.ctx
    
              ctx.beginPath()
    
              ctx.strokeStyle = c.c
              ctx.fillStyle = c.c
              // 畫圓
              ctx.arc(c.x, c.y, c.r, 0, 2 * Math.PI)
    
              ctx.stroke()
              ctx.fill()
    
              // ctx.textAlign = 'center'
              // ctx.textBaseline = 'middle'
    
              // ctx.fillStyle = 'black'
              // ctx.font = '1rem 微軟雅黑'
              // ctx.fillText(that.dataListCopy[index].follow, c.x, c.y - 10) //圓內文字
    
              let img = new Image()
              img.src = that.dataListCopy[index].image
              ctx.drawImage(img, c.x - c.r, c.y - c.r, c.r * 2, c.r * 2)
    
              this.circleNumber++
            }
    
            check(x, y, r) {
              return !(x + r > this.dWidth || x - r < 0 || y + r > this.dHeight || y - r < 0)
            }
    
            // 獲取一個新圓的半徑,主要判斷半徑與最近的一個圓的距離
            getR(x, y) {
              if (this.circleArray.length === 0) return Math.floor(Math.random() * 20 + 20)
    
              let lenArr = this.circleArray.map((c) => {
                let xSpan = c.x - x
                let ySpan = c.y - y
    
                return Math.floor(Math.sqrt(Math.pow(xSpan, 2) + Math.pow(ySpan, 2))) - c.r
              })
    
              let minCircleLen = Math.min(...lenArr)
              let minC = this.circleArray[lenArr.indexOf(minCircleLen)]
              let tempR = this.fix ? this.radiuArr[this.circleArray.length] : minCircleLen - this.minMargin
              let bool = this.fix ? tempR <= minCircleLen - minC.r : tempR >= this.minRadius
    
              return bool ? tempR : false
            }
    
            // 生成一個圓,隨機生成圓心。
            // 如果連續生成200次半徑都沒有合適的話,終止進程
            createOneCircle() {
              let x, y, r
              let createCircleTimes = 0
    
              while (true) {
                createCircleTimes++
                x = Math.floor(Math.random() * this.dWidth)
                y = Math.floor(Math.random() * this.dHeight)
    
                let TR = this.getR(x, y)
                if (!TR) {
                  continue
                } else {
                  r = TR
                }
                if (this.check(x, y, r) || createCircleTimes > 200) {
                  break
                }
              }
    
              this.check(x, y, r) && this.circleArray.push(new Circle(x, y, r))
            }
    
            // 如果生成100次新圓都失敗的話,終止方案。
            // 如果生成100種方案都沒有合適可用的話,終止進程。
            init() {
              let n = 0
    
              while (this.circleArray.length < this.total) {
                this.circleArray = []
    
                let i = 0
                while (this.circleArray.length < this.total) {
                  this.createOneCircle()
                  i++
                  if (i >= 100) {
                    break
                  }
                }
    
                n++
    
                if (n > 100) {
                  break
                }
              }
    
              // 根據半徑從大到小畫圓。
              this.circleArray
                .sort((a, b) => b.r - a.r)
                .forEach((c, index) => {
                  this.drawOneCircle(c, index)
                })
            }
          }
          // console.log(this.circle);
    
          const p = new RandomCircle({
            id: 'myCanvas',
            total: that.dataListCopy.length // 配置數量
          })
    
          p.init()
          console.log(p)
          console.log(p.circleArray)
        }
      }
    }
    </script>

    “Vue怎么使用Canvas生成隨機大小且不重疊圓”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    永顺县| 贡山| 开封县| 三原县| 武威市| 富源县| 修水县| 香港| 雷山县| 黑龙江省| 宜兴市| 商洛市| 阿拉善左旗| 广南县| 饶阳县| 华安县| 滦南县| 贵溪市| 泰顺县| 吉首市| 临武县| 大新县| 利川市| 罗山县| 遂昌县| 长治市| 新竹县| 泾川县| 茶陵县| 灌云县| 礼泉县| 通州市| 西乡县| 霍邱县| 玉树县| 大埔县| 巴林右旗| 台山市| 元氏县| 巴南区| 库车县|