The following code shows how to create an image magnifier.
It cuts out a section of a small image and displays the enlarged one on the canvas.
<!DOCTYPE HTML> <html> <head> <script> class EventManager{//from ww w. j av a 2s .com constructor(canvasId){ this.canvas = document.getElementById(canvasId); this.context = this.canvas.getContext("2d"); this.drawStage = undefined; this.listening = false; // desktop flags this.mousePos = null; this.mouseDown = false; this.mouseUp = false; this.mouseOver = false; this.mouseMove = false; // mobile flags this.touchPos = null; this.touchStart = false; this.touchMove = false; this.touchEnd = false; // Region Events this.currentRegion = null; this.regionIndex = 0; this.lastRegionIndex = -1; this.mouseOverRegionIndex = -1; } getContext(){ return this.context; } getCanvas(){ return this.canvas; } clear(){ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); } getCanvasPos = function(){ let obj = this.getCanvas(); let top = 0; let left = 0; while (obj.tagName != "BODY") { top += obj.offsetTop; left += obj.offsetLeft; obj = obj.offsetParent; } return { top: top, left: left }; } setDrawStage(func){ this.drawStage = func; this.listen(); } reset(evt){ if (!evt) { evt = window.event; } this.setMousePosition(evt); this.setTouchPosition(evt); this.regionIndex = 0; if (this.drawStage !== undefined) { this.drawStage(); } // desktop flags this.mouseOver = false; this.mouseMove = false; this.mouseDown = false; this.mouseUp = false; // mobile touch flags this.touchStart = false; this.touchMove = false; this.touchEnd = false; } listen(){ let that = this; if (this.drawStage !== undefined) { this.drawStage(); } // desktop events this.canvas.addEventListener("mousedown", function(evt){ that.mouseDown = true; that.reset(evt); }, false); this.canvas.addEventListener("mousemove", function(evt){ that.reset(evt); }, false); this.canvas.addEventListener("mouseup", function(evt){ that.mouseUp = true; that.reset(evt); }, false); this.canvas.addEventListener("mouseover", function(evt){ that.reset(evt); }, false); this.canvas.addEventListener("mouseout", function(evt){ that.mousePos = null; }, false); // mobile events this.canvas.addEventListener("touchstart", function(evt){ evt.preventDefault(); that.touchStart = true; that.reset(evt); }, false); this.canvas.addEventListener("touchmove", function(evt){ evt.preventDefault(); that.reset(evt); }, false); this.canvas.addEventListener("touchend", function(evt){ evt.preventDefault(); that.touchEnd = true; that.reset(evt); }, false); } getMousePos(evt){ return this.mousePos; } getTouchPos(evt){ return this.touchPos; } setMousePosition(evt){ let mouseX = evt.clientX - this.getCanvasPos().left + window.pageXOffset; let mouseY = evt.clientY - this.getCanvasPos().top + window.pageYOffset; this.mousePos = { x: mouseX, y: mouseY }; } setTouchPosition(evt){ if (evt.touches !== undefined && evt.touches.length == 1) { // Only deal with one finger let touch = evt.touches[0]; // Get the information for finger #1 let touchX = touch.pageX - this.getCanvasPos().left + window.pageXOffset; let touchY = touch.pageY - this.getCanvasPos().top + window.pageYOffset; this.touchPos = { x: touchX, y: touchY }; } } beginRegion = function(){ this.currentRegion = {}; this.regionIndex++; } addRegionEventListener = function(type, func){ let event = (type.indexOf('touch') == -1) ? 'on' + type : type; this.currentRegion[event] = func; } closeRegion(){ let pos = this.touchPos || this.mousePos; if (pos !== null && this.context.isPointInPath(pos.x, pos.y)) { if (this.lastRegionIndex != this.regionIndex) { this.lastRegionIndex = this.regionIndex; } // handle onmousedown if (this.mouseDown && this.currentRegion.onmousedown !== undefined) { this.currentRegion.onmousedown(); this.mouseDown = false; } // handle onmouseup else if (this.mouseUp && this.currentRegion.onmouseup !== undefined) { this.currentRegion.onmouseup(); this.mouseUp = false; } // handle onmouseover else if (!this.mouseOver && this.regionIndex != this.mouseOverRegionIndex && this.currentRegion.onmouseover !== undefined) { this.currentRegion.onmouseover(); this.mouseOver = true; this.mouseOverRegionIndex = this.regionIndex; } // handle onmousemove else if (!this.mouseMove && this.currentRegion.onmousemove !== undefined) { this.currentRegion.onmousemove(); this.mouseMove = true; } // handle touchstart if (this.touchStart && this.currentRegion.touchstart !== undefined) { this.currentRegion.touchstart(); this.touchStart = false; } // handle touchend if (this.touchEnd && this.currentRegion.touchend !== undefined) { this.currentRegion.touchend(); this.touchEnd = false; } // handle touchmove if (!this.touchMove && this.currentRegion.touchmove !== undefined) { this.currentRegion.touchmove(); this.touchMove = true; } } else if (this.regionIndex == this.lastRegionIndex) { this.lastRegionIndex = -1; this.mouseOverRegionIndex = -1; // handle mouseout condition if (this.currentRegion.onmouseout !== undefined) { this.currentRegion.onmouseout(); } } } } function loadImages(sources, callback){ let loadedImages = 0; let numImages = 0; let images = {}; // get num of sources for (let src in sources) { numImages++; } // load images for (let src in sources) { images[src] = new Image(); images[src].onload = function(){ // call callback function when images // have loaded if (++loadedImages >= numImages) { callback(images); } }; images[src].src = sources[src]; } } function drawMagnifier(config){ let context = config.context; let images = config.images; let mousePos = config.mousePos; let imageX = config.imageX; let imageY = config.imageY; let magWidth = config.magWidth; let magHeight = config.magHeight; let smallWidth = config.smallWidth; let smallHeight = config.smallHeight; let largeWidth = config.largeWidth; let largeHeight = config.largeHeight; let sourceX = ((mousePos.x - imageX) * largeWidth / smallWidth) - magWidth / 2; let sourceY = ((mousePos.y - imageY) * largeHeight / smallHeight) - magHeight / 2; let destX = mousePos.x - magWidth / 2; let destY = mousePos.y - magHeight / 2; let viewWidth = magWidth; let viewHeight = magHeight; let viewX = destX; let viewY = destY; let drawMagImage = true; if (sourceX < 0) { if (sourceX > -1 * magWidth) { let diffX = -1 * sourceX; viewX += diffX; viewWidth -= diffX; sourceX = 0; } else { drawMagImage = false; } } if (sourceX > largeWidth - magWidth) { if (sourceX < largeWidth) { viewWidth = largeWidth - sourceX; } else { drawMagImage = false; } } if (sourceY < 0) { if (sourceY > -1 * magHeight) { let diffY = -1 * sourceY; viewY += diffY; viewHeight -= diffY; sourceY = 0; } else { drawMagImage = false; } } if (sourceY > largeHeight - magHeight) { if (sourceY < largeHeight) { viewHeight = largeHeight - sourceY; } else { drawMagImage = false; } } context.beginPath(); context.fillStyle = "white"; context.fillRect(destX, destY, magWidth, magHeight); if (drawMagImage) { context.beginPath(); context.drawImage(images.jet1Image, sourceX, sourceY, viewWidth, viewHeight, viewX, viewY, viewWidth, viewHeight); } // draw magnifier border context.beginPath(); context.lineWidth = 2; context.strokeStyle = "black"; context.strokeRect(destX, destY, magWidth, magHeight); } function drawImages(images){ let events = new EventManager("myCanvas"); let canvas = events.getCanvas(); let context = events.getContext(); // define magnifier dependencies let imageX = canvas.width / 2 - images.jet2Image.width / 2; let imageY = canvas.height / 2 - images.jet2Image.height / 2; let magWidth = 200; let magHeight = 150; let smallWidth = images.jet2Image.width; let smallHeight = images.jet2Image.height; let largeWidth = images.jet1Image.width; let largeHeight = images.jet1Image.height; events.setDrawStage(function(){ let mousePos = events.getMousePos(); this.clear(); context.drawImage(images.jet2Image, imageX, imageY, smallWidth, smallHeight); // draw rectangular region for image context.beginPath(); context.lineWidth = 2; context.strokeStyle = "black"; context.strokeRect(imageX, imageY, smallWidth, smallHeight); context.closePath(); if (mousePos !== null) { drawMagnifier({ context: context, images: images, mousePos: mousePos, imageX: imageX, imageY: imageY, magWidth: magWidth, magHeight: magHeight, smallWidth: smallWidth, smallHeight: smallHeight, largeWidth: largeWidth, largeHeight: largeHeight }); } }); canvas.addEventListener("mouseout", function(){ events.drawStage(); }, false); } window.onload = function(){ let sources = { jet2Image: "http://java2s.com/style/demo/jet2.png", jet1Image: "http://java2s.com/style/demo/jet2.png" }; loadImages(sources, drawImages); }; </script> </head> <body> <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;"> </canvas> </body> </html>