'FabricJS - Skewing an image using corners

I'm trying to create an app where a user can "skew" an image using the four corner grab handles. I have this working with a standard polygon, but cannot get it to work using an image. I'm a complete Canvas/Fabric noob, so no idea where to start.

https://jsfiddle.net/09qtbs85/

HTML:

<body onload="Edit();">
<canvas id="c" width="500" height="500"></canvas>

JS:

var canvas = this.__canvas = new fabric.Canvas('c');
var points = [{"x":10,"y":10},{"x":10,"y":60},{"x":100,"y":60},{"x":100,"y":10}]
var img = fabric.Image.fromURL('https://i.imgur.com/XMVWqfo.jpeg', function(myImg)
{
 canvas.add(myImg);
});
var polygon = new fabric.Polygon(points,
{
 left: 100,
 top: 50,
 fill: '#FEE04E',
 scaleX: 4,
 scaleY: 4,
 objectCaching: false,
 transparentCorners: true,
 cornerColor: '#000000',
});
canvas.viewportTransform = [0.7, 0, 0, 0.7, -50, 50];
canvas.add(polygon);
function polygonPositionHandler(dim, finalMatrix, fabricObject)
{
 var x = (fabricObject.points[this.pointIndex].x - fabricObject.pathOffset.x),
     y = (fabricObject.points[this.pointIndex].y - fabricObject.pathOffset.y);
 return fabric.util.transformPoint({ x: x, y: y },fabric.util.multiplyTransformMatrices(fabricObject.canvas.viewportTransform,fabricObject.calcTransformMatrix()));
}
function actionHandler(eventData, transform, x, y)
{
 var polygon = transform.target,
     currentControl = polygon.controls[polygon.__corner],
     mouseLocalPosition = polygon.toLocalPoint(new fabric.Point(x, y), 'center', 'center'),
     polygonBaseSize = polygon._getNonTransformedDimensions(),
     size = polygon._getTransformedDimensions(0, 0),
     finalPointPosition = {x: mouseLocalPosition.x * polygonBaseSize.x / size.x + polygon.pathOffset.x, y: mouseLocalPosition.y * polygonBaseSize.y / size.y + polygon.pathOffset.y};
 polygon.points[currentControl.pointIndex] = finalPointPosition;
 return true;
}
function anchorWrapper(anchorIndex, fn)
{
 return function(eventData, transform, x, y)
 {
  var fabricObject = transform.target,
      absolutePoint = fabric.util.transformPoint({x: (fabricObject.points[anchorIndex].x - fabricObject.pathOffset.x), y: (fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y)}, fabricObject.calcTransformMatrix()),
      actionPerformed = fn(eventData, transform, x, y),
      newDim = fabricObject._setPositionDimensions({}),
      polygonBaseSize = fabricObject._getNonTransformedDimensions(),
      newX = (fabricObject.points[anchorIndex].x - fabricObject.pathOffset.x) / polygonBaseSize.x,
      newY = (fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y) / polygonBaseSize.y;
  fabricObject.setPositionByOrigin(absolutePoint, newX + 0.5, newY + 0.5);
  return actionPerformed;
 }
}
function Edit()
{
 var poly = canvas.getObjects()[0];
 canvas.setActiveObject(poly);
 poly.edit = !poly.edit;
 if(poly.edit)
 {
  var lastControl = poly.points.length - 1;
  poly.cornerStyle = 'circle';
  poly.cornerColor = 'rgba(0,0,255,0.5)';
  poly.controls = poly.points.reduce(function(acc, point, index)
  {
   acc['p' + index] = new fabric.Control(
   {
    positionHandler: polygonPositionHandler,
    actionHandler: anchorWrapper(index > 0 ? index - 1 : lastControl, actionHandler),
    actionName: 'modifyPolygon',
    pointIndex: index
   });
   return acc;
  }, { });
 }
 else
 {
  poly.cornerColor = 'blue';
  poly.cornerStyle = 'rect';
  poly.controls = fabric.Object.prototype.controls;
 }
 poly.hasBorders = !poly.edit;
 canvas.requestRenderAll();
}

I need the image to be able to be resized just like the yellow rectangle can be (then the rectangle will be removed)



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source