最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue使用Canvas生成隨機(jī)大小且不重疊圓

 更新時(shí)間:2021年11月03日 15:56:15   作者:阿怪沒(méi)有腦袋  
Canvas是HTML5中新增的元素,專門用來(lái)繪制圖形,下面這篇文章主要給大家介紹了關(guān)于Vue使用Canvas生成隨機(jī)大小且不重疊圓的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

canvas 相關(guān)文檔

效果圖展示

第一張是 隨機(jī)顏色隨機(jī)大小聚合 在一起效果

第二張是 隨機(jī)背景圖片隨機(jī)大小分散 效果(這里我使用的圖片都一樣所以沒(méi)展現(xiàn)出不同圖片)

案例完整代碼

  • 本實(shí)例是用 vue 來(lái)實(shí)現(xiàn)的,其他方法和 vue 類似,改為對(duì)應(yīng)的語(yǔ)法即可實(shí)現(xiàn)效果。
  • 案例用到了 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 模擬數(shù)據(jù)
      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 {
  // 接收數(shù)據(jù)
  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()
        }

        // 隨機(jī)顏色
        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},$)`
        }
      }

      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) //圓內(nèi)文字

          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)
        }

        // 獲取一個(gè)新圓的半徑,主要判斷半徑與最近的一個(gè)圓的距離
        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
        }

        // 生成一個(gè)圓,隨機(jī)生成圓心。
        // 如果連續(xù)生成200次半徑都沒(méi)有合適的話,終止進(jìn)程
        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種方案都沒(méi)有合適可用的話,終止進(jìn)程。
        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
            }
          }

          // 根據(jù)半徑從大到小畫圓。
          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 // 配置數(shù)量
      })

      p.init()
      console.log(p)
      console.log(p.circleArray)
    }
  }
}
</script>

總結(jié)

到此這篇關(guān)于Vue使用Canvas生成隨機(jī)大小且不重疊圓的文章就介紹到這了,更多相關(guān)Vue用Canvas生成隨機(jī)圓內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 實(shí)例講解vue源碼架構(gòu)

    實(shí)例講解vue源碼架構(gòu)

    在本篇文章中小編給大家分享了關(guān)于vue源碼架構(gòu)的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們學(xué)習(xí)下。
    2019-01-01
  • vue3中element-plus表格搜索過(guò)濾數(shù)據(jù)

    vue3中element-plus表格搜索過(guò)濾數(shù)據(jù)

    本文主要介紹了vue3中element-plus表格搜索過(guò)濾數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • vue監(jiān)聽(tīng)對(duì)象及對(duì)象屬性問(wèn)題

    vue監(jiān)聽(tīng)對(duì)象及對(duì)象屬性問(wèn)題

    這篇文章主要介紹了vue監(jiān)聽(tīng)對(duì)象及對(duì)象屬性問(wèn)題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • Vuex的實(shí)戰(zhàn)使用詳解

    Vuex的實(shí)戰(zhàn)使用詳解

    這篇文章主要介紹了Vuex的實(shí)戰(zhàn)使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • 使用Vue指令實(shí)現(xiàn)Markdown渲染和代碼高亮

    使用Vue指令實(shí)現(xiàn)Markdown渲染和代碼高亮

    在前端開(kāi)發(fā)中,我們經(jīng)常需要將Markdown格式的文本渲染成HTML并展示在頁(yè)面上,同時(shí)還希望能夠?qū)Υa塊進(jìn)行高亮顯示,今天我將分享一段代碼,通過(guò)Vue指令實(shí)現(xiàn)了這個(gè)功能,需要的朋友可以參考下
    2023-09-09
  • vue實(shí)現(xiàn)商品列表的無(wú)限加載思路和步驟詳解

    vue實(shí)現(xiàn)商品列表的無(wú)限加載思路和步驟詳解

    這篇文章主要介紹了vue實(shí)現(xiàn)商品列表的無(wú)限加載思路和步驟詳解,基礎(chǔ)思路是觸底條件滿足之后 page++,拉取下一頁(yè)數(shù)據(jù),結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下,
    2024-06-06
  • 詳解Vue組件實(shí)現(xiàn)tips的總結(jié)

    詳解Vue組件實(shí)現(xiàn)tips的總結(jié)

    這篇文章主要介紹了詳解Vue組件實(shí)現(xiàn)tips的總結(jié),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • vue中下載文件后無(wú)法打開(kāi)的坑及解決

    vue中下載文件后無(wú)法打開(kāi)的坑及解決

    這篇文章主要介紹了vue中下載文件后無(wú)法打開(kāi)的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • vue-amap安裝和用法步驟

    vue-amap安裝和用法步驟

    vue-amap是餓了么開(kāi)源的一套基于?Vue?2.0?和高德地圖的地圖組件。接下來(lái)通過(guò)本文給大家介紹vue-amap安裝和使用,需要的朋友可以參考下
    2021-12-12
  • uni-app中App與webview雙向?qū)崟r(shí)通信詳細(xì)代碼示例

    uni-app中App與webview雙向?qū)崟r(shí)通信詳細(xì)代碼示例

    在移動(dòng)應(yīng)用開(kāi)發(fā)中,uni-app是一個(gè)非常流行的框架,它允許開(kāi)發(fā)者使用一套代碼庫(kù)構(gòu)建多端應(yīng)用,包括H5、小程序、App等,這篇文章主要給大家介紹了關(guān)于uni-app中App與webview雙向?qū)崟r(shí)通信的相關(guān)資料,需要的朋友可以參考下
    2024-07-07

最新評(píng)論

文安县| 漯河市| 泽普县| 汉寿县| 沽源县| 呼伦贝尔市| 古蔺县| 海门市| 乌鲁木齐县| 乐东| 万州区| 佛冈县| 玛沁县| 莱阳市| 广宁县| 巨野县| 靖边县| 都昌县| 霍山县| 夏河县| 桐柏县| 仙游县| 翼城县| 南宫市| 佳木斯市| 长沙市| 桂阳县| 肇庆市| 沅江市| 启东市| 昌平区| 玛曲县| 申扎县| 淅川县| 富锦市| 元氏县| 休宁县| 夹江县| 昆山市| 营山县| 健康|