Handle canvases that have one or more resources with Choice #10
Replies: 4 comments 5 replies
-
This will likely be the tough part. I've thought about it before. If we did raise an event, or had some callback somewhere, you could image a develop experience like this: function handleChoiceDetected(data) {
data.choices // the choices in the IIIF form.
data.renderChoice(data.choices[0]); // render a single choice (hiding any others)
data.renderChoice([data.choices[0], data.choices[1]]); // Or render multiple
data.setOptions(data.choices[0], { opacity: 20 }); // Something to pass directly to the rendering
data.setOptions(data.choices[1], { opacity: 80 });
return function() {
// An unsubscribe callback for when the UI can be removed.
};
} So you could bind this to an external UI, but everything you need is here and not part of some library you need to pull in. |
Beta Was this translation helpful? Give feedback.
-
Demo of Hyperion handling choice: #25 To be explored in pseudocode - my code waits for CP general purpose How does it access the choices on the canvas? cp.choices -> one or more sets of my code renders a choosing UI - or, actually, one per set of choices (uncommon but possible) Is I should also be able to interrogate their current visibility. E.g., I didn't record the fact that I set a particular "layer" to 50% opacity 5 minutes ago, but I can see what everything is set to now. (luckily, anno painting order is same as CSS stacking order...) |
Beta Was this translation helpful? Give feedback.
-
From the point of view of a developer using these web components, a choice could happen either before loading or after. Web componentIf I know which choice should be chosen, I can use the web component to make that choice. <canvas-panel canvas-id="http://example.org/canvas-1.json" choice-id="http://example.org/choice-1" /> Before loadingBefore I put the vault.loadManifest('http://example.org/manifest.json').then(manifestRef => {
// At this point I know the canvas is loaded - could also
const canvas = vault.fromRef({ id: 'http://example.org/manifest/canvas-1.json', type: 'Canvas' });
// These are "invented" helpers.
if (vault.containsChoice(canvas)) {
const choiceSets = vault.extractChoiceSets(canvas); // Array<{ annotation: {}, choices: Choice[] }>
// Render UI for choices.
// When I'm ready, I can insert a web component onto the page:
// <canvas-panel canvas-id=" ... " choice-id=" ... " />
} else {
// Render normal component
// <canvas-panel canvas-id=" ... " ... />
}
}); This gives complete flexibility over choices at the data level, and can happen before anything is rendered to the user. After loadingIn most cases, you won't want to handle a choice until you come across one. So the canvas panel component itself could dispatch events for you to respond to. <canvas-panel id="viewer" canvas-id="http://example.org/canvas-1.json" [ ... ] />
<script>
const viewer = document.getElementById('viewer');
viewer.addEventListener('canvas-choice', (helper) => {
helper.choices // the choices in the IIIF form.
helper.renderChoice(helper.choices[0]); // render a single choice (hiding any others)
helper.renderChoice([helper.choices[0], data.choices[1]]); // Or render multiple
helper.setOptions(helper.choices[0], { opacity: 20 }); // Something to pass directly to the rendering
helper.setOptions(helper.choices[1], { opacity: 80 });
return function() {
// An unsubscribe callback for when the UI can be removed.
};
})
</script> When that event fires, as a developer I can render my own UI from that data and bind Since the element.setAttribute('choice-id', 'http://example.org/choice-1') |
Beta Was this translation helpful? Give feedback.
-
A thought on
The developer showing UI is going to need to react to an event to decide what UI controls to show, but what's that event? In the example above there's a specific CP event "I've found a choice or choices in the canvas" and the developer reacts to it by building the choice UI. An alternative approach would be a CP event "I've loaded everything I'm going to know about this canvas, for now" - kind of like Do we support both? |
Beta Was this translation helpful? Give feedback.
-
Extension of #9
As explained in #9, I don't necessarily need to know in advance that the Canvas has resources with
Choice
for something to render. In simple scenarios, I might not want to know, because there's nothing I can do about it anyway. Let the component make a sensible default choice, because anything more means I need to provide more user interface to deal with the user making one of more choices... which can extend into blending of layers, etc.The thing to flesh out here is how do I react to the presence of one or more
Choice
?First I need to know what choices are available (when? how? listen for content-loaded event on the component and then inspect it? Receive a specific choice-detected event?)
Then I need to know what the choices are (the component should probably just give me the IIIF model back here) - I need their labels, ids and in the supplied order from the original IIIF Canvas.
It's up to me to render some UI for presenting those choices to the user (but as with other examples in these discussions, we could provide a sample reference implementation that can be reused).
As the user makes their Choice, the API of the component is called and it updates the rendered scene.
"Show the choice with
id
xxx" - simple approachand/or
The canvas rendering component is bound to my choice UI and is reacting to my actions in it
I can also blend:
"Show the choice with id xxx at 80% opacity AND show the choice with id yyy at 50% opacity, all the others are at 0%"
Beta Was this translation helpful? Give feedback.
All reactions