|  |  | @@ -0,0 +1,93 @@ | 
		
	
		
			
			|  |  |  | let overlayLoaded = false; | 
		
	
		
			
			|  |  |  | let baseLoaded = false; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | let radius = 200; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | document.addEventListener("DOMContentLoaded", e => { | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const overlayImg = document.querySelector("#overlay-img"); | 
		
	
		
			
			|  |  |  | const baseImg = document.querySelector("#base-img"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayImg.addEventListener("load", e => { | 
		
	
		
			
			|  |  |  | console.log("The overlay is loaded"); | 
		
	
		
			
			|  |  |  | overlayLoaded = true; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (overlayLoaded && baseLoaded) { | 
		
	
		
			
			|  |  |  | setup(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | baseImg.addEventListener("load", e => { | 
		
	
		
			
			|  |  |  | console.log("The base is loaded"); | 
		
	
		
			
			|  |  |  | baseLoaded = true; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (overlayLoaded && baseLoaded) { | 
		
	
		
			
			|  |  |  | setup(); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | }) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | function setup() { | 
		
	
		
			
			|  |  |  | const overlay = document.querySelector("#overlay"); | 
		
	
		
			
			|  |  |  | const base = document.querySelector("#base"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const overlayImg = document.querySelector("#overlay-img"); | 
		
	
		
			
			|  |  |  | const baseImg = document.querySelector("#base-img"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /** @type {CanvasRenderingContext2D} */ | 
		
	
		
			
			|  |  |  | const overlayCtx = overlay.getContext("2d"); | 
		
	
		
			
			|  |  |  | /** @type {CanvasRenderingContext2D} */ | 
		
	
		
			
			|  |  |  | const baseCtx = base.getContext("2d"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | baseCtx.canvas.width = baseImg.width; | 
		
	
		
			
			|  |  |  | baseCtx.canvas.height = baseImg.height; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | baseCtx.drawImage(baseImg, 0, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.canvas.width = overlayImg.width; | 
		
	
		
			
			|  |  |  | overlayCtx.canvas.height = overlayImg.height; | 
		
	
		
			
			|  |  |  |  | 
		
	
		
			
			|  |  |  | overlayCtx.drawImage(overlayImg, 0, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlay.addEventListener("mousemove", e => { | 
		
	
		
			
			|  |  |  | let x = e.clientX - e.target.getBoundingClientRect().x; | 
		
	
		
			
			|  |  |  | let y = e.clientY - e.target.getBoundingClientRect().y; | 
		
	
		
			
			|  |  |  | updateOverlay(x, y); | 
		
	
		
			
			|  |  |  | }); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | console.log("Done"); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | function updateOverlay(x, y) { | 
		
	
		
			
			|  |  |  | console.log("MOVE") | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /** @type {CanvasRenderingContext2D} */ | 
		
	
		
			
			|  |  |  | const overlayCtx = overlay.getContext("2d"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const overlayImg = document.querySelector("#overlay-img"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const w = overlayCtx.canvas.width; | 
		
	
		
			
			|  |  |  | const h = overlayCtx.canvas.height; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.save(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.globalCompositeOperation = "source-over"; | 
		
	
		
			
			|  |  |  | overlayCtx.clearRect(0, 0, w, h); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.beginPath(); | 
		
	
		
			
			|  |  |  | overlayCtx.ellipse(x, y, radius, radius, 0, 0, 2 * Math.PI); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | const gradient = overlayCtx.createRadialGradient(x, y, 0, x, y, radius); | 
		
	
		
			
			|  |  |  | gradient.addColorStop(0.75, '#000000FF'); | 
		
	
		
			
			|  |  |  | gradient.addColorStop(1, '#00000000'); | 
		
	
		
			
			|  |  |  | overlayCtx.fillStyle = gradient; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.fill(); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.globalCompositeOperation = "source-in"; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.drawImage(overlayImg, 0, 0); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | overlayCtx.restore(); | 
		
	
		
			
			|  |  |  | } |