使用Photoshop中的可拖动手柄歪斜图像

时间:2013-11-07 20:59:30

标签: javascript jquery html html5 canvas

我试图像使用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();
            });

        });

只要我能理解达到所需效果的公式,任何帮助都会受到赞赏。

我编辑了这个问题,以适应我需要应用转换图像的公式的条件

3 个答案:

答案 0 :(得分:2)

您忘记在makeHandlesDraggable()功能中为“左上角”和“右下角”手柄实施案例。您目前只有if条件为“右上角”和“左下角”。

答案 1 :(得分:2)

查看WebGL库glfx.js.过滤:透视。将有4个可拖动点。手动执行此操作需要大量计算。

http://evanw.github.io/glfx.js/demo/

答案 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