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

Sequences helper #6

Open
stephenwf opened this issue Jul 22, 2022 · 0 comments
Open

Sequences helper #6

stephenwf opened this issue Jul 22, 2022 · 0 comments

Comments

@stephenwf
Copy link
Member

There are quite a few ways viewers can sequences up canvases, and optionally regions / time-slices to present to the user.

You could make a sequences of canvases from:

  • manifest.items
  • Flat start-to-finish

The slices of IIIF that can affect any given sequence:

  • The order of the manifest.items
  • Specified behaviours (individuals, paged, facing-pages, sequence, hidden)
  • Ranges with specific resource + selectors
  • Annotations with selectors inside an Annotation page

This helper should be useful both for providing enough information to display the current item in a sequence, helpers for next/previous in a sequence and also easy to build a tree or list navigation from one.

Here's what a single parsed sequence might look like:

const sequence: ParsedSequence = {
  id: 'https://example.org/sequence',
  type: 'manifest-items',
  label: {en: ['something']},
  start: 0,
  grouping: [
    [ 0 ], [ 1, 2 ], [ 3 ]
  ],
  navigation: {
    id: '..', // maybe reuse the range ID?
    label: { en: ['Table of contents'] },
    items: [
      { id: '..', label: { en: ['Cover'] }, start: 0, indexes: [0] },
      { id: '..', label: { en: ['Chapter 1'] }, start: 1, indexes: [1, 2] },
      { id: '..', label: { en: ['Back cover'] }, start: 3, indexes: [3] },
    ]
  },
  items: [
    // Should all be resolvable with `vault.get()`
    { id: 'https://example.org/cover', type: 'Canvas', label: { en: ['Cover']} },
    { id: 'https://example.org/page-1', type: 'Canvas', label: { en: ['Page 1']} },
    { id: 'https://example.org/page-2', type: 'Canvas', label: { en: ['Page 2']} },
    { id: 'https://example.org/back', type: 'Canvas', label: { en: ['Back']} },
  ],
}

With helpers like:

nextInSequence(sequence: ParsedSequence, currentIndex: number): index | undefined;
previousInSequence(sequence: ParsedSequence, currentIndex: number): index | undefined;
activeNavigation(sequence: ParsedSequence, currentIndex: number): string[]; // For active states
getGrouping(sequence: ParsedSequence, currentIndex: number): number[];

Cookbook

There are some examples of book paging strategies:
https://iiif.io/api/cookbook/recipe/0011-book-3-behavior/

Accordion book - in this example, there are 4 images that are continuous. In other words there is only ever one grouping:

{ grouping: [ [0, 1, 2, 3] ], ... }

Individuals - the groupings in this example would be flat (or not present)

{ grouping: [ [0], [1], [2], [3], ],  ... }

Table of contents: https://iiif.io/api/cookbook/recipe/0024-book-4-toc/
This will be very relevant, and the most likely use-case to be found in the wild.

Nav date is explained here (possibly out of scope, see below)
https://iiif.io/api/cookbook/recipe/0230-navdate/

Time-based range navigation here: https://iiif.io/api/cookbook/recipe/0026-toc-opera/
Although this should be supported, returning SpecificResource instead of canvas references (PR upcoming in IIIF Parser) - it would not be able to tell you which media should be playing. So there is still a gap for a vault helper that can take "Canvas" + "Time range" and return enough data to construct an <audio /> tag with correct start/end. To highlight the complexity - you could "paint" an MP4 onto a canvas using:

{
  "id": "https://iiif.io/api/cookbook/recipe/0026-toc-opera/canvas/1/annotation_page/1/annotation/1",
  "type": "Annotation",
  "motivation": "painting",
  "target": "https://iiif.io/api/cookbook/recipe/0026-toc-opera/canvas/1#t=0,30",
  "body": {
    "id": "https://fixtures.iiif.io/video/indiana/donizetti-elixir/vae0637_accessH264_low.mp4",
    "type": "Video",
    "format": "video/mp4",
    "height": 1080,
    "width": 1920,
    "duration": 30,
    "selector": {
      "type": "FragmentSelector",
      "conformsTo": "http://www.w3.org/TR/media-frags/",
      "value": "t=30,60"
    }
  }
}

With this annotation, you are saying that you want to play from 30s-60s from the audio source, and paint it onto the canvas at 0s-30s. So when you have a range that says: canvas/1#t=10 that needs to be resolved into 10s for the UI, but 40s for the <audio/>

Annotations: https://iiif.io/api/cookbook/recipe/0269-embedded-or-referenced-annotations/
In this example, either embedded or referenced annotations, inside of an annotation page, could be constructed into a sequence. For example it could be used to drive navigation through search results or drive exhibition-style experiences.

Missing pieces

Assumptions

  • This may be used in a reactive / editing context so resolving all resources inside this helper structure would require it to be rebuilt if changed.
  • The label property on items may be stale, so if working in an editor environment - just treat it like a ref and subscribe to the vault
@stephenwf stephenwf transferred this issue from IIIF-Commons/vault-helpers Jan 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant