Quantcast
Channel: Active questions tagged html - Stack Overflow
Viewing all articles
Browse latest Browse all 74074

reshape circle in canvas

$
0
0

Hi I'm facing a problem with canvas.

I try to make a circle that can be reshape like this. In the demo the circle can be reshape

the problem is to drag and drop the circle point to reshape it.

I know how to drag and drop point in the javascript canvas but how to reshape the cirle line to follow the point.

const DEBUG = true;

const WIDTH = window.innerWidth;
const HEIGHT = window.innerHeight;

const MIN_DIMENSION = WIDTH < HEIGHT ? WIDTH : HEIGHT;
const DEFAULT_RADIUS = MIN_DIMENSION * 0.45;
let canvas, ctx;

let cos = Math.cos;
let sin = Math.sin;
let pi = Math.PI;
let pi2 = pi * 2;

class Point {
  constructor(x,y) {
    this.x = x;
    this.y = y;
  }
}


function block(c, cb) {
  c.save();
  c.beginPath();
  cb(c);
  c.closePath();
  c.restore();
}

function circle(c,r) {
  c.arc(0, 0, r, 0, pi2);
}

function debugPoints(c, points) {
  points.forEach((p,i) => {
    if(i % 2 === 0) {
      c.fillStyle = 'red';
    } else {
      c.fillStyle = 'black';
    }
    c.beginPath();
    c.arc(p.x, p.y, 2, 0, pi2);
    c.fill();
    c.closePath();
  })
}

function bezierCirclePoints(r, n) {
  let a = pi2/(2*n);
  let R = r/cos(a);
  
  let points = new Array(2 * n);
  
  
  console.log('n:', n);
  console.log('a:', a);
  console.log('r:', r);
  console.log('R:', R);
  // calculate even bezier points
  for(let i = 0; i < n; i++) {
    let i2 = 2*i;
    let x = r * sin(i2 * a);
    let y = -r * cos(i2 * a);
    points[i2] =  new Point(x, y);
  }
  // calculate odd bezier points
  for(let i = 0; i < n; i++) {
    let i2 = 2*i + 1;
    let x = R * sin(i2 * a);
    let y = -R * cos(i2 * a);
    points[i2] =  new Point(x, y);
  }
  points.push(points[0]);
  return points;
}

function bezierCircle(c, r = DEFAULT_RADIUS, n = 7) {
  let points = bezierCirclePoints(r,n);
  
  c.translate(WIDTH * 0.5,HEIGHT * 0.5);
  
  if(DEBUG) {
    debugPoints(c, points);
  }
  
  c.fillStyle = 'red';
  c.strokeStyle = 'red';

  // draw circle
  c.beginPath();
  let p = points[0];
  c.moveTo(p.x, p.y);
  
  for(let i = 1; i < points.length; i+=2){
      let p1 = points[i];
      let i2 = i + 1;
      if(i2 >= points.length) {
        i2 = 0;
      }  
      let p2 = points[i2];
      c.quadraticCurveTo(p1.x, p1.y, p2.x, p2.y);
  } 
  c.stroke();
  c.closePath();
}

function redCircle(c) {
  c.fillStyle = 'red';
  c.translate(200,200);
  circle(c, 100);
  c.fill();
}


canvas = document.getElementById('circle');
canvas.width = WIDTH;
canvas.height = HEIGHT;
ctx = canvas.getContext('2d');

block(ctx, bezierCircle)
<canvas id="circle"></canvas>

Viewing all articles
Browse latest Browse all 74074

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>