我试图像使用html5画布在photoshop中那样扭曲图像。我可以使用右上角手柄和左下手柄的偏斜,但遗憾的是无法在其他两个手柄上应用偏斜,如下面的代码所示: HTML:
<div class="scalableParent">
<img src="img/Chrysanthemum.jpg" class="scalable"/>
</div>
Javascript(JQuery):
$(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();
});
});
只要我能理解达到所需效果的公式,任何帮助都会受到赞赏。
我编辑了这个问题,以适应我需要应用转换图像的公式的条件
答案 0 :(得分:2)
您忘记在makeHandlesDraggable()
功能中为“左上角”和“右下角”手柄实施案例。您目前只有if
条件为“右上角”和“左下角”。
答案 1 :(得分:2)
查看WebGL库glfx.js.过滤:透视。将有4个可拖动点。手动执行此操作需要大量计算。
答案 2 :(得分:1)
这可能对您有所帮助
cntxt.setTransform(1,(dragPosition.left*10)/canvas.width ,0,1, 0, (dragPosition.top*canvas.height)/100); // for left top
cntxt.setTransform(1, 0, Math.tan((dragPosition.left-canvas.width)/dragPosition.top), 1, 0, 0); // for right bottom
选中此fiddle
这个链接非常有用,试图找到解决方案 http://www.rgraph.net/blog/2013/february/an-example-of-the-html5-canvas-transform-function.html