Note that there are some explanatory texts on larger screens.

plurals
  1. POSkew image using draggable handles as in photoshop
    text
    copied!<p>I am trying to skew image just like we do in photoshop using html5 canvas. I am able to use skew for top-right handle and the left bottom handle but unfortunately not able to apply skew on the other two handles as in code below: The HTML:</p> <pre><code>&lt;div class="scalableParent"&gt; &lt;img src="img/Chrysanthemum.jpg" class="scalable"/&gt; &lt;/div&gt; </code></pre> <p>The Javascript (JQuery):</p> <pre><code>$(document).ready(function(){ var uid = 0; jQuery.fn.extend({ skew: function() { uid++; this.attr("style","position:relative"); var parent = this; var image = this.find("img"); var canvas = createCorrespondingCanvas(image); var img = new Image(); $(img).on("load", function(){ canvas.width = this.width canvas.height = this.height var ctx=canvas.getContext("2d"); ctx.clearRect(0,0,0,0) ctx.drawImage(this,0,0, this.width, this.height); $(this).hide(); //$(img).off("load"); }); img.src= image.attr("src") this.find("img").attr("style", "position:absolute; z-index: -1"); var handles = createHandles(this, image); makeHandlesDraggable(handles); createOutputImage(); var output; function createOutputImage(){ output = new Image(); output.id="outputImage"; $(parent).append(output); } function createHandles(el, image){ var handleLeftTop = document.createElement("div"); handleLeftTop.className = "handle left-top"; $(handleLeftTop).css({position:"absolute", width: 40, height: 40, border: "1px solid black"}); var handleLeftBottom = document.createElement("div"); handleLeftBottom.className = "handle left-bottom"; $(handleLeftBottom).css({position:"absolute", width: 40, height: 40, border: "1px solid black"}); var handleRightTop = document.createElement("div"); handleRightTop.className = "handle right-top"; $(handleRightTop).css({position:"absolute", width: 40, height: 40, border: "1px solid black"}); var handleRightBottom = document.createElement("div"); handleRightBottom.className = "handle right-bottom"; $(handleRightBottom).css({position:"absolute", width: 40, height: 40, border: "1px solid black"}); el.append(handleLeftTop,handleLeftBottom,handleRightTop,handleRightBottom); $(handleLeftTop).css({ left: $(image).position().left, top: $(image).position().top }); $(handleLeftBottom).css({ left: $(image).position().left, top: $(image).position().top + $(image).height() - 40 }); $(handleRightTop).css({ left: $(image).position().left + $(image).width() - 40, top: $(image).position().top }); $(handleRightBottom).css({ left: $(image).position().left + $(image).width() - 40, top: $(image).position().top + $(image).height() - 40 }); return { leftTop: handleLeftTop, leftBottom: handleLeftBottom, rightTop: handleRightTop, rightBottom: handleRightBottom }; } function createCorrespondingCanvas(img){ var can = document.createElement("canvas"); can.id = "can"+uid; $(can).css({zIndex: 1}); $(img).attr("data-canvasid", can.id) parent.append(can) uid++; return can; } function makeHandlesDraggable(handles){ for( var handle in handles){ if($(handles[handle]).hasClass("right-top")){ $(handles[handle]).draggable({ containment: parent, start: function(a,b,c){ }, /*axis: "x", */ drag: function(a,b,c){ var cntxt = canvas.getContext("2d"); cntxt.clearRect(0, 0, img.width, img.height); var dragPosition = b.helper.position(); cntxt.setTransform(1, Math.tan(dragPosition.top/dragPosition.left), 0, 1, 0, 0); // for right top cntxt.drawImage(img, 0, 0, img.width, img.height); }, stop: function(){ console.log("data") destroyAndRecreate() } }); } else if($(handles[handle]).hasClass("left-bottom")){ $(handles[handle]).draggable({ containment: parent, start: function(a,b,c){ }, /*axis: "x", */ drag: function(a,b,c){ var cntxt = canvas.getContext("2d"); cntxt.clearRect(0, 0, img.width, img.height); var dragPosition = b.helper.position(); cntxt.setTransform(1, 0, Math.tan(dragPosition.left/dragPosition.top), 1, 0, 0); // for left bottom cntxt.drawImage(img, 0, 0, img.width, img.height); }, stop: function(){ console.log("data") //$(image).attr("src",canvas.toDataURL()); destroyAndRecreate() } }); }else if($(handles[handle]).hasClass("right-bottom")){ $(handles[handle]).draggable({ containment: parent, start: function(a,b,c){ }, /*axis: "x", */ drag: function(a,b,c){ var cntxt = canvas.getContext("2d"); cntxt.clearRect(0, 0, img.width, img.height); var dragPosition = b.helper.position(); // Dont know the formula to be applied here }, stop: function(){ console.log("data") destroyAndRecreate() } }); } else if($(handles[handle]).hasClass("left-top")){ $(handles[handle]).draggable({ containment: parent, start: function(a,b,c){ }, /*axis: "x", */ drag: function(a,b,c){ var cntxt = canvas.getContext("2d"); cntxt.clearRect(0, 0, img.width, img.height); var dragPosition = b.helper.position(); // Dont know the formula to be applied here }, stop: function(){ console.log("data") destroyAndRecreate() } }); } } } function destroyAndRecreate(){ var data = canvas.toDataURL(); $(output).attr("src", data); var ref = $(output).clone(); $parent = $(output).parent(); $parent.empty(); $parent.append(ref); $(ref).on("load", function(){ $parent.skew(); }); } $("#btnSave").on("click", function(){ //$(output).attr("src", $(image).attr("src")).hide(); window.open($(output).attr("src")) }); } }); $( ".scalableParent img" ).on("load", function(){ $( ".scalableParent" ).skew(); }); }); </code></pre> <p>Any help is appreciated as long as I can understand the formula to achieve the effect required.</p> <p>I've Edited the question to accomodate the conditions where I need to apply the formula for transforming the images</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload