使用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)