Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I resize an image pattern when the pattern is draggable?

I used this Resize an image with javascript for use inside a canvas createPattern to resize the initial image, but when I try to put the same code in my drag/drop functionality, it does not work correctly (it creates a new image and when I try to drag it, it gets strange - see image below. the "O" has the image before dragging/dropping, the "P" has the image after dragging/dropping).

enter image description here

Here is the code I am using:

function photos_create_preview_image(element)
{
  console.log(element.id);
  if(element.id.indexOf("canvas") != -1)
  {
    var canvas = document.getElementById(element.id); 
    var ctx = canvas.getContext("2d");

    var canvasOffset = $("#" + element.id).offset();
    var offsetX = canvasOffset.left;
    var offsetY = canvasOffset.top;
    var isDown = false;
    var startX;
    var startY;
    var imgX = 0;
    var imgY = 0;
    var imgWidth, imgHeight;
    var mouseX, mouseY;


    var new_img = new Image();
    new_img.onload = function() 
    {
      var tempCanvas = photos_create_temp_canvas(new_img);

      imgWidth = new_img.width;
      imgHeight = new_img.height;
      //var pattern = ctx.createPattern(new_img, "no-repeat");
      var pattern = ctx.createPattern(tempCanvas, "no-repeat");
      ctx.fillStyle = pattern;
      ctx.fill();

    };

    new_img.src = SITE_URL + "/system/photo/cf_preview/" + selected_fid;

    function photos_create_temp_canvas(new_img)
    {
      var tempCanvas = document.createElement("canvas"),
      tCtx = tempCanvas.getContext("2d");

      tempCanvas.width = new_img.width / 3; //TODO: Figure out what this should be, right now it is just a "magic number"
      tempCanvas.height = new_img.height / 3 ;
      tCtx.drawImage(new_img,0,0,new_img.width,new_img.height,0,0,new_img.width / 3,new_img.height / 3);
      return tempCanvas;
    }

    function handleMouseDown(e) 
    {
        e.preventDefault();
        startX = parseInt(e.pageX - window.scrollX);
        startY = parseInt(e.pageY - window.scrollY);
        if (startX >= imgX && startX <= imgX + imgWidth && startY >= imgY && startY <= imgY + imgHeight) {
          isDown = true;
        }
    }

    function handleMouseUp(e) 
    {
        e.preventDefault();
        isDown = false;
    }

    function handleMouseOut(e) 
    {
        e.preventDefault();
        isDown = false;
    }

    function handleMouseMove(e) 
    {
        if (!isDown) {
            return;
        }
        e.preventDefault();
        mouseX = parseInt(e.clientX - offsetX);
        mouseY = parseInt(e.clientY - offsetY);

        if (!isDown) {
            return;
        }
        imgX += mouseX - startX;
        imgY += mouseY - startY;
        startX = mouseX;
        startY = mouseY;

        var tempCanvas = photos_create_temp_canvas(new_img);
        var pattern = ctx.createPattern(tempCanvas, "no-repeat");
        //var pattern = ctx.createPattern(new_img, "no-repeat");
        ctx.save();
        ctx.translate(imgX, imgY);
        ctx.fillStyle = pattern;
        ctx.fill();
        ctx.restore();
    }

    $("#" + element.id).mousedown(function (e) {
        handleMouseDown(e);
    });
    $("#" + element.id).mousemove(function (e) {
        handleMouseMove(e);
    });
    $("#" + element.id).mouseup(function (e) {
        handleMouseUp(e);
    });
    $("#" + element.id).mouseout(function (e) {
        handleMouseOut(e);
    });
  }
  else //You can ignore this - not relevant to the question
  {

    new_img = new Image();
    new_img.onload = function() {
      this.width /= 3; //TODO: Figure out what this should be, right now it is just a "magic number"
      this.height /= 3;

      element.appendChild(new_img);
      $(new_img).draggable({ containment: "parent" });
    };

    new_img.src = SITE_URL + "/system/photo/cf_preview/" + selected_fid;
  }
  console.log("new image: " + new_img.src);
}

I changed the code to:

...
ctx.fillStyle = "#BFBFBF";
ctx.fill();

var tempCanvas = photos_create_temp_canvas(new_img);
var pattern = ctx.createPattern(tempCanvas, "no-repeat");
ctx.save();
ctx.translate(imgX, imgY);
ctx.fillStyle = pattern;

ctx.fill();
ctx.restore();
...

And that part works but, now it is only letting me move the image from the bottom. (See image below)

enter image description here

like image 712
AllisonC Avatar asked Jan 03 '14 16:01

AllisonC


1 Answers

You need to clear the canvas before redrawing:

function handleMouseMove(e) 
    {

      ...

        var tempCanvas = photos_create_temp_canvas(new_img);
        var pattern = ctx.createPattern(tempCanvas, "no-repeat");
        //var pattern = ctx.createPattern(new_img, "no-repeat");
        ctx.save();
        ctx.translate(imgX, imgY);
        ctx.fillStyle = pattern;
        ctx.clearRect(0, 0, tempCanvas.width, tempCanvas.height);
        ctx.fill();
        ctx.restore();
    }
like image 54
tnt-rox Avatar answered Nov 14 '22 12:11

tnt-rox