0

I'm trying to use 2 canvases, I want them both to accept an image dropped into them and use mouseclicks to manipulate the images. Here is the code I'm working on.

I have it where if I only have the eventlisteners for the 'droppedImage' canvas it works ok, as soon as I put in handlers for the 'changeImage' canvas it sees the 2nd canvas and reports the coordinates as an extension of the 1st canvas and it no longer displays the the RGB values or change the background of the 3rd canvas 'selectedColour'

Posting this as I head to bed, if anyone gives answers or requires further info I will pop on tomorrow before work to update.

window.onload = function() {
    var droppedImage = document.getElementById("droppedImage"),
        ctx = droppedImage.getContext("2d");
    droppedImage.addEventListener("mouseup", mpos);
        // init event handlers
    droppedImage.addEventListener("dragenter", dragEnter, false);
    droppedImage.addEventListener("dragexit", dragExit, false);
    droppedImage.addEventListener("dragover", dragOver, false);
    droppedImage.addEventListener("drop", drop, false);

        var changeImage = document.getElementById("changeImage"),
        ctx = changeImage.getContext("2d");
    changeImage.addEventListener("mouseup", mpos);
    // init event handlers
    changeImage.addEventListener("dragenter", dragEnter, false);
    changeImage.addEventListener("dragexit", dragExit, false);
    changeImage.addEventListener("dragover", dragOver, false);
    changeImage.addEventListener("drop", drop, false);

    var selectedColour = document.getElementById("selectedColour");

function dragEnter(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}

function dragExit(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}

function dragOver(evt) {
    evt.stopPropagation();
    evt.preventDefault();
}

function drop(evt) {
    evt.stopPropagation();
    evt.preventDefault();

    var files = evt.dataTransfer.files;
    var count = files.length;

    // Only call the handler if 1 or more files was dropped.
    if (count >0)   
        importImage(files);
}




function mpos(e) {
    var cX = 0,
        cY = 0;

    if (event.pageX || event.pageY) {
        cX = event.pageX;
        cY = event.pageY;
    }
    else {
        cX = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
        cY = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }

    cX -= droppedImage.offsetLeft;
    cY -= droppedImage.offsetTop;

   // ctx.fillRect(cX, cY, 2, 2);

   alert("X co-ord : "+ cX +", Y co-ord : "+ cY);
   var imageData = ctx.getImageData(cX, cY, 1, 1);
   alert("Pixel 1: "+ imageData.data[0]+", "+imageData.data[1]+", "+ imageData.data[2]+", "+ imageData.data[3]);
   selectedColour.style.backgroundColor = "rgb("+imageData.data[0]+","+imageData.data[1]+","+imageData.data[2]+")";

}
}


function importImage(files) {

    var file = files[0];
    var reader = new FileReader;
    reader.onloadend = handleReaderLoadEnd; 
    reader.readAsDataURL(file);



function handleReaderLoadEnd(evt){     


    var canvas = document.getElementsByTagName('canvas')[0];
    var ctx = canvas.getContext('2d');
    var img = new Image;
        img.src = event.target.result;          
        img.onload = function() {       
        width = img.width;
        height = img.height;        
        var scaleX, scaleY, scale;
        var scaledWidth, scaledHeight;
        scaleX = width / canvas.width;
        scaleY = height / canvas.height;
        scale = scaleX > scaleY ? scaleX : scaleY;
        scaledWidth = width / scale;
        scaledHeight = height / scale;
        ctx.clearRect(0,0, canvas.width, canvas.height);
        ctx.drawImage(img, (canvas.width - scaledWidth) / 2, (canvas.height - scaledHeight) / 2, scaledWidth, scaledHeight);

        }
    }


}

1 Answer 1

1

Theoretically, if you have two sets of canvases and add event listeners to both of them then both sets of event listeners will fire at the same time, by design. Better to have one canvas that has event listeners attached, then detect the mouse co-ordinates and manipulate the image that is being clicked. Remember that you can't have click handlers on drawn sprites inside the canvas, only on the canvas itself; you check whether the mouse co-ordinates are inside the drawn sprites.

In your scenario I would simply duplicate the image that was dropped in and pass that to the second canvas element. I'm assuming that you're doing some kind of two-up image editing application; in this case I would have one 'drop zone' on the left for the image to go in, and then it would appear, editable on the right hand side. And then have click handlers only on one canvas. I have also got some more thoughts on this in this thread.

Sign up to request clarification or add additional context in comments.

6 Comments

I'll look into this tomorrow and see how I get on, thanks for the help.
Hi Ben, I am working on a two image editing type application but it will be two different images. So I think I need to have 2 separate canvases as the images will be scaled on the fly for display in the browser. I'm not uploading images to a server. The only other way I can think to do it is if I have one large canvas and try to control the scaling in relation to a selected size/area within the canvas. Does that sound more feasible? Thanks for your help
What you could do is have one canvas per image; then a third canvas to handle all of the other drawing and the event functions. The first time you drop the image it would go on one canvas, second time the second canvas. Use CSS to position the canvases over each other with position:absolute & z-index. Hope that helps.
So Ben are you saying that I'd have my 2 images side by side over the 3rd canvas which should be that same size as both images combined and would hold all eventhandlers? So in theory if a click occurs you are checking in an area on the 3rd canvas which relates directly to whichever canvas is above the clicked area? SO this means taking in the clicked co-ords and having an action based around the location? Sorry for the questions I'm a bit slow on the uptake.. Thanks for the advice.
Yep, exactly right. As the canvas is just a means of drawing graphics to the screen you need to calculate the co-ordinates of the mouse relative to the canvas element whenever you want to add some interaction.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.