Skip to content

Commit

Permalink
Merge pull request #134 from bodleian/qa
Browse files Browse the repository at this point in the history
Release 2024-11-26
  • Loading branch information
BeebBenjamin authored Nov 26, 2024
2 parents edf806f + c36f403 commit 217b41e
Show file tree
Hide file tree
Showing 15 changed files with 525 additions and 206 deletions.
372 changes: 220 additions & 152 deletions src/plugins/Relight.js

Large diffs are not rendered by default.

3 changes: 1 addition & 2 deletions src/plugins/RelightAmbientLightIntensity.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class RelightAmbientLightIntensity extends React.Component {
style={{
marginTop: '20px',
marginBottom: '20px',
marginLeft: '8px',
marginRight: '8px',
height: '87px',
padding: '0px 15px',
}}
size={size}
orientation={orientation}
Expand Down
3 changes: 1 addition & 2 deletions src/plugins/RelightDirectionalLightIntensity.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class RelightDirectionalLightIntensity extends React.Component {
style={{
marginTop: '20px',
marginBottom: '20px',
marginLeft: '8px',
marginRight: '8px',
height: '87px',
padding: '0px 15px',
}}
size={size}
orientation={orientation}
Expand Down
56 changes: 56 additions & 0 deletions src/plugins/RelightExpandSlidersButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import ArrowDownwardIcon from '@material-ui/icons/ArrowDownward';
import ArrowUpwardIcon from '@material-ui/icons/ArrowUpward';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
import { MiradorMenuButton } from 'mirador/dist/es/src/components/MiradorMenuButton';

import PropTypes from 'prop-types';

/**
* The RelightExpandSlidersButton component is a plug-in button used to collapse or expand the shader sliders.
* The icon used by the component toggles with the drawerOpen state.
*/
class RelightExpandSlidersButton extends React.Component {
constructor(props) {
super(props);
}
render() {
const { drawerOpen, aspect, onClick } = this.props;

let icon = drawerOpen ? <ArrowUpwardIcon /> : <ArrowDownwardIcon />;

if (aspect === 'landscape') {
icon = drawerOpen ? <ArrowBackIcon /> : <ArrowForwardIcon />;
}

return (
<MiradorMenuButton
style={{
clear: 'both',
}}
aria-label={
drawerOpen
? 'Collapse relighting shader control sliders'
: 'Expand shader control sliders to take control of the light levels and shading parameters. ' +
'You can control light intensity, metalness, roughness, and normal depth here; there is a ' +
'description of what each one does on the relevant slider, just hover over it and see.'
}
onClick={onClick}
>
{icon}
</MiradorMenuButton>
);
}
}

RelightExpandSlidersButton.propTypes = {
/** The drawerOpen prop tells the button to render as if the sliders are expanded or closed **/
drawerOpen: PropTypes.bool.isRequired,
/** The aspect prop contains the current aspect of the window the element is in i.e. portrait or landscape **/
aspect: PropTypes.string.isRequired,
/** The onClick prop is a function used to manage component behaviour when the component is clicked **/
onClick: PropTypes.func.isRequired,
};

export default RelightExpandSlidersButton;
21 changes: 14 additions & 7 deletions src/plugins/RelightHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export function generateTiles(
const th = Math.min(tileHeight, scaledHeightRemaining);

let tileFormat = 'jpg';

if (preferredFormats) {
tileFormat = preferredFormats[0];
}
Expand Down Expand Up @@ -162,6 +161,8 @@ export function getMaps(annotationBodies) {

if (service !== null) {
layers[element.id] = service.__jsonld.mapType;
} else {
layers[element.id] = 'none';
}
});
return layers;
Expand Down Expand Up @@ -301,12 +302,7 @@ export function reduceLayers(layers, maps, excludedMaps) {
return layers.reduce(function (accumulator, layer, index) {
let visibility;
let mapType;
if (maps[layer.id] === undefined) {
mapType = 'undefined';
} else {
mapType = maps[layer.id].trim();
}

mapType = maps[layer.id].trim();
visibility = excludedMaps.includes(mapType);
accumulator[layer.id] = {
index: index,
Expand All @@ -326,3 +322,14 @@ export function reduceLayers(layers, maps, excludedMaps) {
export function* setLayers(windowId, canvasId, updateLayers, payload) {
yield put(updateLayers(windowId, canvasId, payload));
}

/**
* Gets the aspect of the window i.e. is it portrait or landscape, based on width and height
* **/
export function getAspect() {
let aspect = 'portrait';
if (window.innerHeight < window.innerWidth) {
aspect = 'landscape';
}
return aspect;
}
13 changes: 11 additions & 2 deletions src/plugins/RelightLightControls.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,18 @@ class RelightLightControls extends React.Component {
}
render() {
// children is used so that parent props can be passed to the children components inside its tags
const { children } = this.props;
const { children, aspect } = this.props;

let display = 'block';

if (aspect === 'landscape') {
display = 'flex';
}

return (
<div
style={{
display: 'flex',
display: display,
}}
>
{children}
Expand All @@ -30,6 +37,8 @@ RelightLightControls.propTypes = {
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]).isRequired,
/** The aspect prop contains the current aspect of the window the element is in i.e. portrait or landscape **/
aspect: PropTypes.string.isRequired,
};

export default RelightLightControls;
141 changes: 128 additions & 13 deletions src/plugins/RelightLightDirection.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,134 @@
import React from 'react';
import Tooltip from '@material-ui/core/Tooltip';
import PropTypes from 'prop-types';
import { ReactComponent as Angles } from './public/angles.svg';

/**
* The RelightLightDirection component is a circular div component that is styled to look like a hemisphere being lit
* from an angle by a light. It allows the user to have a cheap way to see which direction the directional light is
* pointing (as it is just a 2D html object). It will also detect various mouse events that allow the user to use it
* to also change the direction of the directional light in the Three canvas scene. The movement of x and y is mapped
* to the direction of the directional light in the Three canvas scene.
*/
**/
class RelightLightDirection extends React.Component {
constructor(props) {
super(props);
this.rotation = this.props.rotation % 360;
this.adjustedAngle = 0;
this.currentAngle = 0;
this.transform = `rotate(${this.rotation}deg)`;
this.state = {
calculatedBackgroundStyle:
`radial-gradient(at ` + 50 + `% ` + 50 + `%, #ffffff, #000000)`,
};
}

/**
* The rotatePoint method re-positions the RelightLightDirection based on rotation of the OpenSeaDragon canvas
* flip is currently not supported.
* @param {number} x The current x mouse position over the component
* @param {number} y The current y mouse position over the component
* @param {boolean} rotate If the canvas was rotated
* @param {boolean} flipped If the canvas is currently flipped
* @param {number} angle The current angle that the OpenSeaDragon canvas is rotated by
* */
rotatePoint(x, y, rotate, flipped, angle = 0) {
if (!rotate) {
switch (angle) {
case 0:
this.adjustedAngle = 0;
break;
case -270:
case 90:
this.adjustedAngle = 90;
break;
case -180:
case 180:
this.adjustedAngle = 180;
break;
case -90:
case 270:
this.adjustedAngle = 270;
break;
}
}
const radians = (Math.PI / 180) * (angle - this.adjustedAngle);
const cx = 50;
const cy = 50;
const cos = Math.cos(radians);
const sin = Math.sin(radians);
const nx = cos * (x - cx) - sin * (y - cy) + cx;
const ny = cos * (y - cy) + sin * (x - cx) + cy;

if (rotate || flipped) {
this.setState({
calculatedBackgroundStyle:
`radial-gradient(at ` +
Math.abs(nx) +
`% ` +
Math.abs(ny) +
`%, #ffffff, #000000)`,
});
} else {
this.setState({
calculatedBackgroundStyle:
`radial-gradient(at ` +
Math.abs(x) +
`% ` +
Math.abs(y) +
`%, #ffffff, #000000)`,
});
}
}

/**
* The componentDidUpdate method is a standard React class method that is used to run other methods whenever state or
* props are updated. Here we used it to re-render the RelightLightDirection control if there is a change in state detected.
* @param prevProps the previous props sent to the Relight component
* @param prevState the previous state set in the Relight component
* @param snapshot a snapshot of the component before the next render cycle, you can use the React class method
* getSnapShotBeforeUpdate to create this
* **/
componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.rotation !== this.props.rotation) {
this.rotatePoint(
this.props.moveX,
this.props.moveY,
true,
this.props.flipped,
this.props.rotation % 360
);
}
if (
prevProps.moveX !== this.props.moveX ||
prevProps.moveY !== this.props.moveY
) {
this.rotatePoint(
this.props.moveX,
this.props.moveY,
false,
this.props.flipped,
this.props.rotation % 360
);
}
if (prevProps.flipped !== this.props.flipped) {
this.rotatePoint(
this.props.moveX,
this.props.moveY,
false,
this.props.flipped,
this.props.rotation % 360
);
}
}
/**
Render the RelightLightDirection component
@returns {JSX.Element}
*/
render() {
const {
id,
tooltipTitle,
mouseX,
mouseY,
onMouseMove,
onMouseDown,
onMouseUp,
Expand All @@ -33,14 +143,9 @@ class RelightLightDirection extends React.Component {
border: '#000000',
width: '100px',
height: '100px',
borderRadius: '50px',
margin: '13px',
background:
`radial-gradient(at ` +
mouseX +
`% ` +
mouseY +
`%, #ffffff, #000000)`,
borderRadius: '50px',
background: this.state.calculatedBackgroundStyle,
}}
aria-label="Change light direction"
aria-expanded="False"
Expand All @@ -49,7 +154,9 @@ class RelightLightDirection extends React.Component {
onMouseUp={onMouseUp}
onMouseLeave={onMouseLeave}
onTouchMove={onMouseMove}
/>
>
<Angles width="100px" height="100px" alt="" />
</div>
</Tooltip>
</>
);
Expand All @@ -61,6 +168,10 @@ RelightLightDirection.propTypes = {
id: PropTypes.string.isRequired,
/** The tooltipTitle prop is used to define the text that appears in the hover over component tooltip **/
tooltipTitle: PropTypes.string.isRequired,
/** The moveX prop is the raw mouse X position over the component needed for styling changes **/
moveX: PropTypes.number.isRequired,
/** The moveY prop is the raw mouse Y position over the component needed for styling changes **/
moveY: PropTypes.number.isRequired,
/** The onMouseMove prop is a function used to manage the component behaviour when the mouse is moved over **/
onMouseMove: PropTypes.func.isRequired,
/** The onMouseDown prop is a function used to manage the component behaviour when the mouse button is pressed **/
Expand All @@ -72,9 +183,13 @@ RelightLightDirection.propTypes = {
/** The onTouchMove prop is a function used to manage the component behaviour when a finger moved over **/
onTouchMove: PropTypes.func.isRequired,
/** The mouseX prop is the current x coordinate of the mouse or touch event **/
mouseX: PropTypes.number,
mouseX: PropTypes.number.isRequired,
/** The mouseY prop is the current y coordinate of the mouse or touch event **/
mouseY: PropTypes.number,
mouseY: PropTypes.number.isRequired,
/** The rotation prop is the current rotation of the viewer **/
flipped: PropTypes.bool.isRequired,
/** The flipped prop is the current flip state of the OpenSeaDragon viewer **/
rotation: PropTypes.number.isRequired,
};

RelightLightDirection.defaultProps = {
Expand Down
7 changes: 3 additions & 4 deletions src/plugins/RelightMetalnessIntensity.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class RelightMetalnessIntensity extends React.Component {
style={{
marginTop: '20px',
marginBottom: '20px',
marginLeft: '8px',
marginRight: '8px',
height: '87px',
padding: '0px 15px',
}}
size={size}
orientation={orientation}
Expand Down Expand Up @@ -75,8 +74,8 @@ RelightMetalnessIntensity.propTypes = {
};

RelightMetalnessIntensity.defaultProps = {
intensity: 0.1,
defaultIntensity: 0.1,
intensity: 0.0,
defaultIntensity: 0.0,
step: 0.1,
min: 0.0,
max: 1.0,
Expand Down
3 changes: 1 addition & 2 deletions src/plugins/RelightNormalDepth.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@ class RelightNormalDepth extends React.Component {
style={{
marginTop: '20px',
marginBottom: '20px',
marginLeft: '8px',
marginRight: '8px',
height: '87px',
padding: '0px 15px',
}}
size={size}
orientation={orientation}
Expand Down
Loading

0 comments on commit 217b41e

Please sign in to comment.