canvas 画不重叠的圆,

1. 前言

     使用canvas在一个矩形内画不重复的圆,须要注意两点javascript

  1. 使用随机数(Math.random())生成的坐标、半径和宽高比较
  2. 求出两个圆心的距离

2. html代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            background: #efefef;
        }

        .box {
            width: 500px;
            height: 500px;
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            margin: auto;
            border: 1px solid #999;
        }
    </style>
</head>

<body>
    <div class="box" id="box"></div>
</body>
<script src="./jquery.min.js"></script>
<script src="./circleDraw.js"></script>
<script>
    $('#box').draw({
        number: 50, // 圆的个数
        colors: ['#FF8E56', '#00A0FF', '#0ADFCD', '#1678D3', '#00D069', '#ECB700'],
        text: ['Chrome', '火狐', 'Opera', '360', '猎豹', 'safari']
    });
</script>

</html>

3. circleDraw.js

(function ($) {
    $.fn.extend({
        draw: function (option) {
            if (!option) {
                option = {};
            }
            option = $.extend({}, $.fn.draw.defaultOption, option);
            try{
                if(!(option.colors instanceof Array) || !(option.text instanceof Array)){
                  throw Error('colors、text 接受的参数是 Array[string]');
                }
            }catch(e){
                console.log(e.stack)
            }
            var that = $(this);
            try{
                var width = $(that).width(),
                height = $(that).height();
                if(!(width && height)){
                  throw Error('请设置宽高度');
                }
            }catch(e){
                console.log(e.stack)
            }
            $(that).append("<canvas width="+width+" height="+height+"></canvas>");
            var obj = $(that).find('canvas')[0];
            ctx = obj.getContext('2d');
            var circularIndex = 0,
                loopIndex = 0;
            // 获取中心点的坐标和半径 x1 , y1 , r1;
            try{
                while (true) {
                    circularIndex++;
                    // 寻找0 - ?  之间的数值
                    var x = Math.floor(Math.random() * width),
                        y = Math.floor(Math.random() * height);
                    var cir = $.fn.draw.circular.effect(x , y , width , height);
                    if(!cir){
                        circularIndex --;
                        loopIndex++;
                        if(loopIndex > 500000){ // 若是循环4000+ 尚未找到合适的圆,中止,防止死循环
                            break;
                        }
                        continue;
                    }else{
                        var color = option.colors[circularIndex] ? option.colors[circularIndex] : 
                                option.colors[circularIndex % option.colors.length ];
                        var text = option.text[circularIndex] ? option.text[circularIndex] : 
                        option.text[circularIndex % option.text.length ];
                        $.fn.draw.circular.begin(cir.x , cir.y , cir.r , text , color ,ctx);
                    }
                    if (circularIndex >=option.number) { // 随机生成10个园
                        break;
                    }
                }
            }catch(e){
                console.log(e);
            }
        }
    });
})(jQuery);
(function ($) {
    var recordArr = [];
    $.fn.draw.defaultOption = {
        number:5, // 生成的个数
        colors: ['#FF8E56'], // 默认一个颜色,能够接受的参数是 Array
        text:['Chrome']
    }
    $.fn.draw.circular = {
        /**
          x1  x轴坐标
          y   y轴坐标
          r   半径
          text 文字
          color 填充颜色
        **/
        begin: function (x, y, r, text, color , ctx) {
            recordArr.push({
                x: x,
                y: y,
                r: r
            })
            ctx.beginPath();
            ctx.arc(x, y, r, 0, 2 * Math.PI, false);
            ctx.fillStyle = color;
            ctx.fill();
            ctx.font = "14px Microsoft YaHei";
            ctx.fillStyle = "#fffffe";
            ctx.textAlign = "center";
            ctx.fillText(text, x , y + 5);
            ctx.closePath();
        },
        /**
         * x 坐标
         * y 坐标
         * width 当前盒子宽度
         * height 盒子高度
         *  */
        effect:function (x , y , width , height) { 
            // 设置一个以盒子大小来计算的半径
            var boxR = Math.floor(width / 6);
            // 获取随机半径
            var randomR = Math.floor(Math.random() * boxR);
            if (randomR < 30) { // 设置半径不能低于30
               return false;
            } else {
                // 不能划到框外
                if (x + randomR > width || y + randomR > height) {
                    return false;
                } else if (y - 2 * randomR < 0 || x - 2 * randomR < 0) {
                    return false;
                }
                // 不能出现重叠圆
                for(var a = 0 ; a < recordArr.length ; a++){
                    var distant = Math.floor(Math.sqrt(
                        Math.pow(Math.abs(recordArr[a].x - x), 2) + Math.pow(Math.abs(recordArr[a].y - y), 2)
                    ));
                    if(distant < randomR + recordArr[a].r){
                        return false;
                    }
                }
                return {
                    x:x,
                    y:y,
                    r:randomR
                };
            }
        }
    }
})(jQuery)

欢迎你们吐槽,若是转载请标明出处。

相关文章
相关标签/搜索