vue 画圆 不重叠 随机大小 随机颜色 源码实例

52 篇文章 1 订阅
35 篇文章 0 订阅
该博客介绍了如何使用JavaScript在canvas上动态生成不重叠的随机圆圈。通过创建Circle和RandomCircle类,实现了计算新圆半径以避免与其他圆碰撞的算法,最终绘制出具有特定数量和样式的圆圈。博客内容包括代码实例和效果展示,适合前端开发者学习。
摘要由CSDN通过智能技术生成

效果图:

实例代码:

methods:{

 

circleInfo: function() {

      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)

          debugger

          this.ctx = this.c.getContext("2d");

          this.dWidth = this.c.width;

          this.dHeight = this.c.height;

 

          this.fix = obj.fix || false;

          this.minMargin = obj.minMargin || 10;

          this.minRadius = obj.minRadius || 30;

          this.radiuArr = obj.radiuArr || [80,70,60,50,45,40,40,35,35,30,];

          this.total = obj.total || 10;

          this.circleArray = [];

          this.circleNumber = 1;

        }

 

        drawOneCircle(c) {

          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.fillStyle = "black";

          ctx.fillText("No:" + this.circleNumber, c.x - 10, c.y - 5); //圆内文字

          ctx.fillText("R:" + c.r, c.x - 10, c.y + 5);

          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 + 80);

          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) => {

              this.drawOneCircle(c);

            });

        }

      }

 

      // console.log(this.circle);

 

      const p = new RandomCircle({

        id: "myCanvas",

        total: 10, //配置数量

      });

      p.init();

      console.log(p);

 

      console.log(p.circleArray);

    },

},


created() {

    this.$nextTick(()=>{

            this.circleInfo();//初始化

    })

  },

 

 

如果帮到你了,帮忙点个赞,谢谢, 有任何疑问可以留言哦

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值