Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update for the documentation #254

Merged
merged 5 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions docs/api-reference/2-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,23 @@ sidebar_position: 2

# Events


Canvas panel exposes the following events:

### ready

This is called when the web component is ready and the APIs are available. This does not happen when the content is loaded, you will need to use other events or load the content before.
This is called when the web component is ready and the APIs are available. This
does not happen when the content is loaded, you will need to use other events or
load the content before.

### world-ready

This is called when image content is loaded into the Atlas Viewer. It will not
fire until the zoom level (scale) has been calculated.

### media

This is fired when a Video or Audio canvas is loaded into the viewer. This is not currently a strategy supported by Canvas panel.
This is fired when a Video or Audio canvas is loaded into the viewer. This is
not currently a strategy supported by Canvas panel.

### choice

Expand All @@ -24,17 +31,22 @@ This is fired when a choice is available or the state of a choice changes.
This is fired only in `<canvas-panel />` when a canvas is changed.

### sequence-change
This is fired only in `<sequence-panel />` when a sequence is changed (one or more canvases displayed).

This is fired only in `<sequence-panel />` when a sequence is changed (one or
more canvases displayed).

### sequence

This is fired when a sequence has been loaded and is available - or subsequently changes, if a range is selected for example.
This is fired when a sequence has been loaded and is available - or subsequently
changes, if a range is selected for example.

### zoom-to

This is fired when the users zoom changes - either from calling a zoom method or scroll-zooming. This is not called when the user
calls the `goHome()` method or when a transition is manually created.
This is fired when the users zoom changes - either from calling a zoom method or
scroll-zooming. This is not called when the user calls the `goHome()` method or
when a transition is manually created.

### go-home

This is fired when a user calls the `goHome()` method or uses the keyboard shortcut.
This is fired when a user calls the `goHome()` method or uses the keyboard
shortcut.
149 changes: 106 additions & 43 deletions docs/examples/10-handling-choice.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,90 +4,150 @@ sidebar_position: 10

# Handling Choice

import { GitHubDiscussion } from "../../GitHubDiscussion.js";
import choicesReactSandbox from '@site/sandboxes/choices-react.csb/_load';
import simpleChoice from '@site/sandboxes/10-choices/simpleChoice.csb/_load';
import choice1 from '@site/sandboxes/10-choices/choice1.csb/_load';
import { Sandbox } from '@site/Sandbox';

A Canvas have have multiple images. Sometimes, they are all a part of the scene to be rendered and the developer doesn't have to do anything extra - Canvas Panel will just render the scene.

But sometimes, the multiple images form a set of choices, for the user to pick from. Multispectral images are an example of this.

