view source

JavaScript

document.title = 'Canvasで正多角形を描画 重複を避けて配置描画';

$(function(){
  var w = document.body.clientWidth;
  var h = window.innerHeight;
  var wh = Math.min(w,h);
  var padding = 10;
  var r = 80;
  var cx = r+padding;
  var cy = r+padding;

  var canvas = $('<canvas>',{width:w, height:h});
  canvas[0].width = w;
  canvas[0].height = h;
  $('#demo').append(canvas);
  var ctx = canvas[0].getContext('2d');
  var polygons = [];

  //接触判定//雑に円
  function checkColl(n, m){
    var a = Math.abs(n.x - m.x);
    var b = Math.abs(n.y - m.y);
    var cc = Math.pow(a,2)+Math.pow(b,2);
    var c = Math.pow(cc, 1/2);
    console.log({
      rr:rr,
      c:c,
    })
    var rr = n.r+m.r;
    if(rr > c){return true;}
  }

  //重複を避けて配置
  //複数の円を重ならずに描画
  function checkAvoifPolygonPos(){
    var isColl = true;
    console.log('checkAvoifPolygon');
    var n = {};
    while (isColl){
      var x = Math.random()*w*14/16 + w/16;
      var y = Math.random()*h*14/16 + h/16;
      var r = Math.random()*wh/4 + wh/32;
      n = {
        x:x,
        y:y,
        r:r,
      }
      isColl = false;
      polygons.some(function(m){
        if(checkColl(n, m)){
          isColl = true;
          return true;
        } else {
          isColl = false;
        }
      });
    }
    
    console.log(n);
    return n;
  }


  function drawPolygon(cx,cy,r,vertex,color,rnd){
    ctx.beginPath();
    ctx.fillStyle = color || '#000';
    var rnd = rnd || Math.random();
    var addDegree = Math.floor(rnd*360);
    var addRadian = addDegree * ( Math.PI / 180 ) ;
    for(var i=0;i<vertex;i++){
      var rad = Math.PI*2/vertex*i + addRadian;
      var x = cx + Math.cos(rad)*r;
      var y = cy + Math.sin(rad)*r;
      if(i===0){
        ctx.moveTo(x,y);
      } else {
        ctx.lineTo(x,y);
      }
    }
    //ctx.stroke();
    ctx.fill();
  }
  function drawStar(cx,cy,r,vertex,color,rnd){
    ctx.beginPath();
    ctx.fillStyle = color || '#000';
    var rnd = rnd || Math.random();
    var addDegree = Math.floor(rnd*360);
    var addRadian = addDegree * ( Math.PI / 180 ) ;
    for(var i=0;i<vertex;i++){
      var rad = Math.PI*2/vertex*i + addRadian;
      var rr = r;
      if(i%2===0){rr=r/2}
      var x = cx + Math.cos(rad)*rr;
      var y = cy + Math.sin(rad)*rr;
      if(i===0){
        ctx.moveTo(x,y);
      } else {
        ctx.lineTo(x,y);
      }
    }
    //ctx.stroke();
    ctx.fill();
  }

  function setPolygon(x,y,r,vertex,color){
    var r = Math.floor(Math.random()*18)+5;
    var vertex = Math.floor(Math.random()*4)+3;
    var n = {
      x:x,
      y:y,
      r:r,
    }
    drawPolygon(x,y,r,vertex, '#f00');
  }

/*
  for(i=0;i<8;i++){
    var vertex = i+3
    cx += r*2.5;
    if(i%4===0){cy+=r*2.5;cx=r+padding;}
    var rnd = Math.random();
    drawPolygon(cx,cy,r,vertex,'#000',rnd);
    polygons.push({
      x:cx,
      y:cy,
      r:r,
      rnd:rnd,
      vertex:vertex
    });
  }
  for(i=3;i<16;i+=2){
    var vertex = i+3
    cx += r*2.5;
    if(i%5===0){cy+=r*2.5;cx=r+padding;}
    var rnd = Math.random();
    drawStar(cx,cy,r,vertex,'#000',rnd);
    polygons.push({
      x:cx,
      y:cy,
      r:r,
      rnd:rnd,
      vertex:vertex
    });
  }
  console.log(polygons);
*/
  for(i=0;i<8;i++){
    var vertex = i+3
    var n = checkAvoifPolygonPos();
    var rnd = Math.random();
    drawPolygon(n.x ,n.y, n.r, vertex,'#00f',rnd);
    polygons.push({
      x:n.x,
      y:n.y,
      r:n.r,
      rnd:rnd,
      vertex:vertex,
      type:'Polygon',
    });
  }

  for(i=3;i<16;i+=2){
    var vertex = i+3
    var n = checkAvoifPolygonPos();
    var rnd = Math.random();
    drawStar(n.x ,n.y, n.r, vertex,'#0f0',rnd);
    polygons.push({
      x:n.x,
      y:n.y,
      r:n.r,
      rnd:rnd,
      vertex:vertex,
      type:'Star',
    });
  }

  canvas.on('click', function(e){
    var x = e.offsetX;
    var y = e.offsetY;
    var n = {
      x:x,
      y:y,
      r:1,
    }
    setPolygon(x,y);
    polygons.forEach(function(m){
      if(checkColl(n, m)){
        if(m.type === 'Polygon'){
          drawPolygon(m.x, m.y, m.r+1, m.vertex,'#ff0',m.rnd);
        }
        if(m.type === 'Star'){
          drawStar(m.x, m.y, m.r+1, m.vertex,'#ff0',m.rnd);
        }
      }
    });
  });
  canvas.on('dblclick', function(e){
    for(i=0;i<90;i++){
      var x = Math.floor(Math.random()*w * 39/40)+5;
      var y = Math.floor(Math.random()*h * 39/40)+5;
      setPolygon(x,y);
    }
  });

  $(document).on('keydown', function(e){
    ctx.clearRect(0, 0, w, h);
    polygons = [];
  });

  for(i=0;i<90;i++){
      var x = Math.floor(Math.random()* (w - padding*2))+padding;
      var y = Math.floor(Math.random()* (h - padding*2))+padding;
    setPolygon(x,y);
  }


})

CSS

HTML

ページのソースを表示 : Ctrl+U , DevTools : F12

view-source:https://hi0a.com/demo/-js/js-canvas-polygon/

ABOUT

hi0a.com 「ひまアプリ」は無料で遊べるミニゲームや便利ツールを公開しています。

プログラミング言語の動作デモやWEBデザイン、ソースコード、フロントエンド等の開発者のための技術を公開しています。

必要な機能の関数をコピペ利用したり勉強に活用できます。

プログラムの動作サンプル結果は画面上部に出力表示されています。

環境:最新のブラウザ GoogleChrome / Windows / Android / iPhone 等の端末で動作確認しています。

画像素材や音素材は半分自作でフリー素材配布サイトも利用しています。LINK参照。

動く便利なものが好きなだけで技術自体に興味はないのでコードは汚いです。

途中放置や実験状態、仕様変更、API廃止等で動かないページもあります。