0

I'm working on a tool which will pick colors from an image, and I'm trying to use draggable divs to highlight the color in an image to add to the palette. The code I have works in the preview function of espresso, but once it's deployed to the website, the background color does not update real-time. Instead it will update when I scroll the window down or sometimes after a delay. Here is the relevant code:

for (i=0; i<maxPaletteSize; i++)
{
    circleDiv[i] = document.getElementById('circle' + i);
    $("#circle" + i).draggable({
        drag: function(event, ui) {
            // find current x,y of div
            var circleX = ui.position.left;
            var circleY = ui.position.top;

            // figure out what color pixel the circle is over
            var pixelNum = Math.round(circleY * img.width + circleX) * 4;
            var color = "rgba(" + imgData.data[pixelNum] + "," + imgData.data[pixelNum+1] + "," + imgData.data[pixelNum+2] + ")";

            // change div background to the appropriate color
            $(ui.helper).css({backgroundColor: color});   
        }
    });

}

When I step through the code, the color is set correctly, it's just the backgroundColor does not update real time (although it's more responsive when I step through the code). I've tried using animate as well as changing the display to none and then inline (suggestions I've seen for other issues posted here), but nothing makes it respond real time.

Any help would be appreciated.

Editing to add the code where the divs are initially set up. I store all the divs in an array for easier access in other parts of the code.

// draw the circles
for (i=0; i<paletteSize; i++)
{
    // get the color from the palette
    var paletteColorIdx = paletteCircles[i].palette;
    // show the div
    circleDiv[i].style.display = 'inline';
    // calculate the absolute x,y coords
    circleDiv[i].style.left = (uiFrame.offsetLeft + paletteCircles[i].x - circleDiv[i].offsetWidth/2) + "px";
    circleDiv[i].style.top = (uiFrame.offsetTop + paletteCircles[i].y - circleDiv[i].offsetHeight/2) + "px";
    // set the color
    circleDiv[i].style.backgroundColor = "rgb(" + palette[paletteColorIdx][0] + "," + palette[paletteColorIdx][1] + ","  + palette[paletteColorIdx][2] + ")";
}

jsfiddle link: http://jsfiddle.net/FzxNk/6/

To see behavior:

  1. Load an image.

  2. Move one of the circles onto an area that is a different color (it should be updating the colors as you move, but it doesn't.)

  3. Move another circle off the image and then back on the image.

  4. When you move the circle onto the image, the previous circle will "pop" to the correct color, and the one you just moved will be black.

2 Answers2

1

It looks like a problem with blending the div and canvas layers. You need the layers to be positioned. You may also need to manage your z-indexes. I added some console.log() statements that convinced me that your div's background color is getting updated, but you just aren't seeing it until you move it off the active canvas area. So, it's not a problem with updating the DOM, it's a display problem with canvas/div interactions. Honestly, it's a browser bug, but you can work around it.

Some more info here: Placing a <div> within a <canvas>

Community
  • 1
  • 1
  • 1
    Another option is to use the canvas for your image data, but use an ordinary image (not canvas) for display. Probably not as straightforward, but if browser bugs are getting in your way, that would be a way to avoid them altogether. – Jason Wehmhoener Mar 12 '13 at 18:05
  • There also seems to be an issue with uploading an image of a different size than your canvas area. The entire image is displayed, but only the canvas area that was previously defined seems to contain image data. Try dragging one of the circles around the edge of the top left corner of the image, in and out of the image boundary, then try the same thing in the bottom right corner and notice the difference. – Jason Wehmhoener Mar 12 '13 at 18:07
  • Tidying up sizes, positions, position type, and z-index will go a long way to fixing this. – Jason Wehmhoener Mar 12 '13 at 18:08
  • I'm smack dab in the middle of a re-factor (moving things to div and off of canvases which is what was being done before) and some of the wackiness you're seeing with the images of different sizes is part of that, I hope. I'll take a look at the div link above and see if that fixes the problem, thank you so much! – Anne Sullivan Mar 12 '13 at 19:00
  • 1
    Let me know. If position and z-index don't do it, you might consider moving the canvas off-screen and using an ordinary image for display. If you think you might need to do that, but need a better explanation, give me a shout. – Jason Wehmhoener Mar 12 '13 at 19:12
  • Changing the z-indexes didn't work (even when I set the positions to relative or absolute. However, having the canvas off screen and drawing over a regular image did in fact fix the problem!If you write it up as an answer, I'll mark it as the correct answer. :) – Anne Sullivan Mar 12 '13 at 21:33
0

Try this out:-

http://jsfiddle.net/FzxNk/1/

Use

$(ui.helper).css("background",color);
Community
  • 1
  • 1
Aditya Singh
  • 9,512
  • 5
  • 32
  • 55
  • I changed it to background, but that made it not update at all. I'm adding to my initial question with the way I'm initializing things in case the problem is there. – Anne Sullivan Mar 12 '13 at 05:34
  • I did, it works in the JSFiddle, but it doesn't solve the problem in my code. I've edited my original post to include more code, in case the problem is elsewhere. – Anne Sullivan Mar 12 '13 at 05:44
  • Will it be possible for you to create a JS fiddle for your problem?? – Aditya Singh Mar 12 '13 at 05:45
  • It's part of a much bigger project (mid-development/refactor, yay!), so I'm not sure how helpful this will be, but here you go. http://jsfiddle.net/FzxNk/1/ To see the behavior in the jsfiddle do the following: 1. load an image 2. Move one of the circles over another color (desired behavior: the color in the circle updates based on the color it's over) 3. Move a second circle off the image then back on the image. 4. The previous circle you moved will now "pop" to the correct color. The circle you moved off the image will be black. – Anne Sullivan Mar 12 '13 at 06:10