Рисовать только внутри нарисованного многоугольника - PullRequest
0 голосов
/ 17 марта 2020

Я бы хотел свободен, но только внутри объекта, который я нарисовал раньше. Например. Мне нужно нарисовать треугольник, используя мой код ниже, а затем бесплатно нарисовать линии, но только внутри этого треугольника, как обрезать его, чтобы цвет не был за его пределами?

var min = 99;
var max = 999999;
var polygonMode = true;
var pointArray = new Array();
var lineArray = new Array();
var activeLine;
var activeShape = false;
var canvas;
$(window).load(function() {
  prototypefabric.initCanvas();
  $('#create-polygon').click(function() {
    prototypefabric.polygon.drawPolygon();
  });
});
var prototypefabric = new function() {
  this.initCanvas = function() {
    canvas = window._canvas = new fabric.Canvas('c');
    canvas.setWidth(800);
    canvas.setHeight(800);
    canvas.setBackgroundImage('https://i.imgur.com/tsnGll2.jpg', canvas.renderAll.bind(canvas));
    //canvas.selection = false;

    canvas.on('mouse:down', function(options) {
      if (options.target && options.target.id == pointArray[0].id) {
        prototypefabric.polygon.generatePolygon(pointArray);
      }
      if (polygonMode) {
        prototypefabric.polygon.addPoint(options);
      }
    });
    canvas.on('mouse:up', function(options) {

    });
    canvas.on('mouse:move', function(options) {
      if (activeLine && activeLine.class == "line") {
        var pointer = canvas.getPointer(options.e);
        activeLine.set({
          x2: pointer.x,
          y2: pointer.y
        });

        var points = activeShape.get("points");
        points[pointArray.length] = {
          x: pointer.x,
          y: pointer.y
        };
        activeShape.set({
          points: points
        });
        canvas.renderAll();
      }
      canvas.renderAll();
    });
  };
};

prototypefabric.polygon = {
  drawPolygon: function() {
    polygonMode = true;
    pointArray = new Array();
    lineArray = new Array();
    activeLine;
  },
  addPoint: function(options) {
    var random = Math.floor(Math.random() * (max - min + 1)) + min;
    var id = new Date().getTime() + random;
    var circle = new fabric.Circle({
      radius: 5,
      fill: '#ffffff',
      stroke: '#333333',
      strokeWidth: 0.5,
      left: (options.e.layerX / canvas.getZoom()),
      top: (options.e.layerY / canvas.getZoom()),
      selectable: false,
      hasBorders: false,
      hasControls: false,
      originX: 'center',
      originY: 'center',
      id: id
    });
    if (pointArray.length == 0) {
      circle.set({
        fill: 'red'
      })
    }
    var points = [(options.e.layerX / canvas.getZoom()), (options.e.layerY / canvas.getZoom()), (options.e.layerX / canvas.getZoom()), (options.e.layerY / canvas.getZoom())];
    line = new fabric.Line(points, {
      strokeWidth: 2,
      fill: '#999999',
      stroke: 'green',
      class: 'line',
      originX: 'center',
      originY: 'center',
      selectable: false,
      hasBorders: false,
      hasControls: false,
      evented: false
    });
    if (activeShape) {
      var pos = canvas.getPointer(options.e);
      var points = activeShape.get("points");
      points.push({
        x: pos.x,
        y: pos.y
      });
      var polygon = new fabric.Polygon(points, {
        stroke: '#333333',
        strokeWidth: 1,
        fill: '#cccccc',
        opacity: 0.3,
        selectable: false,
        hasBorders: false,
        hasControls: false,
        evented: false
      });
      canvas.remove(activeShape);
      canvas.add(polygon);
      activeShape = polygon;
      canvas.renderAll();
      console.log(points);
    } else {
      var polyPoint = [{
        x: (options.e.layerX / canvas.getZoom()),
        y: (options.e.layerY / canvas.getZoom())
      }];
      var polygon = new fabric.Polygon(polyPoint, {
        stroke: '#333333',
        strokeWidth: 1,
        fill: '#cccccc',
        opacity: 0.3,
        selectable: false,
        hasBorders: false,
        hasControls: false,
        evented: false
      });
      activeShape = polygon;
      canvas.add(polygon);
    }
    activeLine = line;

    pointArray.push(circle);
    lineArray.push(line);

    canvas.add(line);
    canvas.add(circle);
    canvas.selection = false;
  },
  generatePolygon: function(pointArray) {
    var points = new Array();
    $.each(pointArray, function(index, point) {
      points.push({
        x: point.left,
        y: point.top,
      });
      canvas.remove(point);
    });
    $.each(lineArray, function(index, line) {
      canvas.remove(line);
    });
    canvas.remove(activeShape).remove(activeLine);
    var polygon = new fabric.Polygon(points, {
      stroke: '#333333',
      strokeWidth: 0.5,
      fill: 'rgba(255, 255, 255, 0.5)',
      opacity: 1,
      hasBorders: false,
      hasControls: false
    });
    canvas.add(polygon);

    activeLine = null;
    activeShape = null;
    polygonMode = false;
    canvas.selection = true;
  }
};

