使用canvas在一个矩形内画不重复的圆,须要注意两点javascript
<!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>
(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)