For further details on this scenario, see the IIIF Cookbook [Choice example](https://preview.iiif.io/cookbook/3333-choice/recipe/0033-choice/). (TODO - replace with published link)

You don't necessarily need to know in advance that the Canvas has resources with Choice for something to render. In simple scenarios, you might not need to know, because there's nothing you can do about it anyway: let canvas panel make a sensible default choice, because anything more means you need to provide _more_ user interface to deal with the user making one or more choices. At the other end, your app might be sophisticated and allow blending of layers, e.g., to view multispectral captures of paintings.

For the more sophisticated UI, you need to react to the presence of one or more Choices on the canvas. You need to know what choices are available - their labels, ids and their "stacking" order.

You can then render UI for offering the choices to the user - and react to that choice by telling Canvas Panel to update the scene to reflect changes. Your UI component might be _bound_ to Canvas Panel.

You might also support blending: "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%".

Usually, if Choice is present at all, it's only one set of choices, for the whole canvas. But it's possible for a scene to be made of multiple content resources each of which have their own set of choices.
import { GitHubDiscussion } from "../../GitHubDiscussion.js"; import
choicesReactSandbox from '@site/sandboxes/choices-react.csb/\_load'; import
simpleChoice from '@site/sandboxes/10-choices/simpleChoice.csb/\_load'; import
choice1 from '@site/sandboxes/10-choices/choice1.csb/\_load'; import { Sandbox }
from '@site/Sandbox';
stephenwf marked this conversation as resolved.
Show resolved Hide resolved

A Canvas have have multiple images. Sometimes, they are all a part of the scene
to be rendered and the developer doesn't have to do anything extra - Canvas
Panel will just render the scene.

But sometimes, the multiple images form a set of choices, for the user to pick
from. Multispectral images are an example of this.

For further details on this scenario, see the IIIF Cookbook
[Choice example](https://preview.iiif.io/cookbook/3333-choice/recipe/0033-choice/).
(TODO - replace with published link)

You don't necessarily need to know in advance that the Canvas has resources with
Choice for something to render. In simple scenarios, you might not need to know,
because there's nothing you can do about it anyway: let canvas panel make a
sensible default choice, because anything more means you need to provide _more_
user interface to deal with the user making one or more choices. At the other
end, your app might be sophisticated and allow blending of layers, e.g., to view
multispectral captures of paintings.

For the more sophisticated UI, you need to react to the presence of one or more
Choices on the canvas. You need to know what choices are available - their
labels, ids and their "stacking" order.

You can then render UI for offering the choices to the user - and react to that
choice by telling Canvas Panel to update the scene to reflect changes. Your UI
component might be _bound_ to Canvas Panel.

You might also support blending: "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%".

Usually, if Choice is present at all, it's only one set of choices, for the
whole canvas. But it's possible for a scene to be made of multiple content
resources each of which have their own set of choices.

## Simple scenario - known choice

<!-- TODO: GH-106 -->

```html
<canvas-panel iiif-content="http://example.org/canvas-1.json" choice-id="http://example.org/choice-1" />
<canvas-panel
iiif-content="http://example.org/canvas-1.json"
choice-id="http://example.org/choice-1"
/>
```

<Sandbox stacked project={choice1} />


Here the value of `choice-id` is the `id` of the content resource within a set of choices. You don't need to specify which set of choices, in the rare event that there is more than one - although you can specify more than one value:
Here the value of `choice-id` is the `id` of the content resource within a set
of choices. You don't need to specify which set of choices, in the rare event
that there is more than one - although you can specify more than one value:

```html
<canvas-panel iiif-content="http://example.org/canvas-1.json"
choice-id="http://example.org/choice-set-a/3, http://example.org/choice-set-b/7" />
<canvas-panel
iiif-content="http://example.org/canvas-1.json"
choice-id="http://example.org/choice-set-a/3, http://example.org/choice-set-b/7"
/>
abrin marked this conversation as resolved.
Show resolved Hide resolved
```

## Before loading

Before you put the `<canvas-panel />` web component on a page, you can first load the manifest into the vault, find out if there is a choice and render a UI.
Before you put the `<canvas-panel />` web component on a page, you can first
load the manifest into the vault, find out if there is a choice and render a UI.

In this example, the "choice" event is fired when Canvas Panel detects that a Choice is present on the rendered Canvas.
In this example, the "choice" event is fired when Canvas Panel detects that a
Choice is present on the rendered Canvas.

:::tip

The choice event may be fired multiple times as Canvas Panel loads
The choice event will be fired once for each choice on a Canvas and when the
choice(s) or the canvas changes. So you will need to keep track of these events.

A choice event will look like the following:

```json
{
"type": "single-choice",
"label": { "en": ["text"] },
"items": [
{
"id": "id",
"label": { "en": ["text"] },
"selected": true
}
],
"partOf": {
"canvasId": "https://...",
"manifestId": "https://...",
"choiceId": "1234"
}
}
```

:::

<Sandbox project={simpleChoice} />

Canvas panel also has the additional helpers for scenarios where you don't want to react to the choice event:
Canvas panel also has the additional helpers for scenarios where you don't want
to react to the choice event:

```js
cp.setDefaultChoiceIds(ids);

const options = {
deselectOthers: true // whether to deselect all other choices
deselect: false // whether to deselect this choice
};

cp.makeChoice(id, options)
```

And you can render a choice directly, with opacity, via attributes (e.g., if generating the markup on the server):
And you can render a choice directly, with opacity, via attributes (e.g., if
generating the markup on the server):

```html
<canvas-panel iiif-content="http://example.org/canvas-1.json" choice-id="http://example.org/choice-1#opacity=0.5" />
<canvas-panel
iiif-content="http://example.org/canvas-1.json"
choice-id="http://example.org/choice-1#opacity=0.5"
/>
```

## Choice React Example

This is a more realistic use of Canvas Panel's choice-handling capability:


<Sandbox project={choicesReactSandbox} />


## Additional choice helper API

There is an additional helper that can be used to extract choices.

```js
import { createPaintingAnnotationsHelper } from '@iiif/vault-helpers';
import { createPaintingAnnotationsHelper } from "@iiif/vault-helpers";

const helper = createPaintingAnnotationsHelper(element.vault);
const choice = helper.extractChoices("http://example.org/manifest/canvas-1.json");
// Choice looks like this:
const choice = helper.extractChoices(
"http://example.org/manifest/canvas-1.json"
);
// Choice looks like this:
// {
// type: 'single-choice';
// label?: InternationalString;
Expand All @@ -99,19 +159,22 @@ const choice = helper.extractChoices("http://example.org/manifest/canvas-1.json"
// }
```

You might want to analyse the canvas even earlier, to decide what UI to render. You need to ensure that the Manifest
is loaded before you extract the choices for your canvas.
You might want to analyse the canvas even earlier, to decide what UI to render.
You need to ensure that the Manifest is loaded before you extract the choices
for your canvas.

Using this helper gives complete flexibility over choices at the data level, and can happen before anything is rendered to the user.
Using this helper gives complete flexibility over choices at the data level, and
can happen before anything is rendered to the user.

Since the `choice-id` attribute also drives the users choice, I could do the following to manually set the choice ID.
Since the `choice-id` attribute also drives the users choice, I could do the
following to manually set the choice ID.

```js
element.setAttribute('choice-id', 'http://example.org/choice-1')
element.setAttribute("choice-id", "http://example.org/choice-1");

// or even

element.setAttribute('choice-id', 'http://example.org/choice-1#opacity=20')
element.setAttribute("choice-id", "http://example.org/choice-1#opacity=20");
```

<GitHubDiscussion ghid="10" />
Loading