From 840dda49216de59cc3f68913f4724a02d865f4a5 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Thu, 20 Jun 2024 15:51:16 +0100 Subject: [PATCH 1/6] Fixed: Track light direction with rotation and flip --- src/plugins/Relight.js | 91 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/src/plugins/Relight.js b/src/plugins/Relight.js index 8fc21f8..b4b4470 100644 --- a/src/plugins/Relight.js +++ b/src/plugins/Relight.js @@ -81,25 +81,80 @@ class Relight extends React.Component { const control = document.getElementById(id); const boundingBox = control.getBoundingClientRect(); + let xMove; + let yMove; + let style; + if (event.type === 'mousemove') { event.preventDefault(); - this.mouseX = event.clientX - boundingBox.left; - this.mouseY = event.clientY - boundingBox.top; + xMove = event.clientX - boundingBox.left; + yMove = event.clientY - boundingBox.top; } else if (event.type === 'touchmove') { this.mouseDown = true; - this.mouseX = event.touches[0].clientX - boundingBox.left; - this.mouseY = event.touches[0].clientY - boundingBox.top; + xMove = event.touches[0].clientX - boundingBox.left; + yMove = event.touches[0].clientY - boundingBox.top; + } + switch (this.rotation) { + case 0: + this.mouseX = xMove; + this.mouseY = yMove; + this.lightX = (this.mouseX / 100) * 2 - 1; + this.lightY = (this.mouseY / 100) * 2 - 1; + this.lightX = this.flipped ? -this.lightX : this.lightX; + style = + `radial-gradient(at ` + + this.mouseX + + `% ` + + this.mouseY + + `%, #ffffff, #000000)`; + break; + case -270: + case 90: + this.mouseX = yMove; + this.mouseY = xMove; + this.lightX = (this.mouseX / 100) * 2 - 1; + this.lightY = -((this.mouseY / 100) * 2 - 1); + this.lightY = this.flipped ? -this.lightY : this.lightY; + this.lightY = this.flipped ? this.lightY : -this.lightY; + style = + `radial-gradient(at ` + + this.mouseY + + `% ` + + this.mouseX + + `%, #ffffff, #000000)`; + break; + case -180: + case 180: + this.mouseX = xMove; + this.mouseY = yMove; + this.lightX = -((this.mouseX / 100) * 2 - 1); + this.lightY = -((this.mouseY / 100) * 2 - 1); + this.lightX = this.flipped ? -this.lightX : this.lightX; + style = + `radial-gradient(at ` + + this.mouseX + + `% ` + + this.mouseY + + `%, #ffffff, #000000)`; + break; + case -90: + case 270: + this.mouseX = yMove; + this.mouseY = xMove; + this.lightX = -((this.mouseX / 100) * 2 - 1); + this.lightY = (this.mouseY / 100) * 2 - 1; + this.lightY = this.flipped ? -this.lightY : this.lightY; + style = + `radial-gradient(at ` + + this.mouseY + + `% ` + + this.mouseX + + `%, #ffffff, #000000)`; + break; } if (this.mouseDown) { - document.getElementById(id).style.background = - `radial-gradient(at ` + - this.mouseX + - `% ` + - this.mouseY + - `%, #ffffff, #000000)`; - this.lightX = (this.mouseX / 100) * 2 - 1; - this.lightY = (this.mouseY / 100) * 2 - 1; + document.getElementById(id).style.background = style; this.threeCanvasProps.lightX = this.lightX; this.threeCanvasProps.lightY = this.lightY; @@ -565,6 +620,8 @@ class Relight extends React.Component { const excluded_maps = ['composite', 'normal', 'albedo']; this.maps = getMaps(this.props.canvas.iiifImageResources); this.canvasId = this.props.canvas.id; + this.rotation = this.props.viewer.viewport.getRotation(true); + this.flipped = this.props.viewer.viewport.flipped; updateLayer( this.props.state, @@ -575,6 +632,16 @@ class Relight extends React.Component { this.canvasId ); + // add a rotate event handler + this.props.viewer.addHandler('rotate', (event) => { + this.rotation = event.degrees; + }); + + // add a flip event handler + this.props.viewer.addHandler('flip', (event) => { + this.flipped = event.flipped; + }); + // add a custom event handler that listens for the emission of the OpenSeaDragon close event to clean up this.props.viewer.addHandler('close', () => { this.canvasId = this.props.canvas.id; From a9ba01d05c35366e63ccf46bba3167f86c1bd01e Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Thu, 20 Jun 2024 16:48:38 +0100 Subject: [PATCH 2/6] Fixed: Duplicated y flip --- src/plugins/Relight.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/Relight.js b/src/plugins/Relight.js index b4b4470..1fc24d0 100644 --- a/src/plugins/Relight.js +++ b/src/plugins/Relight.js @@ -115,7 +115,6 @@ class Relight extends React.Component { this.lightX = (this.mouseX / 100) * 2 - 1; this.lightY = -((this.mouseY / 100) * 2 - 1); this.lightY = this.flipped ? -this.lightY : this.lightY; - this.lightY = this.flipped ? this.lightY : -this.lightY; style = `radial-gradient(at ` + this.mouseY + From b41cba99e99dbf3b602ddde24147835eed53e234 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Thu, 20 Jun 2024 18:51:43 +0100 Subject: [PATCH 3/6] Attempted Fix: onMove stopping --- src/plugins/Relight.js | 128 ++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 58 deletions(-) diff --git a/src/plugins/Relight.js b/src/plugins/Relight.js index 1fc24d0..b73e23e 100644 --- a/src/plugins/Relight.js +++ b/src/plugins/Relight.js @@ -94,65 +94,77 @@ class Relight extends React.Component { xMove = event.touches[0].clientX - boundingBox.left; yMove = event.touches[0].clientY - boundingBox.top; } - switch (this.rotation) { - case 0: - this.mouseX = xMove; - this.mouseY = yMove; - this.lightX = (this.mouseX / 100) * 2 - 1; - this.lightY = (this.mouseY / 100) * 2 - 1; - this.lightX = this.flipped ? -this.lightX : this.lightX; - style = - `radial-gradient(at ` + - this.mouseX + - `% ` + - this.mouseY + - `%, #ffffff, #000000)`; - break; - case -270: - case 90: - this.mouseX = yMove; - this.mouseY = xMove; - this.lightX = (this.mouseX / 100) * 2 - 1; - this.lightY = -((this.mouseY / 100) * 2 - 1); - this.lightY = this.flipped ? -this.lightY : this.lightY; - style = - `radial-gradient(at ` + - this.mouseY + - `% ` + - this.mouseX + - `%, #ffffff, #000000)`; - break; - case -180: - case 180: - this.mouseX = xMove; - this.mouseY = yMove; - this.lightX = -((this.mouseX / 100) * 2 - 1); - this.lightY = -((this.mouseY / 100) * 2 - 1); - this.lightX = this.flipped ? -this.lightX : this.lightX; - style = - `radial-gradient(at ` + - this.mouseX + - `% ` + - this.mouseY + - `%, #ffffff, #000000)`; - break; - case -90: - case 270: - this.mouseX = yMove; - this.mouseY = xMove; - this.lightX = -((this.mouseX / 100) * 2 - 1); - this.lightY = (this.mouseY / 100) * 2 - 1; - this.lightY = this.flipped ? -this.lightY : this.lightY; - style = - `radial-gradient(at ` + - this.mouseY + - `% ` + - this.mouseX + - `%, #ffffff, #000000)`; - break; - } - if (this.mouseDown) { + switch (this.rotation) { + case 0: + this.mouseX = xMove; + this.mouseY = yMove; + this.lightX = (this.mouseX / 100) * 2 - 1; + this.lightY = (this.mouseY / 100) * 2 - 1; + this.lightX = this.flipped ? -this.lightX : this.lightX; + style = + `radial-gradient(at ` + + this.mouseX + + `% ` + + this.mouseY + + `%, #ffffff, #000000)`; + break; + case -270: + case 90: + this.mouseX = yMove; + this.mouseY = xMove; + this.lightX = (this.mouseX / 100) * 2 - 1; + this.lightY = -((this.mouseY / 100) * 2 - 1); + this.lightY = this.flipped ? -this.lightY : this.lightY; + style = + `radial-gradient(at ` + + this.mouseY + + `% ` + + this.mouseX + + `%, #ffffff, #000000)`; + break; + case -180: + case 180: + this.mouseX = xMove; + this.mouseY = yMove; + this.lightX = -((this.mouseX / 100) * 2 - 1); + this.lightY = -((this.mouseY / 100) * 2 - 1); + this.lightX = this.flipped ? -this.lightX : this.lightX; + style = + `radial-gradient(at ` + + this.mouseX + + `% ` + + this.mouseY + + `%, #ffffff, #000000)`; + break; + case -90: + case 270: + this.mouseX = yMove; + this.mouseY = xMove; + this.lightX = -((this.mouseX / 100) * 2 - 1); + this.lightY = (this.mouseY / 100) * 2 - 1; + this.lightY = this.flipped ? -this.lightY : this.lightY; + style = + `radial-gradient(at ` + + this.mouseY + + `% ` + + this.mouseX + + `%, #ffffff, #000000)`; + break; + default: + this.mouseX = xMove; + this.mouseY = yMove; + this.lightX = (this.mouseX / 100) * 2 - 1; + this.lightY = (this.mouseY / 100) * 2 - 1; + this.lightX = this.flipped ? -this.lightX : this.lightX; + style = + `radial-gradient(at ` + + this.mouseX + + `% ` + + this.mouseY + + `%, #ffffff, #000000)`; + } + document.getElementById(id).style.background = style; this.threeCanvasProps.lightX = this.lightX; this.threeCanvasProps.lightY = this.lightY; From 9ffba89d0d0bcab23c248e7fe1eb65ff16f338de Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Thu, 20 Jun 2024 22:20:29 +0100 Subject: [PATCH 4/6] Fixed: Rotation dropping out of switch statement The rotation was dropping out of the switch statement because the rotation value keeps increasing in 90 deg increments past 360 degs until it is reset. --- src/plugins/Relight.js | 148 ++++++++++++++++++++--------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/src/plugins/Relight.js b/src/plugins/Relight.js index b73e23e..841b4ec 100644 --- a/src/plugins/Relight.js +++ b/src/plugins/Relight.js @@ -77,7 +77,8 @@ class Relight extends React.Component { * The threeCanvasProps are updated in state to cause a re-render each time the mouse is moved whilst the button * is pressed over the component, this updates the props passed to the Three canvas. * */ - onMouseMove(event, id) { + onMouseMove(event, id, rotation) { + event.preventDefault(); const control = document.getElementById(id); const boundingBox = control.getBoundingClientRect(); @@ -86,7 +87,6 @@ class Relight extends React.Component { let style; if (event.type === 'mousemove') { - event.preventDefault(); xMove = event.clientX - boundingBox.left; yMove = event.clientY - boundingBox.top; } else if (event.type === 'touchmove') { @@ -94,77 +94,69 @@ class Relight extends React.Component { xMove = event.touches[0].clientX - boundingBox.left; yMove = event.touches[0].clientY - boundingBox.top; } - if (this.mouseDown) { - switch (this.rotation) { - case 0: - this.mouseX = xMove; - this.mouseY = yMove; - this.lightX = (this.mouseX / 100) * 2 - 1; - this.lightY = (this.mouseY / 100) * 2 - 1; - this.lightX = this.flipped ? -this.lightX : this.lightX; - style = - `radial-gradient(at ` + - this.mouseX + - `% ` + - this.mouseY + - `%, #ffffff, #000000)`; - break; - case -270: - case 90: - this.mouseX = yMove; - this.mouseY = xMove; - this.lightX = (this.mouseX / 100) * 2 - 1; - this.lightY = -((this.mouseY / 100) * 2 - 1); - this.lightY = this.flipped ? -this.lightY : this.lightY; - style = - `radial-gradient(at ` + - this.mouseY + - `% ` + - this.mouseX + - `%, #ffffff, #000000)`; - break; - case -180: - case 180: - this.mouseX = xMove; - this.mouseY = yMove; - this.lightX = -((this.mouseX / 100) * 2 - 1); - this.lightY = -((this.mouseY / 100) * 2 - 1); - this.lightX = this.flipped ? -this.lightX : this.lightX; - style = - `radial-gradient(at ` + - this.mouseX + - `% ` + - this.mouseY + - `%, #ffffff, #000000)`; - break; - case -90: - case 270: - this.mouseX = yMove; - this.mouseY = xMove; - this.lightX = -((this.mouseX / 100) * 2 - 1); - this.lightY = (this.mouseY / 100) * 2 - 1; - this.lightY = this.flipped ? -this.lightY : this.lightY; - style = - `radial-gradient(at ` + - this.mouseY + - `% ` + - this.mouseX + - `%, #ffffff, #000000)`; - break; - default: - this.mouseX = xMove; - this.mouseY = yMove; - this.lightX = (this.mouseX / 100) * 2 - 1; - this.lightY = (this.mouseY / 100) * 2 - 1; - this.lightX = this.flipped ? -this.lightX : this.lightX; - style = - `radial-gradient(at ` + - this.mouseX + - `% ` + - this.mouseY + - `%, #ffffff, #000000)`; - } + // rotation is the total degrees the canvas has rotated, i.e. it stacks, we need to get this back + // to a relative number by using modulus... + const rotationModulus = rotation % 360; + + switch (rotationModulus) { + case 0: + this.mouseX = xMove; + this.mouseY = yMove; + this.lightX = (this.mouseX / 100) * 2 - 1; + this.lightY = (this.mouseY / 100) * 2 - 1; + this.lightX = this.flipped ? -this.lightX : this.lightX; + style = + `radial-gradient(at ` + + this.mouseX + + `% ` + + this.mouseY + + `%, #ffffff, #000000)`; + break; + case -270: + case 90: + this.mouseX = yMove; + this.mouseY = xMove; + this.lightX = (this.mouseX / 100) * 2 - 1; + this.lightY = -((this.mouseY / 100) * 2 - 1); + this.lightY = this.flipped ? -this.lightY : this.lightY; + style = + `radial-gradient(at ` + + this.mouseY + + `% ` + + this.mouseX + + `%, #ffffff, #000000)`; + break; + case -180: + case 180: + this.mouseX = xMove; + this.mouseY = yMove; + this.lightX = -((this.mouseX / 100) * 2 - 1); + this.lightY = -((this.mouseY / 100) * 2 - 1); + this.lightX = this.flipped ? -this.lightX : this.lightX; + style = + `radial-gradient(at ` + + this.mouseX + + `% ` + + this.mouseY + + `%, #ffffff, #000000)`; + break; + case -90: + case 270: + this.mouseX = yMove; + this.mouseY = xMove; + this.lightX = -((this.mouseX / 100) * 2 - 1); + this.lightY = (this.mouseY / 100) * 2 - 1; + this.lightY = this.flipped ? -this.lightY : this.lightY; + style = + `radial-gradient(at ` + + this.mouseY + + `% ` + + this.mouseX + + `%, #ffffff, #000000)`; + } + + if (this.mouseDown) { document.getElementById(id).style.background = style; this.threeCanvasProps.lightX = this.lightX; this.threeCanvasProps.lightY = this.lightY; @@ -789,13 +781,21 @@ class Relight extends React.Component { mouseX={this.state.threeCanvasProps.mouseX} mouseY={this.state.threeCanvasProps.mouseY} onMouseMove={(event) => - this.onMouseMove(event, this.relightLightDirectionID) + this.onMouseMove( + event, + this.relightLightDirectionID, + this.rotation + ) } onMouseDown={(event) => this.onMouseDown(event)} onMouseUp={(event) => this.onMouseUp(event)} onMouseLeave={(event) => this.onMouseLeave(event)} onTouchMove={(event) => - this.onMouseMove(event, this.relightLightDirectionID) + this.onMouseMove( + event, + this.relightLightDirectionID, + this.rotation + ) } /> Date: Fri, 21 Jun 2024 11:20:28 +0100 Subject: [PATCH 5/6] Fixed: Move prevent default back --- src/plugins/Relight.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/Relight.js b/src/plugins/Relight.js index 841b4ec..3c24475 100644 --- a/src/plugins/Relight.js +++ b/src/plugins/Relight.js @@ -78,7 +78,6 @@ class Relight extends React.Component { * is pressed over the component, this updates the props passed to the Three canvas. * */ onMouseMove(event, id, rotation) { - event.preventDefault(); const control = document.getElementById(id); const boundingBox = control.getBoundingClientRect(); @@ -87,6 +86,7 @@ class Relight extends React.Component { let style; if (event.type === 'mousemove') { + event.preventDefault(); xMove = event.clientX - boundingBox.left; yMove = event.clientY - boundingBox.top; } else if (event.type === 'touchmove') { From 6f75019b3078a520f3d4843abfb1c8832bd5fd71 Mon Sep 17 00:00:00 2001 From: Richard Benjamin Allen Date: Fri, 21 Jun 2024 11:57:55 +0100 Subject: [PATCH 6/6] Updated: Improved docstring --- src/plugins/Relight.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/Relight.js b/src/plugins/Relight.js index 3c24475..31c047a 100644 --- a/src/plugins/Relight.js +++ b/src/plugins/Relight.js @@ -75,7 +75,8 @@ class Relight extends React.Component { * The onMouseMove method tracks the mouse coordinates over the RelightLightDirectionControl component to allow the * style of the component to change and indicate to the user which direction the light should be shining from. * The threeCanvasProps are updated in state to cause a re-render each time the mouse is moved whilst the button - * is pressed over the component, this updates the props passed to the Three canvas. + * is pressed over the component, this tracks the current rotation and flipped status of the canvas, + * this also updates the props passed to the Three canvas. * */ onMouseMove(event, id, rotation) { const control = document.getElementById(id);