When an image is dragged on to a canvas element (or another div), this function is called. If the element was a canvas element it uses pattern to create the fill, otherwise it appends the image. When it appends the image, I can call jquery's draggable function. I would like to achieve the same functionality with the canvas element. How would I go about doing that?
Here is the relevant code:
function photos_create_preview_image(element)
{
console.log(element.id);
if(element.id.indexOf("canvas") != -1)
{
console.log("canvas element");
var canvas = document.getElementById(element.id);
ctx = canvas.getContext("2d");
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;
var pattern = ctx.createPattern(new_img, "no-repeat");
ctx.fillStyle = pattern;
ctx.fill();
//TODO: Make image draggable
};
new_img.src = SITE_URL + "/system/photo/cf_preview/" + selected_fid;
}
else
{
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);
}
Here's the new code with MarkE's solution:
function photos_create_preview_image(element)
{
console.log(element.id);
if(element.id.indexOf("canvas") != -1)
{
console.log("canvas element");
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() {
//this.width /= 3; //TODO: Figure out what this should be, right now it is just a "magic number"
// this.height /= 3;
/*var pattern = ctx.createPattern(new_img, "no-repeat");
ctx.fillStyle = pattern;
ctx.fill();*/
imgWidth = new_img.width;
imgHeight = new_img.height;
ctx.drawImage(new_img, imgX, imgY);
//TODO: Make image draggable
};
new_img.src = SITE_URL + "/system/photo/cf_preview/" + selected_fid;
function handleMouseDown(e) {
e.preventDefault();
//startX = parseInt(e.clientX - offsetX);
//startY = parseInt(e.clientY - offsetY);
startX = parseInt(e.pageX - window.scrollX);
startY = parseInt(e.pageY - window.scrollY);
// Put your mousedown stuff here
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);
// Put your mousemove stuff here
if (!isDown) {
return;
}
imgX += mouseX - startX;
imgY += mouseY - startY;
startX = mouseX;
startY = mouseY;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(new_img, imgX, imgY);
}
$("#" + 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
{
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 need the image to be a pattern because it is contained within a path. Right now the code works when called with drawImage.
Basically I need it to look like this (which it does when I use the pattern code):