I have a web page that displays an image excerpt from a document using drawimage(x,z,width,height)
. The user has the ability to draw a rectangle around any given line on the image by clicking the line. The image then has a rectangle drawn on it using rect(x,y,w,h)
.
Using the JavaScript magnifier, the user can hover over the image to see a zoomed in version. However, it does not show the rectangle drawn on to the image on the canvas.
Is it possible to draw both the rectangle and the image? Currently this is the setup for the magnifier:
// - Setup the magnifier component var glass, w, h, bw; glass = document.getElementById("magnifier"); // Get pre-existing div for the magnifier glass.setAttribute("class", "img-magnifier-glass"); // Set background properties for the magnifier glass: glass.style.backgroundImage = 'url("' + pRow.getValue("imgPath") + '")'; // pRow here refers to a parameter array that is passed in containing data about the image and rectangle glass.style.backgroundRepeat = "no-repeat"; glass.style.backgroundSize = imgwidth + "px " + imgheight + "px"; bw = 3; // Border width of the magnifier glass. w = glass.offsetWidth / 2; h = glass.offsetHeight / 2;
Later on there is code to actually move the background position. But I don’t see a way to show the rectangle that is drawn on top of the image, in the canvas, on the magnifier.
Advertisement
Answer
Finally I have solved it and this one was quite the task.
To do it
- I had to draw an offscreen canvas
- Then on this new canvas copy the current master image and draw on a rectangle
- Serialise the result in a URL
- Then pass this URL to the magnifier background image property
This does introduce a long load time each time you want to change the rectangle location. But allows for the rectangle to become part of the image so the magnifier picks it up.
Here is the code (this was done in Omnis Studio if anything looks off from normal JavaScript (also there is a lot of code before this. But this is the solution, so I’ll just show this bit)):
// Draw the same orange box, but on the original image size var img = document.getElementById('jp') // The master image. It will // have been already loaded by now // Create an offscreen canvas, put the image and then the bounding box //var mc = document.createElement("canvas") // Get an offscreen canvas. Saves from having to create it each time var mc = document.getElementById('offscreenCanvas') // Make the canvas the same size as the master image. // Otherwise, whatever we render will be truncated. mc.width = imgwidth mc.height = imgheight // Get the drawing context for this offscreen canvas var mctx = mc.getContext("2d") // Erase the previous box (if any) mctx.clearRect(0, 0, mc.width, mc.height) // Draw the full image onto our magnifier canvas, starting at (0, 0) mctx.drawImage(img, 0, 0, imgwidth, imgheight) mctx.beginPath() // Create our selection box mctx.strokeStyle = "orange"// mctx.lineWidth = 8 // Because we're "zoomed in", make this line a little thicker boxX = pRow.getValue("x") // Top left x coordinate - unscaled coordinates boxY = pRow.getValue("y") // top left y coordinate boxW = pRow.getValue("width") // Distance right boxH = pRow.getValue("height") // Distance down mctx.rect(boxX, boxY, boxW, boxH) mctx.stroke() // Serialise the result of overlaying the box on the image var r_img = mc.toDataURL("image/png") // window.location = r_img // Debugging ... open image in a new // window window.open(r_img, "toDataURL() image") // Get pre-existing div for the magnifier glass = document.getElementById("magnifier") // Our rendered image glass.style.backgroundImage = "url(" + r_img + ")"
If anyone can find a way to do this without needing to constantly reload the image and cause a large amount of lag/wait time. Please let me know.