Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Mirador Video
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
IIIF
Mirador
Mirador Video
Commits
4ff3865d
Commit
4ff3865d
authored
6 years ago
by
Christopher Johnson
Browse files
Options
Downloads
Patches
Plain Diff
changes OpenSeadragonViewer to a functional component [ci skip]
closes #1930
parent
06613178
No related branches found
No related tags found
No related merge requests found
Pipeline
#1130
skipped
Changes
2
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/components/OpenSeadragonViewer.js
+138
-156
138 additions, 156 deletions
src/components/OpenSeadragonViewer.js
src/containers/OpenSeadragonViewer.js
+0
-1
0 additions, 1 deletion
src/containers/OpenSeadragonViewer.js
with
138 additions
and
157 deletions
src/components/OpenSeadragonViewer.js
+
138
−
156
View file @
4ff3865d
import
React
,
{
Component
}
from
'
react
'
;
import
React
,
{
useEffect
,
useRef
}
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
OpenSeadragon
from
'
openseadragon
'
;
import
debounce
from
'
lodash/debounce
'
;
...
...
@@ -6,110 +6,124 @@ import ns from '../config/css-ns';
import
ZoomControls
from
'
../containers/ZoomControls
'
;
/**
* Represents a OpenSeadragonViewer in the mirador workspace. Responsible for mounting
* and rendering OSD.
*/
class
OpenSeadragonViewer
extends
Component
{
/**
* @param {Object} props
* usePrevious Hook
* @param value
* @returns {any}
*/
constructor
(
props
)
{
super
(
props
);
this
.
viewer
=
null
;
this
.
ref
=
React
.
createRef
(
);
this
.
onViewportChange
=
this
.
onViewportChange
.
bind
(
this
)
;
function
usePrevious
(
value
)
{
const
ref
=
useRef
(
);
useEffect
(()
=>
{
ref
.
current
=
value
;
}
);
return
ref
.
current
;
}
/**
* React lifecycle event
* Represents an OpenSeadragonViewer in the mirador workspace. Responsible for mounting
* and rendering OSD.
*/
componentDidMount
()
{
const
{
tileSources
,
viewer
}
=
this
.
props
;
if
(
!
this
.
ref
.
current
)
{
return
;
}
this
.
viewer
=
new
OpenSeadragon
({
id
:
this
.
ref
.
current
.
id
,
const
OpenSeadragonViewer
=
(
props
)
=>
{
const
{
tileSources
,
viewer
,
windowId
,
children
,
updateViewport
,
}
=
props
;
const
osdRef
=
useRef
();
const
viewerInstance
=
useRef
();
const
wholeBounds
=
useRef
();
const
prevTileSources
=
usePrevious
(
tileSources
);
useEffect
(()
=>
{
if
(
!
viewerInstance
.
current
)
{
viewerInstance
.
current
=
new
OpenSeadragon
({
id
:
osdRef
.
current
.
id
,
preserveViewport
:
true
,
blendTime
:
0.1
,
alwaysBlend
:
false
,
showNavigationControl
:
false
,
preserveImageSizeOnResize
:
true
,
});
this
.
viewer
.
addHandler
(
'
viewport-change
'
,
debounce
(
this
.
onViewportChange
,
300
));
}
if
(
viewerInstance
.
current
)
{
// set update viewer state handler
viewerInstance
.
current
.
addHandler
(
'
viewport-change
'
,
debounce
(
onViewportChange
,
300
));
if
(
viewer
)
{
this
.
viewer
.
viewport
.
panTo
(
viewer
,
false
);
this
.
viewer
.
viewport
.
zoomTo
(
viewer
.
zoom
,
viewer
,
false
);
const
{
viewport
}
=
viewerInstance
.
current
;
// set initial zoom
viewport
.
panTo
(
viewer
,
false
);
viewport
.
zoomTo
(
viewer
.
zoom
,
viewer
,
false
);
if
(
viewer
.
x
!==
viewport
.
centerSpringX
.
target
.
value
||
viewer
.
y
!==
viewport
.
centerSpringY
.
target
.
value
)
{
viewport
.
panTo
(
viewer
,
false
);
}
tileSources
.
forEach
((
tileSource
,
i
)
=>
this
.
addTileSource
(
tileSource
,
i
));
if
(
viewer
.
zoom
!==
viewport
.
zoomSpring
.
target
.
value
)
{
viewport
.
zoomTo
(
viewer
.
zoom
,
viewer
,
false
);
}
}
// build bounds for all tile sources
wholeBounds
.
current
=
boundsFromTileSources
();
// add tile sources to viewerInstance
tileSources
.
forEach
((
tileSource
,
i
)
=>
addTileSource
(
tileSource
,
i
));
}
/**
* When the tileSources change, make sure to close the OSD viewer.
* When the viewport state changes, pan or zoom the OSD viewer as appropriate
*/
componentDidUpdate
(
prevProps
)
{
const
{
tileSources
,
viewer
}
=
this
.
props
;
if
(
!
this
.
tileSourcesMatch
(
prevProps
.
tileSources
))
{
this
.
viewer
.
close
();
// check for new tile sources
if
(
!
tileSourcesMatch
())
{
viewerInstance
.
current
.
close
();
Promise
.
all
(
tileSources
.
map
((
tileSource
,
i
)
=>
this
.
addTileSource
(
tileSource
,
i
)),
tileSources
.
map
((
tileSource
,
i
)
=>
addTileSource
(
tileSource
,
i
)),
).
then
(()
=>
{
if
(
tileSources
[
0
])
{
this
.
fitBounds
(...
this
.
boundsFromTileSources
(),
true
);
fitBounds
(...
boundsFromTileSources
(),
true
);
}
});
}
else
if
(
viewer
)
{
const
{
viewport
}
=
this
.
viewer
;
if
(
viewer
.
x
!==
viewport
.
centerSpringX
.
target
.
value
||
viewer
.
y
!==
viewport
.
centerSpringY
.
target
.
value
)
{
this
.
viewer
.
viewport
.
panTo
(
viewer
,
false
);
}
if
(
viewer
.
zoom
!==
viewport
.
zoomSpring
.
target
.
value
)
{
this
.
viewer
.
viewport
.
zoomTo
(
viewer
.
zoom
,
viewer
,
false
);
}
}
}
// clean up
return
()
=>
{
viewerInstance
.
current
.
removeAllHandlers
();
};
});
/**
*
* @param tileSource
* @param i
* @returns {Promise<any>}
*/
componentWillUnmount
()
{
this
.
viewer
.
removeAllHandlers
();
}
const
addTileSource
=
(
tileSource
,
i
=
0
)
=>
new
Promise
((
resolve
,
reject
)
=>
{
const
bounds
=
boundingRectFromTileSource
(
tileSource
,
i
);
const
rect
=
new
OpenSeadragon
.
Rect
(...
bounds
);
viewerInstance
.
current
.
addTiledImage
({
tileSource
,
fitBounds
:
rect
,
success
:
event
=>
resolve
(
event
),
error
:
event
=>
reject
(
event
),
});
});
/**
* Forward OSD state to redux
*/
onViewportChange
(
event
)
{
const
{
updateViewport
,
windowId
}
=
this
.
props
;
const
{
viewport
}
=
event
.
eventSource
;
const
onViewportChange
=
(
e
)
=>
{
const
{
viewport
}
=
e
.
eventSource
;
updateViewport
(
windowId
,
{
x
:
viewport
.
centerSpringX
.
target
.
value
,
y
:
viewport
.
centerSpringY
.
target
.
value
,
zoom
:
viewport
.
zoomSpring
.
target
.
value
,
});
}
}
;
/**
* boundsFromTileSources - calculates the overall width/height
* based on 0 -> n tileSources
*/
boundsFromTileSources
()
{
const
{
tileSources
}
=
this
.
props
;
const
boundsFromTileSources
=
()
=>
{
const
heights
=
[];
const
dimensions
=
[];
if
(
tileSources
.
length
)
{
tileSources
.
forEach
((
tileSource
)
=>
{
heights
.
push
(
tileSource
.
height
);
dimensions
.
push
({
width
:
tileSource
.
width
,
height
:
tileSource
.
height
,
width
:
tileSource
.
width
,
height
:
tileSource
.
height
,
});
});
const
minHeight
=
Math
.
min
(...
heights
);
...
...
@@ -118,103 +132,71 @@ class OpenSeadragonViewer extends Component {
const
aspectRatio
=
dim
.
width
/
dim
.
height
;
scaledWidth
+=
Math
.
floor
(
minHeight
*
aspectRatio
);
});
return
[
0
,
0
,
scaledWidth
,
minHeight
,
];
return
[
0
,
0
,
scaledWidth
,
minHeight
];
}
return
null
;
};
/**
* boundingRectFromTileSource - Creates a bounding rectangle
* in the Viewports space, using the current tileSource and the tileSource
* total area. Limitation, can only handle tileSources with a length of 1 or 2
*/
boundingRectFromTileSource
(
tileSource
,
i
)
{
const
{
tileSources
}
=
this
.
props
;
const
wholeBounds
=
this
.
boundsFromTileSources
();
const
{
width
}
=
tileSources
[
i
];
const
{
height
}
=
tileSources
[
i
];
const
aspectRatio
=
width
/
height
;
const
scaledWidth
=
Math
.
floor
(
wholeBounds
[
3
]
*
aspectRatio
);
const
boundingRectFromTileSource
=
(
tileSource
,
i
)
=>
{
if
(
wholeBounds
.
current
)
{
const
aspectRatio
=
tileSource
.
width
/
tileSource
.
height
;
const
scaledWidth
=
Math
.
floor
(
wholeBounds
.
current
[
3
]
*
aspectRatio
);
let
x
=
0
;
if
(
i
===
1
)
{
x
=
wholeBounds
[
2
]
-
scaledWidth
;
x
=
wholeBounds
.
current
[
2
]
-
scaledWidth
;
}
return
[
x
,
0
,
scaledWidth
,
wholeBounds
[
3
],
];
}
/**
*/
addTileSource
(
tileSource
,
i
=
0
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
!
this
.
viewer
)
{
return
;
}
this
.
viewer
.
addTiledImage
({
tileSource
,
fitBounds
:
new
OpenSeadragon
.
Rect
(
...
this
.
boundingRectFromTileSource
(
tileSource
,
i
),
),
success
:
event
=>
resolve
(
event
),
error
:
event
=>
reject
(
event
),
});
});
return
[
x
,
0
,
scaledWidth
,
wholeBounds
.
current
[
3
]];
}
return
null
;
};
/**
*
* @param x
* @param y
* @param w
* @param h
*/
fitBounds
(
x
,
y
,
w
,
h
)
{
this
.
viewer
.
viewport
.
fitBounds
(
const
fitBounds
=
(
x
,
y
,
w
,
h
)
=>
{
viewer
Instance
.
current
.
viewport
.
fitBounds
(
new
OpenSeadragon
.
Rect
(
x
,
y
,
w
,
h
),
true
,
);
}
}
;
/**
* tileSourcesMatch - compares previous tileSources to current to determine
* whether a refresh of the OSD viewer is needed.
* @param {Array} prevTileSources
* @return {Boolean}
*/
tileSourcesMatch
(
prevTileSources
)
{
const
{
tileSources
}
=
this
.
props
;
return
tileSources
.
some
((
tileSource
,
index
)
=>
{
const
tileSourcesMatch
=
()
=>
tileSources
.
some
((
tileSource
,
index
)
=>
{
if
(
prevTileSources
)
{
if
(
!
prevTileSources
[
index
])
{
return
false
;
}
if
(
tileSource
[
'
@id
'
]
===
prevTileSources
[
index
][
'
@id
'
])
{
return
true
;
return
tileSource
[
'
@id
'
]
===
prevTileSources
[
index
][
'
@id
'
];
}
return
false
;
return
null
;
});
}
/**
* Renders things
*/
render
()
{
const
{
windowId
,
children
}
=
this
.
props
;
return
(
<>
<
div
className
=
{
ns
(
'
osd-container
'
)}
id
=
{
`
${
windowId
}
-osd`
}
ref
=
{
this
.
r
ef
}
ref
=
{
osdR
ef
}
>
{
children
}
<
/div
>
<
ZoomControls
windowId
=
{
windowId
}
/
>
<
/
>
);
}
}
};
OpenSeadragonViewer
.
defaultProps
=
{
children
:
null
,
...
...
This diff is collapsed.
Click to expand it.
src/containers/OpenSeadragonViewer.js
+
0
−
1
View file @
4ff3865d
...
...
@@ -24,7 +24,6 @@ const mapDispatchToProps = {
const
enhance
=
compose
(
connect
(
mapStateToProps
,
mapDispatchToProps
),
miradorWithPlugins
,
// further HOC go here
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment