文档章节

canvas 画不重叠的圆,

彝陵之战
 彝陵之战
发布于 08/10 22:29
字数 677
阅读 4
收藏 0

1. 前言

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

  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)

欢迎大家吐槽,如果转载请标明出处。

© 著作权归作者所有

彝陵之战
粉丝 2
博文 1
码字总数 677
作品 0
东城
私信 提问
Html5 Canvas动画基础(碰撞检测)

在Canvas中进行碰撞检测,大家往往直接采用游戏引擎(Cocos2d-JS、Egret)或物理引擎(Box2D)内置的碰撞检测功能,好奇的你有思考过它们的内部运行机制吗?下面将针对基本的碰撞检测技术进行讲解...

2018/12/05
0
0
Html5 Canvas动画基础碰撞检测的实现

在Canvas中进行碰撞检测,大家往往直接采用游戏引擎(Cocos2d-JS、Egret)或物理引擎(Box2D)内置的碰撞检测功能,好奇的你有思考过它们的内部运行机制吗?下面将针对基本的碰撞检测技术进行讲解...

嫣然丫丫丫
2018/12/11
0
0
Android 的Paint(画笔)及Canvas(画布)

要绘图,首先得调整画笔,待画笔调整好之后,再将图像绘制到画布上,这样才可以显示在手机屏幕上。Android 中的画笔是 Paint类,Paint 中包含了很多方法对其属性进行设置,主要方法如下: se...

双鱼座1990
2015/12/04
8K
1
Canvas globalCompositeOperation

在默认情况之下,如果在Canvas之中将某个物体(源)绘制在另一个物体(目标)之上,那么浏览器就会简单地把源特体的图像叠放在目标物体图像上面。 简单点讲,在Canvas中,把图像源和目标图像...

前端小攻略
2018/12/21
0
0
使用canvas寻路最小生成树

online source 问题引入 在学习了加权无向图寻找最小生成树的算法之后,想通过可视化的方式来表示一个图的构造和最小生成树的寻路过程,就使用canvas来模拟了图的构造,连接边和加重显示最小...

带带带带土
2017/11/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Android Binder机制 - interface_cast和asBinder讲解

研究Android底层代码时,尤其是Binder跨进程通信时,经常会发现interface_cast和asBinder,很容易被这两个函数绕晕,下面来讲解一下: interface_cast 下面根据下述ICameraClient例子进行分析...

天王盖地虎626
昨天
7
0
计算机实现原理专题--存储器的实现(二)

计算机实现原理专题--存储器的实现(一)中描述了一种可以记住输入端变化的装置。现需要对其功能进行扩充,我们将上面的开关定义为置位,下面的开关定义为复位,然后需要增加一个保持位,当保...

FAT_mt
昨天
5
0
集合--Collection与迭代

1.1Collection 集合 集合:集合是Java提供的一种容器技术,可以用来存储多个数据 集合与数组的区别: 数组的长度是固定的,集合的长度是可变的 数组中存储的是同类型的元素,存储基本数据类型...

Firefly-
昨天
11
0
聊聊rocketmq的consumeTimeout

序 本文主要研究一下rocketmq的consumeTimeout consumeTimeout rocketmq-client-4.5.2-sources.jar!/org/apache/rocketmq/client/consumer/DefaultMQPushConsumer.java public class Defaul......

go4it
昨天
5
0
JAVA--高级基础开发

Day13[Map集合练习题] 练习一:Map接口的特点 请简述Map 的特点: Map集合中存放的数据都是键值对,并且键不能相同,值可以相同。 Map集合中的Key是根据Set集合来存放的。 Map集合可以使用n...

李文杰-yaya
昨天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部