// Removing active object on backspace

$(document).keydown(function(event) {
  if (event.which == 8) {
    if (canvas.getActiveObject()) {
      canvas.getActiveObject().remove();
    }
  }
});

// end of Removing active object on backspace

// Freedrawing

function enableFreeDrawing() {
  removeEvents();
  canvas.isDrawingMode = true;
  canvas.freeDrawingBrush.color = e.target.value;
}

document.getElementById('colorpicker').addEventListener('click', function(e) {
  canvas.freeDrawingBrush.color = e.target.value;
  canvas.freeDrawingBrush.width = 2;
});

function removeEvents() {
  canvas.isDrawingMode = false;
  canvas.selection = false;
  canvas.off('mouse:down');
  canvas.off('mouse:up');
  canvas.off('mouse:move');
}

// Manipulate canvas

$(function() {

  $('#zoomIn').click(function() {
    canvas.setZoom(canvas.getZoom() * 1.1);
  });

  $('#zoomOut').click(function() {
    canvas.setZoom(canvas.getZoom() / 1.1);
  });

  $('#goRight').click(function() {
    var units = 10;
    var delta = new fabric.Point(units, 0);
    canvas.relativePan(delta);
  });

  $('#goLeft').click(function() {
    var units = 10;
    var delta = new fabric.Point(-units, 0);
    canvas.relativePan(delta);
  });
  $('#goUp').click(function() {
    var units = 10;
    var delta = new fabric.Point(0, -units);
    canvas.relativePan(delta);
  });

  $('#goDown').click(function() {
    var units = 10;
    var delta = new fabric.Point(0, units);
    canvas.relativePan(delta);
  });

  $('#zoomIn').click(function() {
    canvas.setZoom(canvas.getZoom() * 1.1);
  });

  $('#zoomOut').click(function() {
    canvas.setZoom(canvas.getZoom() / 1.1);
  });

});

// End of manipulate canvas
canvas {
  border: 1px solid black;
  border-radius: 27px;
}

* {
  font-family: "Roboto", sans-serif;
  font-weight: 100;
}

body {
  overflow: hidden;
}

/*#c {*/
/*  border: 1px solid black;*/
/*  background: url(assets/geoportal.JPG);*/
/*  background-size: cover;*/
/*  border-radius: 27px;*/
/*}*/

.canvas-container {
  margin: 0 auto;
  margin-top: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
  <canvas id="c" width="800" height="800"></canvas>
  <ul class="action-list">
    <li>
      <button class="thmb" href="#" id="create-polygon">Narysuj polygon</button>
    </li>
    <li>
      <div id="colorpicker">
        <button class="thmb" href="#" onclick="enableFreeDrawing()" value="#FFFF00">Yellow</button>
        <button class="thmb" href="#" onclick="enableFreeDrawing()" value="#00FF00">Green</button>
        <button class="thmb" href="#" onclick="enableFreeDrawing()" value="#F00000">Red</button>
        <button class="thmb" href="#" onclick="removeEvents()">Stop Drawing</button>
      </div>
    </li>
    <li>
      <button id="goLeft" class="thmb">&lt;</button>
      <button id="goRight" class="thmb">&gt;</button>
      <button id="goUp" class="thmb">Up</button>
      <button id="goDown" class="thmb">Down</button>
      <button id="zoomIn" class="thmb">+</button>
      <button id="zoomOut" class="thmb">-</button>
    </li>
  </ul>
</div>

Ссылка: https://codepen.io/Basstalion/pen/gOpKOjP

...