diff --git a/source/_includes/code_example.html b/source/_includes/code_example.html new file mode 100644 index 000000000..030ed33d7 --- /dev/null +++ b/source/_includes/code_example.html @@ -0,0 +1,10 @@ +{% assign _title = include.title | default: 'Full JSON example' %} +{% assign _target = include.target | default: "_blank" %} + +
+
+ {{ _title }}
+ {% highlight json %} + {% include_lines presentation/4.0/example/{{ include.src }} from:{{ include.from }} to:{{ include.to }} %} + {% endhighlight %} +
diff --git a/source/_includes/links.md b/source/_includes/links.md index 6c0e773e8..e3d2db20b 100644 --- a/source/_includes/links.md +++ b/source/_includes/links.md @@ -306,3 +306,92 @@ [recipe-segment-image-part]: {{ site.api_url | absolute_url }}/cookbook/segment-image-part/ "Annotating part of an image to a canvas" [slack]: http://bit.ly/iiif-slack [web-arch]: http://www.w3.org/TR/webarch/ "Architecture of the World Wide Web" + + + + + +[prezi-40-model-Agent]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Agent +[prezi-40-model-AmbientAudio]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AmbientAudio +[prezi-40-model-AnimationSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AnimationSelector +[prezi-40-model-Annotation]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Annotation +[prezi-40-model-AnnotationCollection]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AnnotationCollection +[prezi-40-model-AnnotationPage]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#AnnotationPage +[prezi-40-model-Canvas]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Canvas +[prezi-40-model-Choice]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Choice +[prezi-40-model-Collection]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Collection +[prezi-40-model-FragmentSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#FragmentSelector +[prezi-40-model-Manifest]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Manifest +[prezi-40-model-OrthographicCamera]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#OrthographicCamera +[prezi-40-model-PerspectiveCamera]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#PerspectiveCamera +[prezi-40-model-PointAudio]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#PointAudio +[prezi-40-model-PointSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#PointSelector +[prezi-40-model-Range]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Range +[prezi-40-model-RotateTransform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#RotateTransform +[prezi-40-model-ScaleTransform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#ScaleTransform +[prezi-40-model-Scene]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Scene +[prezi-40-model-Service]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Service +[prezi-40-model-SpecificResource]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SpecificResource +[prezi-40-model-SpotAudio]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SpotAudio +[prezi-40-model-SpotLight]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SpotLight +[prezi-40-model-SvgSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#SvgSelector +[prezi-40-model-TextualBody]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#TextualBody +[prezi-40-model-Timeline]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#Timeline +[prezi-40-model-TranslateTransform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#TranslateTransform +[prezi-40-model-WktSelector]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#WktSelector +[prezi-40-model-accompanyingContainer]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#accompanyingContainer +[prezi-40-model-action]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#action +[prezi-40-model-angle]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#angle +[prezi-40-model-annotations]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#annotations +[prezi-40-model-backgroundColor]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#backgroundColor +[prezi-40-model-behavior]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#behavior +[prezi-40-model-body]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#body +[prezi-40-model-color]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#color +[prezi-40-model-duration]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#duration +[prezi-40-model-exclude]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#exclude +[prezi-40-model-far]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#far +[prezi-40-model-fieldOfView]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#fieldOfView +[prezi-40-model-format]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#format +[prezi-40-model-height]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#height +[prezi-40-model-homepage]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#homepage +[prezi-40-model-id]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#id +[prezi-40-model-instant]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#instant +[prezi-40-model-intensity]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#intensity +[prezi-40-model-interactionMode]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#interactionMode +[prezi-40-model-items]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#items +[prezi-40-model-label]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#label +[prezi-40-model-language]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#language +[prezi-40-model-lookAt]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#lookAt +[prezi-40-model-metadata]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#metadata +[prezi-40-model-motivation]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#motivation +[prezi-40-model-navDate]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#navDate +[prezi-40-model-navPlace]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#navPlace +[prezi-40-model-near]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#near +[prezi-40-model-placeholderContainer]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#placeholderContainer +[prezi-40-model-position]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#position +[prezi-40-model-profile]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#profile +[prezi-40-model-provider]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#provider +[prezi-40-model-provides]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#provides +[prezi-40-model-refinedBy]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#refinedBy +[prezi-40-model-rendering]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#rendering +[prezi-40-model-requiredStatement]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#requiredStatement +[prezi-40-model-rights]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#rights +[prezi-40-model-service]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#service +[prezi-40-model-source]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#source +[prezi-40-model-spatialScale]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#spatialScale +[prezi-40-model-start]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#start +[prezi-40-model-structures]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#structures +[prezi-40-model-summary]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#summary +[prezi-40-model-supplementary]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#supplementary +[prezi-40-model-target]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#target +[prezi-40-model-temporalScale]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#temporalScale +[prezi-40-model-thumbnail]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#thumbnail +[prezi-40-model-timeMode]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#timeMode +[prezi-40-model-transform]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#transform +[prezi-40-model-type]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#type +[prezi-40-model-viewingDirection]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#viewingDirection +[prezi-40-model-volume]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#volume +[prezi-40-model-width]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#width +[prezi-40-model-x]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#x +[prezi-40-model-y]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#y +[prezi-40-model-z]: {{ site.api_url | absolute_url }}/presentation/4.0/model/#z diff --git a/source/_plugins/include_lines.rb b/source/_plugins/include_lines.rb new file mode 100644 index 000000000..be8a2616f --- /dev/null +++ b/source/_plugins/include_lines.rb @@ -0,0 +1,140 @@ +require 'liquid' + +module Jekyll + class IncludeLinesTag < Liquid::Tag + def initialize(tag_name, markup, tokens) + super + @markup = markup.to_s.strip + end + + def render(context) + site = context.registers[:site] + source = site.source + + rendered_markup = Liquid::Template.parse(@markup).render(context) + path, options = parse_markup(rendered_markup) + raise ArgumentError, "include_lines: missing file path" if path.nil? || path.empty? + + from = integer_option(options, 'from') + to = integer_option(options, 'to') + start = integer_option(options, 'start') + finish = integer_option(options, 'end') + + from ||= start + to ||= finish + + format = true + if options.key?('format') + format = boolean_option(options, 'format') + end + indent = integer_option(options, 'indent') + + unless from && to + raise ArgumentError, "include_lines: must specify from/to (1-indexed), e.g. {% include_lines path from:11 to:35 %}" + end + + if from < 1 || to < 1 + raise ArgumentError, "include_lines: from/to must be >= 1 (got from:#{from} to:#{to})" + end + + if to < from + raise ArgumentError, "include_lines: to must be >= from (got from:#{from} to:#{to})" + end + + absolute_path = File.expand_path(path, source) + unless absolute_path.start_with?(File.expand_path(source) + File::SEPARATOR) + raise ArgumentError, "include_lines: path must be within the site source directory" + end + + unless File.file?(absolute_path) + raise ArgumentError, "include_lines: file not found: #{path}" + end + + lines = File.read(absolute_path, encoding: 'UTF-8').split("\n", -1) + max_line = lines.length + + if from > max_line + raise ArgumentError, "include_lines: from (#{from}) is beyond end of file (#{max_line} lines): #{path}" + end + + to = [to, max_line].min + + selected = lines[(from - 1)..(to - 1)] + + if format + selected = dedent_lines(selected) + end + + if indent && indent > 0 + prefix = ' ' * indent + selected = selected.map { |l| l.strip.empty? ? l : (prefix + l) } + end + + selected.join("\n") + rescue StandardError => e + if defined?(Jekyll) && Jekyll.respond_to?(:logger) && Jekyll.logger + Jekyll.logger.error("include_lines:", e.message) + end + raise + end + + private + + def parse_markup(markup) + tokens = markup.scan(/\"[^\"]+\"|\'[^\']+\'|\S+/) + return [nil, {}] if tokens.empty? + + path_token = tokens.shift + path = unquote(path_token) + + options = {} + tokens.each do |t| + key, value = t.split(':', 2) + next if value.nil? + options[key] = unquote(value) + end + + [path, options] + end + + def unquote(value) + v = value.to_s + if (v.start_with?('"') && v.end_with?('"')) || (v.start_with?("'") && v.end_with?("'")) + v[1..-2] + else + v + end + end + + def integer_option(options, key) + return nil unless options.key?(key) + Integer(options[key]) + rescue ArgumentError + raise ArgumentError, "include_lines: #{key} must be an integer (got #{options[key].inspect})" + end + + def boolean_option(options, key) + return nil unless options.key?(key) + + v = options[key].to_s.strip.downcase + return true if %w[1 true yes y on].include?(v) + return false if %w[0 false no n off].include?(v) + + raise ArgumentError, "include_lines: #{key} must be a boolean (got #{options[key].inspect})" + end + + def dedent_lines(lines) + non_empty = lines.reject { |l| l.strip.empty? } + return lines if non_empty.empty? + + min_indent = non_empty.map { |l| l[/\A[ \t]*/].length }.min + return lines if min_indent.nil? || min_indent.zero? + + lines.map do |l| + l.strip.empty? ? l : l[min_indent..] + end + end + end +end + +Liquid::Template.register_tag('include_lines', Jekyll::IncludeLinesTag) diff --git a/source/presentation/4.0/example/02_timeline.json b/source/presentation/4.0/example/02_timeline.json new file mode 100644 index 000000000..a5490fbc9 --- /dev/null +++ b/source/presentation/4.0/example/02_timeline.json @@ -0,0 +1,37 @@ +{ + "@context": "http://iiif.io/api/presentation/4/context.json", + "id": "https://iiif.io/api/presentation/4.0/example/02_timeline.json", + "type": "Manifest", + "label": { + "en": [ + "Simplest Audio Example (IIIF Presentation v4)" + ] + }, + "items": [ + { + "id": "https://iiif.io/api/presentation/4.0/example/02", + "type": "Timeline", + "duration": 1985.024, + "items": [ + { + "id": "https://iiif.io/api/presentation/4.0/example/02/page", + "type": "AnnotationPage", + "items": [ + { + "id": "https://iiif.io/api/presentation/4.0/example/02/page/anno", + "type": "Annotation", + "motivation": "painting", + "body": { + "id": "https://fixtures.iiif.io/audio/indiana/mahler-symphony-3/CD1/medium/128Kbps.mp4", + "type": "Sound", + "format": "audio/mp4", + "duration": 1985.024 + }, + "target": "https://iiif.io/api/presentation/4.0/example/02" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/source/presentation/4.0/index.md b/source/presentation/4.0/index.md index 5db58a797..4c55a90aa 100644 --- a/source/presentation/4.0/index.md +++ b/source/presentation/4.0/index.md @@ -52,6 +52,63 @@ pre.highlight code { .highlight .s2 { color: #a0f0f0 } + +a > code::after { + content: "↗"; + font-size: 0.65em; + opacity: 0.6; + margin-left: 0.2em; + vertical-align: super; + text-decoration: none; +} + +a > code { + /* text-decoration: underline;*/ + color: var(--link-color); + cursor: pointer; +} + +a:hover > code { + background-color: rgba(0,0,0,0.05); + text-decoration: underline; +} + + .code-example { + margin: 0 0 1em 0; + } + .code-example__header { + background-color: #edf0f0; + border-top-left-radius: 1em; + border-top-right-radius: 1em; + padding: 0.6em 1.5em; + font-weight: bold; + } + .code-example__header a { + color: #171717; + text-decoration: underline; + } + .code-example__header + .highlight pre { + border-top-left-radius: 0; + border-top-right-radius: 0; + } + figure.highlight pre { + border-bottom-left-radius: 1em; + border-bottom-right-radius: 1em; + } +.code-example > figure.highlight { + margin-left: 0px; + margin-right: 0px; + margin-top: 0px; + margin-bottom: 0px; + text-align: left; + + } + + code.language-json { + font-size: 0.9rem; + line-height: 1.0; + font-family: "Courier Prime", monospace; + } # Status of this Document @@ -112,9 +169,9 @@ This section is what you need to know to make sense of the examples that follow A Manifest is the primary unit of distribution of IIIF. Each Manifest usually describes how to present an object, such as a book, statue, music album or 3 dimensional scene. It is a JSON document that carries information needed for the client to present content to the user, such as a title and other descriptive information. The scope of what constitutes an object, and thus its Manifest, is up to the publisher of that Manifest. The Manifest contains sufficient information for the client to initialize itself and begin to display something quickly to the user. -The Manifest's `items` property is an ordered list of _Containers_ of _Content Resources_ (images, 3D models, audio, etc). Client software loads the Manifest and presents each Container's Content Resources. The client software also presents user interface controls to navigate the list of Content Containers. +The Manifest's [`items`][prezi-40-model-items] property is an ordered list of _Containers_ of _Content Resources_ (images, 3D models, audio, etc). Client software loads the Manifest and presents each Container's Content Resources. The client software also presents user interface controls to navigate the list of Content Containers. -Manifests have descriptive, technical and linking properties. The required properties of Manifests are `id`, `type`, `items` and `label`. Other commonly used properties include `summary`, `metadata`, `rights`, `thumbnail`, `homepage` and `provider`. +Manifests have descriptive, technical and linking properties. The required properties of Manifests are [`id`][prezi-40-model-id], [`type`][prezi-40-model-type], [`items`][prezi-40-model-items] and [`label`][prezi-40-model-label]. Other commonly used properties include [`summary`][prezi-40-model-summary], [`metadata`][prezi-40-model-metadata], [`rights`][prezi-40-model-rights], [`thumbnail`][prezi-40-model-thumbnail], [`homepage`][prezi-40-model-homepage] and [`provider`][prezi-40-model-provider]. (👀) [Model Documentation](model/#manifest) @@ -139,7 +196,7 @@ Manifests have descriptive, technical and linking properties. The required prope A Container is a frame of reference that allows the relative positioning of Content Resources, a concept borrowed from standards like PDF and HTML, or applications like Photoshop and PowerPoint, where an initially blank display surface has images, video, text and other content "painted" on to it. The frame is defined by a set of dimensions, with different types of Container having different dimensions. This specification defines three sub-classes of Container: Timeline (which only has a duration), Canvas (which has bounded height and width, and may have a duration), and Scene (which has infinite height, width and depth, and may have a duration). -The required properties of all Containers are `id`, and `type`. Most Containers also have the `items` and `label` properties. Further properties are required for the different types of Container. +The required properties of all Containers are [`id`][prezi-40-model-id], and [`type`][prezi-40-model-type]. Most Containers also have the [`items`][prezi-40-model-items] and [`label`][prezi-40-model-label] properties. Further properties are required for the different types of Container. The defined Container types are: @@ -147,41 +204,15 @@ The defined Container types are: A Container that represents a bounded temporal range, without any spatial coordinates. It is typically used for audio-only content. -Timelines have an additional required property of `duration`, which gives the extent of the Timeline as a floating point number of seconds. +Timelines have an additional required property of [`duration`][prezi-40-model-duration], which gives the extent of the Timeline as a floating point number of seconds. -```json -{ - "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/timeline", - "type": "Timeline", - "duration": 32.76, - "items": [ - { - "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/page/p1", - "type": "AnnotationPage", - "items": [ - { - "id": "https://example.org/iiif/presentation/examples/manifest-with-containers/annotation/t1", - "type": "Annotation", - "motivation": [ "painting" ], - "body": { - "id": "https://iiif.io/api/presentation/example-content-resources/audio/clip.mp3", - "type": "Audio", - "format": "audio/mp3", - "duration": 32.76 - }, - "target": "https://example.org/iiif/presentation/examples/manifest-with-containers/timeline" - } - ] - } - ] -} -``` +{% include code_example.html src="02_timeline.json" from=11 to=35 %} ### Canvas A Container that represents a bounded, two-dimensional space, optionally with a bounded temporal range. Canvases are typically used for Image and Video content. -Canvases have two additional required properties: `height` and `width`, which give the spatial extent as integers. Canvases may also have the `duration` property in the same manner as Timelines. +Canvases have two additional required properties: [`height`][prezi-40-model-height] and [`width`][prezi-40-model-width], which give the spatial extent as integers. Canvases may also have the [`duration`][prezi-40-model-duration] property in the same manner as Timelines. ```json { @@ -217,7 +248,7 @@ Canvases have two additional required properties: `height` and `width`, which gi A Container that represents a boundless three-dimensional space, optionally with a bounded temporal range. Scenes are typically used for rendering 3D models, and can additionally have Cameras and Lights. -Scenes may also have the `duration` property in the same manner as Timelines. +Scenes may also have the [`duration`][prezi-40-model-duration] property in the same manner as Timelines. ```json { @@ -255,13 +286,13 @@ Scenes can have time-based and image content in them as well as 3D content. See IIIF uses the concept of _Annotation_ to link resources together from around the web. This specification uses a World Wide Web Consortium (W3C) standard for this called the [Web Annotation Data Model][org-web-anno]. This is a structured linking mechanism useful for making comments about Content Resources, but IIIF's primary use of it is to associate the images, audio and other Content Resources with their Containers for presentation. -In each of the three Containers above, an **Annotation** links the Container to a Content Resource. The Content Resource in the `body` property is _painted_ into the Container by an Annotation whose `target` property is the `id` of the Container. In all three simple cases here the `target` property is the `id` of the Container with no further qualification. +In each of the three Containers above, an **Annotation** links the Container to a Content Resource. The Content Resource in the [`body`][prezi-40-model-body] property is _painted_ into the Container by an Annotation whose [`target`][prezi-40-model-target] property is the [`id`][prezi-40-model-id] of the Container. In all three simple cases here the [`target`][prezi-40-model-target] property is the [`id`][prezi-40-model-id] of the Container with no further qualification. -Different uses of Annotation are distinguished through their `motivation` property. This specification defines a value for `motivation` called `painting` for associating Content Resources with Containers, which this specification calls a Painting Annotation. The verb "paint" is also used to refer to the associating of a Content Resource with a Container by a Painting Annotation. This is from the notion of painting onto a canvas, a metaphor borrowed from art and used for image-based digital applications, and expanded by IIIF into "painting" any Content Resource into a Container of any number of dimensions. +Different uses of Annotation are distinguished through their [`motivation`][prezi-40-model-motivation] property. This specification defines a value for [`motivation`][prezi-40-model-motivation] called `painting` for associating Content Resources with Containers, which this specification calls a Painting Annotation. The verb "paint" is also used to refer to the associating of a Content Resource with a Container by a Painting Annotation. This is from the notion of painting onto a canvas, a metaphor borrowed from art and used for image-based digital applications, and expanded by IIIF into "painting" any Content Resource into a Container of any number of dimensions. The same linking mechanism is also used in IIIF with other motivations for transcriptions, commentary, tags and other content. This provides a single, unified method for aligning content, and provides a standards-based framework for referencing parts of resources. As Annotations can be added later, it promotes a distributed system in which further content such as commentary can be aligned with the objects published on the web. -Annotations are grouped within the `items` property of an Annotation Page, and the `items` property of the Container is a list of Annotation Pages. This allows consistent grouping of Annotations when required. +Annotations are grouped within the [`items`][prezi-40-model-items] property of an Annotation Page, and the [`items`][prezi-40-model-items] property of the Container is a list of Annotation Pages. This allows consistent grouping of Annotations when required. (👀) [Model Documentation](model/#Annotations) @@ -270,7 +301,7 @@ Annotations are grouped within the `items` property of an Annotation Page, and t Content Resources are external web resources, including images, video, audio, 3D models, data, web pages or any other format. Typically these are the resources that will be painted into a Container using a Painting Annotation. -In addition to the required properties `id` and `type`, other commonly used properties include `format`, and `width`, `height` and `duration` as appropriate to the Content Resource format. The values of these properties are often the source of the equivalent Container properties. +In addition to the required properties [`id`][prezi-40-model-id] and [`type`][prezi-40-model-type], other commonly used properties include [`format`][prezi-40-model-format], and [`width`][prezi-40-model-width], [`height`][prezi-40-model-height] and [`duration`][prezi-40-model-duration] as appropriate to the Content Resource format. The values of these properties are often the source of the equivalent Container properties. (👀) [Model Documentation](model/#ContentResources) @@ -302,16 +333,16 @@ There are different types of fragment based on the format of the resource. The m } ``` -Here the Canvas `id` from the earlier example is still the `target` of an Annotation, but it has been qualified to a specific region of that Canvas by a URI fragment `#xywh=6050,3220,925,1250`. Note that the x, y, w, and h are in the Canvas coordinate space, not the image pixel dimensions space. This annotation has no knowledge of or dependency on the particular image we painted onto the Canvas; we could replace that image with one of a different, higher resolution without affecting this annotation or the region of the Canvas it targets. +Here the Canvas [`id`][prezi-40-model-id] from the earlier example is still the [`target`][prezi-40-model-target] of an Annotation, but it has been qualified to a specific region of that Canvas by a URI fragment `#xywh=6050,3220,925,1250`. Note that the x, y, w, and h are in the Canvas coordinate space, not the image pixel dimensions space. This annotation has no knowledge of or dependency on the particular image we painted onto the Canvas; we could replace that image with one of a different, higher resolution without affecting this annotation or the region of the Canvas it targets. ### Specific Resource -URIs with fragments are insufficient for complex referencing, like circular regions or arbitrary text spans, and do not support other useful features such as describing styling or transformation. The Web Annotation Data Model introduces a class called `SpecificResource` that represents the resource in a specific context or role, which IIIF uses to describe these more complex requirements. +URIs with fragments are insufficient for complex referencing, like circular regions or arbitrary text spans, and do not support other useful features such as describing styling or transformation. The Web Annotation Data Model introduces a class called [`SpecificResource`][prezi-40-model-SpecificResource] that represents the resource in a specific context or role, which IIIF uses to describe these more complex requirements. -Several different classes of Selector are used in IIIF, including an alternative implementation of the fragment pattern called `FragmentSelector`. The fragment is given in the `value` property of the `FragmentSelector`, and the resource it should be applied to is given in `source`. +Several different classes of Selector are used in IIIF, including an alternative implementation of the fragment pattern called [`FragmentSelector`][prezi-40-model-FragmentSelector]. The fragment is given in the `value` property of the [`FragmentSelector`][prezi-40-model-FragmentSelector], and the resource it should be applied to is given in [`source`][prezi-40-model-source]. -The required properties of Specific Resources are `id`, `type`, and `source`. Other commonly used properties include `selector`, `transform`, and `scope`. +The required properties of Specific Resources are [`id`][prezi-40-model-id], [`type`][prezi-40-model-type], and [`source`][prezi-40-model-source]. Other commonly used properties include `selector`, [`transform`][prezi-40-model-transform], and `scope`. The fragment example above can be expressed using a Specific Resource: @@ -382,7 +413,7 @@ Collections may include both other Collections and Manifests, forming a tree-str ### Range -IIIF Ranges are used to represent structure _WITHIN_ a Manifest beyond the default order of the Containers in the `items` property. Ranges define meaningful divisions or sequences---such as chapters in a book, sections of a newspaper, or movements of a musical work---that allow clients to present hierarchical or linear navigation interfaces that enable the user to quickly move through the object's content. +IIIF Ranges are used to represent structure _WITHIN_ a Manifest beyond the default order of the Containers in the [`items`][prezi-40-model-items] property. Ranges define meaningful divisions or sequences---such as chapters in a book, sections of a newspaper, or movements of a musical work---that allow clients to present hierarchical or linear navigation interfaces that enable the user to quickly move through the object's content. Ranges may include Containers, parts of Containers via Specific Resources or fragment URIs, or other Ranges, creating tree-like structures that reflect the logical or intellectual organization of the resource, such as a table of contents or an alternative ordering of items. @@ -428,9 +459,9 @@ Ranges may include Containers, parts of Containers via Specific Resources or fra This example is a Manifest with one Canvas, representing an artwork. The content resource, a JPEG image of the artwork, is associated with the Canvas via a Painting Annotation. -The unit integer coordinates of the Canvas (12000 x 9000) are not the same as the pixel dimensions of the JPEG image (4000 x 3000), but they are proportional---the Canvas has a 4:3 landscape aspect ratio, and so does the JPEG image.The `target` property of the Annotation is the Canvas `id`, unqualified by any particular region; this is taken to mean the content (the image) should fill the Canvas completely. As the Canvas and the image are the same aspect ratio, no distortion will occur. This approach allows the current image to be replaced by a higher resolution image in future, on the same Canvas. The Canvas dimensions establish a coordinate system for _painting annotations_ and other kinds of annotation that link content with the Canvas; they are not pixels of images. +The unit integer coordinates of the Canvas (12000 x 9000) are not the same as the pixel dimensions of the JPEG image (4000 x 3000), but they are proportional---the Canvas has a 4:3 landscape aspect ratio, and so does the JPEG image.The [`target`][prezi-40-model-target] property of the Annotation is the Canvas [`id`][prezi-40-model-id], unqualified by any particular region; this is taken to mean the content (the image) should fill the Canvas completely. As the Canvas and the image are the same aspect ratio, no distortion will occur. This approach allows the current image to be replaced by a higher resolution image in future, on the same Canvas. The Canvas dimensions establish a coordinate system for _painting annotations_ and other kinds of annotation that link content with the Canvas; they are not pixels of images. -The example demonstrates the use of the common descriptive properties `label` for the title of the artwork, `metadata` for additional information to display to the user, `summary` for a brief description of the artwork, `rights` to assert a rights statement or license from a controlled vocabulary, `homepage` to link to the artwork's specific web page, `thumbnail` to provide a small image to stand for the Manifest, `provider` to give information about the publisher of the Manifest, and finally, `service` to specify a IIIF Image API service that provides features such as deep zooming, derivative generation, image fragment referencing, rotation, and more. +The example demonstrates the use of the common descriptive properties [`label`][prezi-40-model-label] for the title of the artwork, [`metadata`][prezi-40-model-metadata] for additional information to display to the user, [`summary`][prezi-40-model-summary] for a brief description of the artwork, [`rights`][prezi-40-model-rights] to assert a rights statement or license from a controlled vocabulary, [`homepage`][prezi-40-model-homepage] to link to the artwork's specific web page, [`thumbnail`][prezi-40-model-thumbnail] to provide a small image to stand for the Manifest, [`provider`][prezi-40-model-provider] to give information about the publisher of the Manifest, and finally, [`service`][prezi-40-model-service] to specify a IIIF Image API service that provides features such as deep zooming, derivative generation, image fragment referencing, rotation, and more. ```jsonc { @@ -538,26 +569,26 @@ The example demonstrates the use of the common descriptive properties `label` fo > **Key Points** * All IIIF documents begin with the `@context` key, which maps the JSON structure into a linked data representation. The value identifies the version of the specification in use. [👀 Model Documentation](model/#json-ld-contexts-and-extensions) -* Every JSON object that has a `type` property also has an `id` property and vice versa. +* Every JSON object that has a [`type`][prezi-40-model-type] property also has an [`id`][prezi-40-model-id] property and vice versa. * Text elements intended for display to the user are conveyed by _Language Maps_, JSON objects in which the keys are language codes and the values are lists of one or more strings in that language. [👀 Model Documentation](model/#language-of-property-values) -* The Painting Annotation is a member of the `items` property of an Annotation Page. While in this case there is only one Annotation Page and one Annotation, the mechanism is needed for consistency when there are multiple Annotation Pages, and it allows for Annotation Pages in general to be separate resources on the web. -* The `metadata` label and value pairs are for display to the user rather than for machines to interpret. -* The `rights` property is always a single string value which is a URI. -* Any resource can have a `provider` property which a client can display to the user. This typically tells the user who the publisher is and how they might be contacted. The value of this property is an [Agent](model/#agent). -* The `service` property specifies a software application that a client might interact with to gain additional information or functionality, in this case, the IIIF Image API. Images in IIIF do not require an Image Service---we have included one here as an example, but do not include a service in the following image examples for brevity. +* The Painting Annotation is a member of the [`items`][prezi-40-model-items] property of an Annotation Page. While in this case there is only one Annotation Page and one Annotation, the mechanism is needed for consistency when there are multiple Annotation Pages, and it allows for Annotation Pages in general to be separate resources on the web. +* The [`metadata`][prezi-40-model-metadata] label and value pairs are for display to the user rather than for machines to interpret. +* The [`rights`][prezi-40-model-rights] property is always a single string value which is a URI. +* Any resource can have a [`provider`][prezi-40-model-provider] property which a client can display to the user. This typically tells the user who the publisher is and how they might be contacted. The value of this property is an [Agent](model/#agent). +* The [`service`][prezi-40-model-service] property specifies a software application that a client might interact with to gain additional information or functionality, in this case, the IIIF Image API. Images in IIIF do not require an Image Service---we have included one here as an example, but do not include a service in the following image examples for brevity. {: .note} !!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties __Definitions__
-Classes: [Manifest](#model/Manifest), [Canvas](#model/Canvas), [AnnotationPage](#model/AnnotationPage), [Annotation](#model/Annotation), [Agent](#model/Agent)

-Properties: [id](#model/id), [type](#model/type), [label](#model/label), [metadata](#modle/metadata), [summary](#modle/summary), [rights](#model/rights), [homepage](#model/homepage), [thumbnail](#model/thumbnail), [provider](#model/provider), and [service](#model/Service) +Classes: [Manifest][prezi-40-model-Manifest], [Canvas][prezi-40-model-Canvas], [AnnotationPage][prezi-40-model-AnnotationPage], [Annotation][prezi-40-model-Annotation], [Agent][prezi-40-model-Agent]

+Properties: [id][prezi-40-model-id], [type][prezi-40-model-type], [label][prezi-40-model-label], [metadata][prezi-40-model-metadata], [summary][prezi-40-model-summary], [rights][prezi-40-model-rights], [homepage][prezi-40-model-homepage], [thumbnail][prezi-40-model-thumbnail], [provider][prezi-40-model-provider], and [service][prezi-40-model-Service] {: .note} ## Use Case 2: Book -This example is a Manifest with multiple Canvases, each of which represents a page of a book. It demonstrates the use of the `behavior` property to indicate to a client that the object is _paged_---this helps a client generate the correct user experience. The `viewingDirection` property indicates that the book is read left-to-right. In this case, the property is redundant as `left-to-right` is the default value. The Manifest has a `rendering` property linking to a PDF representation; typically a client would offer this as a download or "view as" option. The `start` property is used to tell a client to initialize the view on a particular Canvas, useful if the digitized work contains a large amount of irrelevant front matter or blank pages. The `requiredStatement` is a message that a client MUST show to the user when presenting the Manifest. +This example is a Manifest with multiple Canvases, each of which represents a page of a book. It demonstrates the use of the [`behavior`][prezi-40-model-behavior] property to indicate to a client that the object is _paged_---this helps a client generate the correct user experience. The [`viewingDirection`][prezi-40-model-viewingDirection] property indicates that the book is read left-to-right. In this case, the property is redundant as `left-to-right` is the default value. The Manifest has a [`rendering`][prezi-40-model-rendering] property linking to a PDF representation; typically a client would offer this as a download or "view as" option. The [`start`][prezi-40-model-start] property is used to tell a client to initialize the view on a particular Canvas, useful if the digitized work contains a large amount of irrelevant front matter or blank pages. The [`requiredStatement`][prezi-40-model-requiredStatement] is a message that a client MUST show to the user when presenting the Manifest. ```json { @@ -681,19 +712,19 @@ This example is a Manifest with multiple Canvases, each of which represents a pa !!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties __Definitions__
-Classes: [Manifest](#model/Manifest), [Canvas](#model/Canvas)

-Properties: [behavior](#model/behavior), [viewingDirection](#model/viewingDirection), [start](#model/start), [rendering](#model/rendering), [requiredStatement](#model/requiredStatement) +Classes: [Manifest][prezi-40-model-Manifest], [Canvas][prezi-40-model-Canvas]

+Properties: [behavior][prezi-40-model-behavior], [viewingDirection][prezi-40-model-viewingDirection], [start][prezi-40-model-start], [rendering][prezi-40-model-rendering], [requiredStatement][prezi-40-model-requiredStatement] {: .note} ## Use Case 3: Periodical -This example demonstrates the use of IIIF Collections to group Manifests into a hierarchy. In this case, there is a Collection for a run of the _The Tombstone Epitaph_, published from 1880 to 1920. This contains 41 child Collections each representing a year's worth of issues. The parent Collection and each of its child Collections use the `behavior` "multi-part" to signal that the Collections and their Manifests are part of a logical set. Each of the year Collections has one Manifest for each issue of the newspaper. +This example demonstrates the use of IIIF Collections to group Manifests into a hierarchy. In this case, there is a Collection for a run of the _The Tombstone Epitaph_, published from 1880 to 1920. This contains 41 child Collections each representing a year's worth of issues. The parent Collection and each of its child Collections use the [`behavior`][prezi-40-model-behavior] "multi-part" to signal that the Collections and their Manifests are part of a logical set. Each of the year Collections has one Manifest for each issue of the newspaper. -The top-level Collection has a `navPlace` property that could be used on a "Newspapers of America" map to allow users to view newspapers by location. Each Manifest has a `navDate` property that could be used to plot the issues on a timeline or calendar-style user interface. Within each Manifest, the `structures` property provides Ranges which are used to identify individual sections of the Newspaper, and individual stories within those sections, which may be spread across multiple columns and pages. Each story's Range includes the `supplementary` property to link to an Annotation Collection that provides the text of the story. +The top-level Collection has a [`navPlace`][prezi-40-model-navPlace] property that could be used on a "Newspapers of America" map to allow users to view newspapers by location. Each Manifest has a [`navDate`][prezi-40-model-navDate] property that could be used to plot the issues on a timeline or calendar-style user interface. Within each Manifest, the [`structures`][prezi-40-model-structures] property provides Ranges which are used to identify individual sections of the Newspaper, and individual stories within those sections, which may be spread across multiple columns and pages. Each story's Range includes the [`supplementary`][prezi-40-model-supplementary] property to link to an Annotation Collection that provides the text of the story. -IIIF Collection with `behavior` "multi-part" that contains the individual "multi-part" Collections for each year/volume: +IIIF Collection with [`behavior`][prezi-40-model-behavior] "multi-part" that contains the individual "multi-part" Collections for each year/volume: ```json { @@ -734,7 +765,7 @@ IIIF Collection with `behavior` "multi-part" that contains the individual "multi ] } ``` -IIIF Collection with `behavior` "multi-part" for the second volume (1881), with individual Manifests for each issue: +IIIF Collection with [`behavior`][prezi-40-model-behavior] "multi-part" for the second volume (1881), with individual Manifests for each issue: ```json { @@ -855,8 +886,8 @@ Manifest for the October 27, 1881 issue, with Ranges for table of contents: {: .note} __Definitions__
-Classes: [Collection](#model/Collection), [Range](#model/Range), [AnnotationCollection](#model/AnnotationCollection)

-Properties: [behavior](#model/behavior), [navPlace](#model/navPlace), [navDate](#model/navDate), [structure](#model/structures), [supplementary](#model/supplementary) +Classes: [Collection][prezi-40-model-Collection], [Range][prezi-40-model-Range], [AnnotationCollection][prezi-40-model-AnnotationCollection]

+Properties: [behavior][prezi-40-model-behavior], [navPlace][prezi-40-model-navPlace], [navDate][prezi-40-model-navDate], [structure][prezi-40-model-structures], [supplementary][prezi-40-model-supplementary] {: .note} thumbnail-nav @@ -868,7 +899,7 @@ sequence ## Use Case 4: A 45 single with 2 tracks -This example is a Manifest with two Timelines, each of which represent a temporal extent during which a song is played. As in most cases, the Timeline `duration` is the same length as that of Content Resource painted into it. This example is a recording digitized from a 45 RPM 7 inch single. It demonstrates the use of `format` for the audio files' content type, `language` (One song is in English and one is in German), `behavior` with value "auto-advance" that tells a client to automatically advance to the second Timeline after playing the first, `annotations` that link to Annotation Pages of annotations with the motivation `supplementing` that provide the lyrics (one example is given afterwards) - and an `accompanyingContainer` that carries a picture of the single's cover that is shown while the songs are playing. +This example is a Manifest with two Timelines, each of which represent a temporal extent during which a song is played. As in most cases, the Timeline [`duration`][prezi-40-model-duration] is the same length as that of Content Resource painted into it. This example is a recording digitized from a 45 RPM 7 inch single. It demonstrates the use of [`format`][prezi-40-model-format] for the audio files' content type, [`language`][prezi-40-model-language] (One song is in English and one is in German), [`behavior`][prezi-40-model-behavior] with value "auto-advance" that tells a client to automatically advance to the second Timeline after playing the first, [`annotations`][prezi-40-model-annotations] that link to Annotation Pages of annotations with the motivation `supplementing` that provide the lyrics (one example is given afterwards) - and an [`accompanyingContainer`][prezi-40-model-accompanyingContainer] that carries a picture of the single's cover that is shown while the songs are playing. ```json @@ -1004,14 +1035,14 @@ This example is a Manifest with two Timelines, each of which represent a tempora !!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties __Definitions__
-Classes: [Manifest](#model/Manifest), [Timeline](#model/Timeline),[TextualBody](#model/TextualBody)

-Properties: [duration](#model/duration), [format](#model/format), [language](#model/language), [behavior](#model/behavior), [annotations](#model/annotations), [accompanyingContainer](#model/accompanyingContainer) +Classes: [Manifest][prezi-40-model-Manifest], [Timeline][prezi-40-model-Timeline],[TextualBody][prezi-40-model-TextualBody]

+Properties: [duration][prezi-40-model-duration], [format][prezi-40-model-format], [language][prezi-40-model-language], [behavior][prezi-40-model-behavior], [annotations][prezi-40-model-annotations], [accompanyingContainer][prezi-40-model-accompanyingContainer] {: .note} ## Use Case 5: Movie with subtitles -This example is a Manifest with one Canvas that represents the temporal extent of the movie (the Canvas `duration`) and its aspect ratio (given by the `width` and `height` of the Canvas). The example demonstrates the use of a `Choice` annotation body to give two alternative versions of the movie, indicated by their `label` and `fileSize` properties as well as `height` and `width`. Subtitles are provided by an annotation that links to a VTT file. The motivation of this annotation is `supplementing` and the `provides` property of this annotation indicates what accessibility feature it provides, in this case the term `subtitles`. The `timeMode` property in this case is redundant as `trim` is the default value. The Canvas has a `placeholderContainer` that provides a poster image to show in place of the video file before the user initiates playback. +This example is a Manifest with one Canvas that represents the temporal extent of the movie (the Canvas [`duration`][prezi-40-model-duration]) and its aspect ratio (given by the [`width`][prezi-40-model-width] and [`height`][prezi-40-model-height] of the Canvas). The example demonstrates the use of a [`Choice`][prezi-40-model-Choice] annotation body to give two alternative versions of the movie, indicated by their [`label`][prezi-40-model-label] and `fileSize` properties as well as [`height`][prezi-40-model-height] and [`width`][prezi-40-model-width]. Subtitles are provided by an annotation that links to a VTT file. The motivation of this annotation is `supplementing` and the [`provides`][prezi-40-model-provides] property of this annotation indicates what accessibility feature it provides, in this case the term `subtitles`. The [`timeMode`][prezi-40-model-timeMode] property in this case is redundant as `trim` is the default value. The Canvas has a [`placeholderContainer`][prezi-40-model-placeholderContainer] that provides a poster image to show in place of the video file before the user initiates playback. ```json { @@ -1126,16 +1157,16 @@ This example is a Manifest with one Canvas that represents the temporal extent o > **Key Points** -* The decision about which item in the `Choice` to play by default is client dependent. In the absence of any other decision process the client should play the first item. In this specific example, the user might make the decision after reading the `label`, or the client might make the decision based on the `fileSize` property and an assessment of the user's available bandwidth. However, the client may have no way of determining why the publisher has offered the choices, and should not prevent the user from making the choice. The cookbook demonstrates several uses of `Choice` for common image and AV use cases. -* Slop - impl note - don't interpret **very** minor discrepancies between `duration` on the different Choices and the Container `duration` as an instruction to stretch or compress the audio/video stream to match the Container duration. No real way to quantify this, just _be sensible_. +* The decision about which item in the [`Choice`][prezi-40-model-Choice] to play by default is client dependent. In the absence of any other decision process the client should play the first item. In this specific example, the user might make the decision after reading the [`label`][prezi-40-model-label], or the client might make the decision based on the `fileSize` property and an assessment of the user's available bandwidth. However, the client may have no way of determining why the publisher has offered the choices, and should not prevent the user from making the choice. The cookbook demonstrates several uses of [`Choice`][prezi-40-model-Choice] for common image and AV use cases. +* Slop - impl note - don't interpret **very** minor discrepancies between [`duration`][prezi-40-model-duration] on the different Choices and the Container [`duration`][prezi-40-model-duration] as an instruction to stretch or compress the audio/video stream to match the Container duration. No real way to quantify this, just _be sensible_. {: .note} !!! warning TODO: The above should be a green class rgb(244,252,239) to distinguish from properties __Definitions__
-Classes: [Manifest](#model/Manifest), [Canvas](#model/Canvas), [Choice](#model/Choice)

-Properties: [fileSize](#model/fileSize), [format](#model/format), [provides](#model/provides), [timeMode](#model/timeMode), [behavior](#model/behavior), [placeholderContainer](#model/placeholderContainer) +Classes: [Manifest][prezi-40-model-Manifest], [Canvas][prezi-40-model-Canvas], [Choice][prezi-40-model-Choice]

+Properties: [fileSize](#model/fileSize), [format][prezi-40-model-format], [provides][prezi-40-model-provides], [timeMode][prezi-40-model-timeMode], [behavior][prezi-40-model-behavior], [placeholderContainer][prezi-40-model-placeholderContainer] {: .note} # 3D @@ -1148,7 +1179,7 @@ The positive y axis points upwards, the positive x axis points to the right, and (Image: Wikipedia) -3D Content Resources are painted into Scenes. This can include 3D models, which can be painted into Scenes as Annotations with `motivation` "painting". Due to particular considerations of 3D space and rendering content within that space, such as scaling or textures with forward and backward faces, non-3D Content Resources must first be wrapped within an appropriate Container or Resource before being painted into a Scene. Image and video resources should be painted on to a Canvas, where the Canvas can in turn be painted into a Scene. Audio resources or Timelines should be referenced by an AudioEmitter and the AudioEmitter can be painted into a Scene. For further detail about painting Containers within other Containers, see [Nesting](#nesting). +3D Content Resources are painted into Scenes. This can include 3D models, which can be painted into Scenes as Annotations with [`motivation`][prezi-40-model-motivation] "painting". Due to particular considerations of 3D space and rendering content within that space, such as scaling or textures with forward and backward faces, non-3D Content Resources must first be wrapped within an appropriate Container or Resource before being painted into a Scene. Image and video resources should be painted on to a Canvas, where the Canvas can in turn be painted into a Scene. Audio resources or Timelines should be referenced by an AudioEmitter and the AudioEmitter can be painted into a Scene. For further detail about painting Containers within other Containers, see [Nesting](#nesting). ## 3D Supporting Resources @@ -1158,25 +1189,25 @@ Constructs from the domain of 3D graphics are expressed in IIIF as Resources. Th A Camera provides a view of a region of the Scene's space from a particular position within the Scene; the client constructs a viewport into the Scene and uses the view of one or more Cameras to render that region. The size and aspect ratio of the viewport is client and device dependent. -There are two types of Camera, `PerspectiveCamera` and `OrthographicCamera`. The first Camera defined and not [hidden](model#hidden-value) in a Scene is the default Camera used to display Scene contents. If the Scene does not have any Cameras defined within it, then the client provides a default Camera. The type, properties and position of this default camera are client-dependent. +There are two types of Camera, [`PerspectiveCamera`][prezi-40-model-PerspectiveCamera] and [`OrthographicCamera`][prezi-40-model-OrthographicCamera]. The first Camera defined and not [hidden](model#hidden-value) in a Scene is the default Camera used to display Scene contents. If the Scene does not have any Cameras defined within it, then the client provides a default Camera. The type, properties and position of this default camera are client-dependent. ### Lights -There are four types of Light: AmbientLight, DirectionalLight, PointLight and SpotLight. They have a `color` and an `intensity`. SpotLight has an additional property of `angle` that determines the spread of its light cone. +There are four types of Light: AmbientLight, DirectionalLight, PointLight and SpotLight. They have a [`color`][prezi-40-model-color] and an [`intensity`][prezi-40-model-intensity]. SpotLight has an additional property of [`angle`][prezi-40-model-angle] that determines the spread of its light cone. If the Scene has no Lights, then the client provides its own lighting as it sees fit. ### Audio Emitters -There are three types of Audio emitter: AmbientAudio, PointAudio and SpotAudio. They have a `source` (an audio Content Resource) and a `volume`. +There are three types of Audio emitter: AmbientAudio, PointAudio and SpotAudio. They have a [`source`][prezi-40-model-source] (an audio Content Resource) and a [`volume`][prezi-40-model-volume]. ### Transforms -When painting resources into Scenes, it is often necessary to resize, rotate or move them relative to the coordinate space of the Scene. These operations are specified using three Transforms: ScaleTransform, RotateTransform and TranslateTransform. Each Transform has three properties, `x`, `y` and `z` which determine how the Transform affects that axis in the local coordinate space. +When painting resources into Scenes, it is often necessary to resize, rotate or move them relative to the coordinate space of the Scene. These operations are specified using three Transforms: ScaleTransform, RotateTransform and TranslateTransform. Each Transform has three properties, [`x`][prezi-40-model-x], [`y`][prezi-40-model-y] and [`z`][prezi-40-model-z] which determine how the Transform affects that axis in the local coordinate space. -Transforms are added to a SpecificResource using the `transform` property, and there may be more than one applied when adding a model to a Scene. Different orders of the same set of transforms can have different results, so attention must be paid when creating the array and when processing it. +Transforms are added to a SpecificResource using the [`transform`][prezi-40-model-transform] property, and there may be more than one applied when adding a model to a Scene. Different orders of the same set of transforms can have different results, so attention must be paid when creating the array and when processing it. ## Use Case 5: Simple 3D Model @@ -1224,7 +1255,7 @@ This example is a Manifest with a single Scene, with a single model of a space s > **Key Points** * As this Scene only has one resource in it (the model), the client must provide lighting and a default camera. -* In this simplest use case, the Painting Annotation targets the whole Scene rather than a specific point. The client places the model's origin at the Scene's origin. This is in contrast to the _bounded_ Containers `Canvas` and `Timeline`, where the painted resource fills the Container completely. +* In this simplest use case, the Painting Annotation targets the whole Scene rather than a specific point. The client places the model's origin at the Scene's origin. This is in contrast to the _bounded_ Containers [`Canvas`][prezi-40-model-Canvas] and [`Timeline`][prezi-40-model-Timeline], where the painted resource fills the Container completely. {: .note} @@ -1232,9 +1263,9 @@ This example is a Manifest with a single Scene, with a single model of a space s This example adds a Light and a Camera to the previous example, and places the model at a specific point rather than at the default origin position. -Annotations may use a type of Selector called a `PointSelector` to align the Annotation to a point within the Scene that is not the Scene's origin. PointSelectors have three spatial properties, `x`, `y` and `z` which give the value on that axis. They also have a temporal property `instant` which can be used if the Scene has a duration, which gives the temporal point in seconds from the start of the duration, the use of which is defined in the [section on Scenes with Durations](). +Annotations may use a type of Selector called a [`PointSelector`][prezi-40-model-PointSelector] to align the Annotation to a point within the Scene that is not the Scene's origin. PointSelectors have three spatial properties, [`x`][prezi-40-model-x], [`y`][prezi-40-model-y] and [`z`][prezi-40-model-z] which give the value on that axis. They also have a temporal property [`instant`][prezi-40-model-instant] which can be used if the Scene has a duration, which gives the temporal point in seconds from the start of the duration, the use of which is defined in the [section on Scenes with Durations](). -The Light is green and has a position, but has its default orientation of looking along the negative-y axis as no rotation has been specified. The Camera has a position and is pointing at the model's origin via the `lookAt` property. The Camera has a `fieldOfView` of 50. The `near` and `far` properties are included to ensure the model falls within the camera's range (although unnecessary in a simple Scene like this). The Scene has a background color. +The Light is green and has a position, but has its default orientation of looking along the negative-y axis as no rotation has been specified. The Camera has a position and is pointing at the model's origin via the [`lookAt`][prezi-40-model-lookAt] property. The Camera has a [`fieldOfView`][prezi-40-model-fieldOfView] of 50. The [`near`][prezi-40-model-near] and [`far`][prezi-40-model-far] properties are included to ensure the model falls within the camera's range (although unnecessary in a simple Scene like this). The Scene has a background color. Use case 5a @@ -1358,18 +1389,18 @@ The Light is green and has a position, but has its default orientation of lookin > **Key Points** * This example uses some of the Scene-Specific resources introduced in the next section. -* A Point Selector explicitly places the model in the Scene via the Painting Annotation's `target` property. In the previous example, there was an implicit Point Selector placing the model at (0,0,0) because no explicit Point Selector was provided. +* A Point Selector explicitly places the model in the Scene via the Painting Annotation's [`target`][prezi-40-model-target] property. In the previous example, there was an implicit Point Selector placing the model at (0,0,0) because no explicit Point Selector was provided. * The provided Light should replace any default lighting the client might have. {: .note} __Definitions__
-Classes: [Manifest](#model/Manifest), [Scene](#model/Scene), [Model](#model/Model), [SpecificResource](#model/SpecificResource), [PointSelector](#model/PointSelector), [PerspectiveCamera](#model/PerspectiveCamera), [SpotLight](#model/SpotLight)

-Properties: [backgroundColor](#model/backgroundColor), [lookAt](#model/lookAt), [near](#model/near), [far](#model/far), [feildOfView](#model/fieldOfView), [angle](#model/angle), [color](#model/color) +Classes: [Manifest][prezi-40-model-Manifest], [Scene][prezi-40-model-Scene], [Model](#model/Model), [SpecificResource][prezi-40-model-SpecificResource], [PointSelector][prezi-40-model-PointSelector], [PerspectiveCamera][prezi-40-model-PerspectiveCamera], [SpotLight][prezi-40-model-SpotLight]

+Properties: [backgroundColor][prezi-40-model-backgroundColor], [lookAt][prezi-40-model-lookAt], [near][prezi-40-model-near], [far][prezi-40-model-far], [feildOfView][prezi-40-model-fieldOfView], [angle][prezi-40-model-angle], [color][prezi-40-model-color] {: .note} ## Use Case 6: Complex Scene -This example is a Manifest with a single Scene with multiple models painted into the Scene at specific positions with transforms applied. It represents a collection of chess game pieces with multiple pawns and a single queen. The example demonstrates painting multiple models into a Scene, including one Content Resource being painted into a Scene multiple times. Transforms and Point Selectors are used to establish position and scale for Annotations. Some external web resources referenced as Content Resources may include elements such as lights or audio that are undesirable within a Manifest, and the `exclude` property is used to prevent these from being rendered. The property `interactionMode` is used to guide clients in how to best guide or limit user interaction with rendered content. +This example is a Manifest with a single Scene with multiple models painted into the Scene at specific positions with transforms applied. It represents a collection of chess game pieces with multiple pawns and a single queen. The example demonstrates painting multiple models into a Scene, including one Content Resource being painted into a Scene multiple times. Transforms and Point Selectors are used to establish position and scale for Annotations. Some external web resources referenced as Content Resources may include elements such as lights or audio that are undesirable within a Manifest, and the [`exclude`][prezi-40-model-exclude] property is used to prevent these from being rendered. The property [`interactionMode`][prezi-40-model-interactionMode] is used to guide clients in how to best guide or limit user interaction with rendered content. ```jsonc { @@ -1511,13 +1542,13 @@ This example is a Manifest with a single Scene with multiple models painted into * Each Annotation is painted into the Scene at a different point via Point Selectors. * The second Annotation represents a pawn game piece that is tipped over, and Transforms are used to achieve this. RotateTransform is used to tip the pawn over and TranslateTransform is used to align the bottom of the pawn with the coordinate origin's XY plane. * The third Annotation represents a queen game piece that is scaled to be larger than the pawns using ScaleTransform. -* The `exclude` property instructs clients not to import or render any external audio or light content present in the Content Resource for the queen game piece. -* The `interactionMode` property instructs clients that, if possible, user interactions relating to orbiting the scene should be restricted to a hemisphere. +* The [`exclude`][prezi-40-model-exclude] property instructs clients not to import or render any external audio or light content present in the Content Resource for the queen game piece. +* The [`interactionMode`][prezi-40-model-interactionMode] property instructs clients that, if possible, user interactions relating to orbiting the scene should be restricted to a hemisphere. {: .note} __Definitions__
-Classes: [Manifest](#model/Manifest), [Scene](#model/Scene), [Model](#model/Model), [SpecificResource](#model/SpecificResource), [PointSelector](#model/PointSelector), [RotateTransform](#model/RotateTransform), [TranslateTransform](#model/TranslateTransform), [ScaleTransform](#model/ScaleTransform)

-Properties: [exclude](#model/exclude), [interactionMode](#model/interactionMode) +Classes: [Manifest][prezi-40-model-Manifest], [Scene][prezi-40-model-Scene], [Model](#model/Model), [SpecificResource][prezi-40-model-SpecificResource], [PointSelector][prezi-40-model-PointSelector], [RotateTransform][prezi-40-model-RotateTransform], [TranslateTransform][prezi-40-model-TranslateTransform], [ScaleTransform][prezi-40-model-ScaleTransform]

+Properties: [exclude][prezi-40-model-exclude], [interactionMode][prezi-40-model-interactionMode] {: .note} @@ -1534,9 +1565,9 @@ A Scene or a Canvas may be treated as a content resource, referenced or describe This example is a Manifest with a single Scene with a duration. Multiple Audio Emitter Annotations are painted into the Scene, with positional emitters used to create a 3D audio experience. Some of the Audio Emitter Annotations are only painted into the Scene for a limited period of time, producing dynamic change in the sounds heard within the Scene. A commenting Annotation is also provided to highlight the instant in time when a change in sound occurs. -A content resource may be annotated into a Scene for a period of time by use of a PointSelector that is temporally scoped by a [FragmentSelector](https://www.w3.org/TR/annotation-model/#fragment-selector). The FragmentSelector has a `value` property, the value of which follows the [media fragment syntax](https://www.w3.org/TR/media-frags/#naming-time) of `t=`. This annotation pattern uses the `refinedBy` property [defined by the W3C Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#refinement-of-selection). When using a URL fragment in place of a SpecificResource, the parameter `t` can be used to select the temporal region. Both patterns are used in this example. +A content resource may be annotated into a Scene for a period of time by use of a PointSelector that is temporally scoped by a [FragmentSelector](https://www.w3.org/TR/annotation-model/#fragment-selector). The FragmentSelector has a `value` property, the value of which follows the [media fragment syntax](https://www.w3.org/TR/media-frags/#naming-time) of `t=`. This annotation pattern uses the [`refinedBy`][prezi-40-model-refinedBy] property [defined by the W3C Web Annotation Data Model](https://www.w3.org/TR/annotation-model/#refinement-of-selection). When using a URL fragment in place of a SpecificResource, the parameter `t` can be used to select the temporal region. Both patterns are used in this example. -An Annotation may target a specific point in time using a PointSelector's `instant` property. The property's value must be a positive floating point number indicating a value in seconds that falls within the Scene's duration. In this example this is used for a comment Annotation. +An Annotation may target a specific point in time using a PointSelector's [`instant`][prezi-40-model-instant] property. The property's value must be a positive floating point number indicating a value in seconds that falls within the Scene's duration. In this example this is used for a comment Annotation. In this example, the audio content resources have durations that do not match the Scene's duration. The Annotation property [`timeMode` property](https://iiif.io/api/presentation/3.0/#timemode) is used to indicate the desired behavior when the duration of the content resource that is not equal to the temporal region targeted by the annotation. @@ -1691,18 +1722,18 @@ In this example, the audio content resources have durations that do not match th > **Key Points** * The Scene has a duration of 60 seconds. -* The Scene has three different Audio Emitter Annotations painted into the Scene---AmbientAudio, PointAudio, and SpotAudio. Each Audio Emitter uses the `volume` property to specify audio volume. +* The Scene has three different Audio Emitter Annotations painted into the Scene---AmbientAudio, PointAudio, and SpotAudio. Each Audio Emitter uses the [`volume`][prezi-40-model-volume] property to specify audio volume. * AmbientAudio targets the Scene via a reference to the Scene URI, which implicitly targets the Scene's entire duration. * PointAudio targets the Scene with a PointSelector to paint the Audio Emitter at a specific point in 3D space, and that PointSelector is temporally scoped by a FragmentSelector to target the first 30 seconds of the Scene duration. -* SpotAudio targets the Scene via a URL fragment to demonstrate an alternate approach to target a point and range of time in the Scene. It uses the `lookAt` property to point the Audio Emitter cone toward the Scene origin. -* The content resources for PointAudio and SpotAudio use the property `timeMode` to specify different ways of handling mismatches between content resource audio length and Scene duration. +* SpotAudio targets the Scene via a URL fragment to demonstrate an alternate approach to target a point and range of time in the Scene. It uses the [`lookAt`][prezi-40-model-lookAt] property to point the Audio Emitter cone toward the Scene origin. +* The content resources for PointAudio and SpotAudio use the property [`timeMode`][prezi-40-model-timeMode] to specify different ways of handling mismatches between content resource audio length and Scene duration. * A commenting Annotation targets the Scene at the instant corresponding to 30 seconds of the Scene duration to highlight the point at which PointAudio stops playing and SpotAudio begins playing. -* It is an error to select a temporal region of a Scene that does not have a `duration`, or to select a temporal region that is not within the Scene's temporal extent. A Canvas or Scene with a `duration` may not be annotated as a content resource into a Scene that does not itself have a `duration`. +* It is an error to select a temporal region of a Scene that does not have a [`duration`][prezi-40-model-duration], or to select a temporal region that is not within the Scene's temporal extent. A Canvas or Scene with a [`duration`][prezi-40-model-duration] may not be annotated as a content resource into a Scene that does not itself have a [`duration`][prezi-40-model-duration]. {: .note} __Definitions__
-Classes: [Manifest](#model/Manifest), [Scene](#model/Scene), [SpecificResource](#model/SpecificResource), [PointSelector](#model/PointSelector), [FragmentSelector](#model/FragmentSelector), [AmbientAudio](#model/AmbientAudio), [PointAudio](#model/PointAudio), [SpotAudio](#model/SpotAudio)

-Properties: [duration](#model/duration), [volume](#model/volume), [angle](#model/angle), [lookAt](#model/lookAt), [timeMode](#model/timeMode) +Classes: [Manifest][prezi-40-model-Manifest], [Scene][prezi-40-model-Scene], [SpecificResource][prezi-40-model-SpecificResource], [PointSelector][prezi-40-model-PointSelector], [FragmentSelector][prezi-40-model-FragmentSelector], [AmbientAudio][prezi-40-model-AmbientAudio], [PointAudio][prezi-40-model-PointAudio], [SpotAudio][prezi-40-model-SpotAudio]

+Properties: [duration][prezi-40-model-duration], [volume][prezi-40-model-volume], [angle][prezi-40-model-angle], [lookAt][prezi-40-model-lookAt], [timeMode][prezi-40-model-timeMode] {: .note} @@ -1710,9 +1741,9 @@ Properties: [duration](#model/duration), [volume](#model/volume), [angle](#model > How does this relate to model doc? What's normative and needs to be in model.md because it defines a Scene? -A Container can be painted into another Container as an Annotation with `motivation` "painting". For example, a Timeline may be painted into a Canvas, a Canvas may be painted into another Canvas, a Canvas may be painted into a Scene, and a Scene may be painted into another Scene. Multiple Containers may be hierarchically nested within each other, and so the list of examples above could be implemented as a single nesting sequence of five Containers. +A Container can be painted into another Container as an Annotation with [`motivation`][prezi-40-model-motivation] "painting". For example, a Timeline may be painted into a Canvas, a Canvas may be painted into another Canvas, a Canvas may be painted into a Scene, and a Scene may be painted into another Scene. Multiple Containers may be hierarchically nested within each other, and so the list of examples above could be implemented as a single nesting sequence of five Containers. -A Timeline, Canvas, or Scene with `duration` can only be painted into a Container that also has `duration`. It is possible to associate a Container with `duration` with a Container that does not have `duration` as the content of a `commenting` annotation rather than painting it into the Container. If a Container with `duration` has a shorter or longer `duration` than the Container into which it is to be painted, the `timeMode` property can be used to instruct clients how to resolve the mismatch. +A Timeline, Canvas, or Scene with [`duration`][prezi-40-model-duration] can only be painted into a Container that also has [`duration`][prezi-40-model-duration]. It is possible to associate a Container with [`duration`][prezi-40-model-duration] with a Container that does not have [`duration`][prezi-40-model-duration] as the content of a `commenting` annotation rather than painting it into the Container. If a Container with [`duration`][prezi-40-model-duration] has a shorter or longer [`duration`][prezi-40-model-duration] than the Container into which it is to be painted, the [`timeMode`][prezi-40-model-timeMode] property can be used to instruct clients how to resolve the mismatch. ```jsonc { @@ -1735,21 +1766,21 @@ A Timeline, Canvas, or Scene with `duration` can only be painted into a Containe ## Painting a Canvas or Timeline into a Scene -Painting nested content into a Scene has some special requirements that must be observed due to important distinctions relating to the infinite boundless 3D space described by a Scene. 2D image or video content resources can be painted into a Scene by first painting the image or video content resource on a Canvas and then painting the Canvas into the Scene. In the case of painting a Timeline into a Scene, an Audio Emitter can be painted into the scene where Timeline is the `body` of the Audio Emitter. This provides greater control over the intended presentation of the Timeline's audio content within the 3D space of the Scene. +Painting nested content into a Scene has some special requirements that must be observed due to important distinctions relating to the infinite boundless 3D space described by a Scene. 2D image or video content resources can be painted into a Scene by first painting the image or video content resource on a Canvas and then painting the Canvas into the Scene. In the case of painting a Timeline into a Scene, an Audio Emitter can be painted into the scene where Timeline is the [`body`][prezi-40-model-body] of the Audio Emitter. This provides greater control over the intended presentation of the Timeline's audio content within the 3D space of the Scene. -A Canvas can be painted into a Scene as an Annotation, though differences between the 2D space described by a Canvas and the 3D space described by a Scene must be considered. A Canvas describes a bounded 2D space with finite `height` and `width` measured in 2D integer coordinates with a coordinate origin at the top-left corner of the Canvas, while Scenes describe a boundless 3D space with x, y, and z axes of 3D continuous coordinates and a coordinate origin at the center of the space. Further, although 2D images or videos with pixel height and width can be painted into a Canvas, Canvas 2D coordinates are not equivalent to pixels. An image of any height and width in pixels can be painted into a Canvas with different height and weight in coordinate units, and this has important consequences for painting Canvases into Scenes. +A Canvas can be painted into a Scene as an Annotation, though differences between the 2D space described by a Canvas and the 3D space described by a Scene must be considered. A Canvas describes a bounded 2D space with finite [`height`][prezi-40-model-height] and [`width`][prezi-40-model-width] measured in 2D integer coordinates with a coordinate origin at the top-left corner of the Canvas, while Scenes describe a boundless 3D space with x, y, and z axes of 3D continuous coordinates and a coordinate origin at the center of the space. Further, although 2D images or videos with pixel height and width can be painted into a Canvas, Canvas 2D coordinates are not equivalent to pixels. An image of any height and width in pixels can be painted into a Canvas with different height and weight in coordinate units, and this has important consequences for painting Canvases into Scenes. When a Canvas is painted as an Annotation targeting a Scene, the top-left corner of the Canvas (the 2D coordinate origin) is aligned with the 3D coordinate origin of the Scene. The top edge of the Canvas is aligned with (e.g., is colinear to) the positive x axis extending from the coordinate origin. The left edge of the Canvas is aligned with (e.g., is colinear to) the negative y axis extending from the coordinate origin. The direction terms "top", "bottom", "right", and "left" used in this section refer to the frame of reference of the Canvas itself, not the Scene into which the Canvas is painted. The Canvas is scaled to the Scene such that the 2D coordinate dimensions correspond to 3D coordinate units - a Canvas 16 units wide and 9 units high will extend 16 coordinate units across the x axis and 9 coordinate units across the y axis. Because Canvas coordinate units and image content resource pixels are not equivalent, any image with a 16:9 aspect ratio painted on this Canvas would extend 16 coordinate units by 9 coordinate units in the 3D space of the Scene, whether it was 160 pixels wide and 90 pixels high or 16,000 pixels wide and 9,000 pixels high. This provides one way to control the size of a Canvas painted into a Scene. -A Canvas in a Scene has a specific forward face and a backward face. By default, the forward face of a Canvas should point in the direction of the positive z axis. If the property `backgroundColor` is used, this color should be used for the backward face of the Canvas. Otherwise, a reverse view of the forward face of the Canvas should be visible on the backward face. +A Canvas in a Scene has a specific forward face and a backward face. By default, the forward face of a Canvas should point in the direction of the positive z axis. If the property [`backgroundColor`][prezi-40-model-backgroundColor] is used, this color should be used for the backward face of the Canvas. Otherwise, a reverse view of the forward face of the Canvas should be visible on the backward face.
To Do: Add an image demonstrating default Canvas placement in Scene
-A `PointSelector` can be used to modify the point at which the Canvas will be painted, by establishing a new point to align with the top-left corner of the Canvas instead of the Scene coordinate origin. [Transforms](#transforms) can be used to modify Canvas rotation, scale, or translation, allowing in particular for an alternate method to control the size of a Canvas to be scaled appropriately to other contents within a Scene. The forward face and backward face of a Canvas can be interchanged with a Scale Transform scaling the z axis by -1.0, though this reflection will also produce mirroring. +A [`PointSelector`][prezi-40-model-PointSelector] can be used to modify the point at which the Canvas will be painted, by establishing a new point to align with the top-left corner of the Canvas instead of the Scene coordinate origin. [Transforms](#transforms) can be used to modify Canvas rotation, scale, or translation, allowing in particular for an alternate method to control the size of a Canvas to be scaled appropriately to other contents within a Scene. The forward face and backward face of a Canvas can be interchanged with a Scale Transform scaling the z axis by -1.0, though this reflection will also produce mirroring. ```jsonc { @@ -1806,7 +1837,7 @@ A `PointSelector` can be used to modify the point at which the Canvas will be pa Like Timelines or Canvases, Scenes can be painted into Scenes. As with other resources, it may be appropriate to modify the initial scale, rotation, or translation of a content resource Scene prior to painting it within another Scene. Scenes associated with SpecificResources may be manipulated through [Transforms](#transforms). -When a Scene is nested into another Scene, the `backgroundColor` of the Scene to be nested should be ignored as it is non-sensible to import. All Annotations painted into the Scene to be nested will be painted into the Scene into which content is being nested, including Light or Camera resources. If the Scene to be nested has one or more Camera Annotations while the Scene into which content is being nested does not, the first Camera Annotation from the nested Scene will become the default Camera for the overall Scene. +When a Scene is nested into another Scene, the [`backgroundColor`][prezi-40-model-backgroundColor] of the Scene to be nested should be ignored as it is non-sensible to import. All Annotations painted into the Scene to be nested will be painted into the Scene into which content is being nested, including Light or Camera resources. If the Scene to be nested has one or more Camera Annotations while the Scene into which content is being nested does not, the first Camera Annotation from the nested Scene will become the default Camera for the overall Scene. ```jsonc { @@ -1826,7 +1857,7 @@ When a Scene is nested into another Scene, the `backgroundColor` of the Scene to In the examples so far, Annotations have been used to associate the images, audio and other Content Resources with their Containers for presentation. IIIF uses the same W3C standard for the perhaps more familiar _annotation_ concepts of commenting, tagging, describing and so on. Annotations can carry textual transcriptions or translations of the content, discussion about the content and any other linking between resources. -Whereas annotations that associate content resources with Containers are included in the `items` property of the Container, all other types of Annotation are referenced from the `annotations` property. Containers, Manifests, Collections and Ranges can all have this property, linking to relevant annotations. As with the `items` property, annotations are grouped into one or more AnnotationPage resources. These are usually external references. +Whereas annotations that associate content resources with Containers are included in the [`items`][prezi-40-model-items] property of the Container, all other types of Annotation are referenced from the [`annotations`][prezi-40-model-annotations] property. Containers, Manifests, Collections and Ranges can all have this property, linking to relevant annotations. As with the [`items`][prezi-40-model-items] property, annotations are grouped into one or more AnnotationPage resources. These are usually external references. ``` Manifest @@ -1921,7 +1952,7 @@ This is an example of a commenting annotation that targets two-minute segment of ### A comment about a face in a painting -A comment on a Canvas can target a non-rectangular area. This example uses a `SvgSelector` to comment on a painting. +A comment on a Canvas can target a non-rectangular area. This example uses a [`SvgSelector`][prezi-40-model-SvgSelector] to comment on a painting. ```json { @@ -1952,13 +1983,13 @@ A comment on a Canvas can target a non-rectangular area. This example uses a `S } ``` -Annotations may alternately use a different type of Selector, called a `WktSelector`, to align the Annotation to a target region within a Canvas or Scene. +Annotations may alternately use a different type of Selector, called a [`WktSelector`][prezi-40-model-WktSelector], to align the Annotation to a target region within a Canvas or Scene. ### A comment about 3D sculpture A commenting annotation can also reference a Content Resource, such as a Model, within a Scene. This is accomplished by targeting the annotation that paints the resource into the Scene. In this example, the commenting annotation targets an annotation that paints a model of a portrait bust into a scene. -In some cases it is desirable to influence the client's positioning of the commenting annotation when rendered. This may be done to ensure that the annotation does not hide key visual elements or to ensure that the annotation itself is not obscured by resources painted in the Container, such as 3D models. In these cases, the `position` property may be used to define the position where a TextualBody should be rendered. The example shows a `position` that places the annotation at a specific coordinate within the Scene. The position is a `SpecificResource` that requires a `source` and `selector`. +In some cases it is desirable to influence the client's positioning of the commenting annotation when rendered. This may be done to ensure that the annotation does not hide key visual elements or to ensure that the annotation itself is not obscured by resources painted in the Container, such as 3D models. In these cases, the [`position`][prezi-40-model-position] property may be used to define the position where a TextualBody should be rendered. The example shows a [`position`][prezi-40-model-position] that places the annotation at a specific coordinate within the Scene. The position is a [`SpecificResource`][prezi-40-model-SpecificResource] that requires a [`source`][prezi-40-model-source] and `selector`. ```jsonc { @@ -2037,7 +2068,7 @@ In some cases it is desirable to influence the client's positioning of the comme @@ -2045,7 +2076,7 @@ It is important to be able to position the textual body of an annotation within An Annotation with the motivation `linking` is used to create links between resources, both within the Manifest or to external content on the web, including other IIIF resources. Examples include linking to the continuation of an article in a digitized newspaper in a different Canvas, or to an external web page that describes the diagram in the Canvas. A client typically renders the links as clickable "Hotspots" - but can offer whatever accessible affordance as appropriate. The user experience of whether the linked resource is opened in a new tab, new window or by replacing the current view is up to the implementation. -The resource the user should be taken to is the `body` of the annotation, and the region of the Container that the user clicks or otherwise activates to follow the link is the `target`: +The resource the user should be taken to is the [`body`][prezi-40-model-body] of the annotation, and the region of the Container that the user clicks or otherwise activates to follow the link is the [`target`][prezi-40-model-target]: ```jsonc { @@ -2067,18 +2098,18 @@ The resource the user should be taken to is the `body` of the annotation, and th Sometimes it is necessary to modify the state of resources. Annotations with the motivation `activating` are referred to as _activating_ annotations, and are used to change resources from their initial state defined in the Manifest or from their current state. They allow IIIF to be used for interactive exhibitions, storytelling, digital dioramas and other interactive applications beyond simply conveying a set of static resources in a Container. -The `target` of the activating annotation is the resource that triggers an action. This could be a commenting annotation, for which a user might click a corresponding UI element. In other scenarios the `target` could be the painting annotation of a 3D model, or an annotation that targets part of a model, or a region of a Canvas, or a point or segment of a Timeline, or any other annotation that a user could interact with (in whatever manner) to trigger an event. Even a volume of space in a Scene or an extent of time in a Container with `duration` could be the `target`. When that volume or time extent is triggered - which might be the user entering that volume or the playhead reaching the extent independently of user interaction - something happens. +The [`target`][prezi-40-model-target] of the activating annotation is the resource that triggers an action. This could be a commenting annotation, for which a user might click a corresponding UI element. In other scenarios the [`target`][prezi-40-model-target] could be the painting annotation of a 3D model, or an annotation that targets part of a model, or a region of a Canvas, or a point or segment of a Timeline, or any other annotation that a user could interact with (in whatever manner) to trigger an event. Even a volume of space in a Scene or an extent of time in a Container with [`duration`][prezi-40-model-duration] could be the [`target`][prezi-40-model-target]. When that volume or time extent is triggered - which might be the user entering that volume or the playhead reaching the extent independently of user interaction - something happens. This specification does not define how a client indicates to a user that a resource is able to be interacted with. -The body of the activating annotation is always an ordered list of Specific Resources, each with `source` and `action` properties. The `source` is the resource to be acted upon in some way, and the `action` property is an ordered list of named actions to perform on that resource. Valid values include "show", "hide", "enable", "disable", "start", "stop", "reset" and "select". +The body of the activating annotation is always an ordered list of Specific Resources, each with [`source`][prezi-40-model-source] and [`action`][prezi-40-model-action] properties. The [`source`][prezi-40-model-source] is the resource to be acted upon in some way, and the [`action`][prezi-40-model-action] property is an ordered list of named actions to perform on that resource. Valid values include "show", "hide", "enable", "disable", "start", "stop", "reset" and "select". -Activating annotations are provided in a Container's `annotations` property. They can be mixed in with the commenting (or other interactive annotations) they target, or they can be in a separate Annotation Page. The client should evaluate all of the enabled activating annotations it can find. +Activating annotations are provided in a Container's [`annotations`][prezi-40-model-annotations] property. They can be mixed in with the commenting (or other interactive annotations) they target, or they can be in a separate Annotation Page. The client should evaluate all of the enabled activating annotations it can find. ### Hiding and disabling resources -A resource with the `behavior` value "hidden" is not rendered by the client. A resource with the `behavior` value "disabled" is not available for user interaction and does not trigger any actions. The following example is a light switch that can be toggled on and off using activating annotations that result in these behaviors being applied or removed. It demonstrates a painted resource - a light - being shown and hidden, and activating annotations being enabled and disabled. Both of these are done by the client processing the action properties of the activating annotation bodies: the actions "show" and "hide" remove or add the behavior value "hidden", and the actions "enable" and "disable" modify the behavior value "disabled". +A resource with the [`behavior`][prezi-40-model-behavior] value "hidden" is not rendered by the client. A resource with the [`behavior`][prezi-40-model-behavior] value "disabled" is not available for user interaction and does not trigger any actions. The following example is a light switch that can be toggled on and off using activating annotations that result in these behaviors being applied or removed. It demonstrates a painted resource - a light - being shown and hidden, and activating annotations being enabled and disabled. Both of these are done by the client processing the action properties of the activating annotation bodies: the actions "show" and "hide" remove or add the behavior value "hidden", and the actions "enable" and "disable" modify the behavior value "disabled". ```jsonc { @@ -2207,9 +2238,9 @@ A resource with the `behavior` value "hidden" is not rendered by the client. A r } ``` -* Initially, a model of a light switch is painted into the Scene. A PointLight is also painted, but with the `behavior` "hidden", which means it is inactive (i.e., off). A commenting annotation with the text "Click the switch to turn the light on or off" targets the light switch. An activating annotation targets the painting annotation that paints the switch, so that user interaction with the light switch will trigger the activating annotation. This activating annotation has a `body` property with three Specific Resources. The first enables the "off" activating annotation, the second shows the PointLight, and the last disables the activating annotation _itself_ - this activating annotation can no longer be activated by a user interaction with the light switch model (its `target`). -* A further activating annotation has the opposite effect. Initially this has the `behavior` "disabled" - which means it is inactive. It also targets the painting annotation, but has no effect while disabled. -* When the user interacts with the light switch model, the client processes any activating annotations that target it and are enabled. In this case, the first activating annotation is triggered because while both target the switch, only the first is enabled. This activation shows the light (i.e., removes its "hidden" `behavior` and therefore turning it on) and enables the other activating annotation, and disables itself. +* Initially, a model of a light switch is painted into the Scene. A PointLight is also painted, but with the [`behavior`][prezi-40-model-behavior] "hidden", which means it is inactive (i.e., off). A commenting annotation with the text "Click the switch to turn the light on or off" targets the light switch. An activating annotation targets the painting annotation that paints the switch, so that user interaction with the light switch will trigger the activating annotation. This activating annotation has a [`body`][prezi-40-model-body] property with three Specific Resources. The first enables the "off" activating annotation, the second shows the PointLight, and the last disables the activating annotation _itself_ - this activating annotation can no longer be activated by a user interaction with the light switch model (its [`target`][prezi-40-model-target]). +* A further activating annotation has the opposite effect. Initially this has the [`behavior`][prezi-40-model-behavior] "disabled" - which means it is inactive. It also targets the painting annotation, but has no effect while disabled. +* When the user interacts with the light switch model, the client processes any activating annotations that target it and are enabled. In this case, the first activating annotation is triggered because while both target the switch, only the first is enabled. This activation shows the light (i.e., removes its "hidden" [`behavior`][prezi-40-model-behavior] and therefore turning it on) and enables the other activating annotation, and disables itself. * If the user clicks the light again, the client again processes any activating annotations that target it and are not disabled. This time the second activating annotation is the enabled one - and it hides the light (turning it off) and disables itself, and enables the first activating annotation again. * Subsequent clicks simply alternate between these two states, indefinitely. @@ -2218,7 +2249,7 @@ A resource with the `behavior` value "hidden" is not rendered by the client. A r Sometimes a model file has inbuilt animations. While a description of these is outside the scope of IIIF, because it is 3D-implementation-specific, as long as there is a way to refer to a model's animation(s) by name, we can connect the animation to IIIF resources. -This pattern is also achieved with activating annotations, except that the body of the activating annotation references a _named animation_ in the model. The `body` is a Specific Resource, where the `source` is the Painting Annotation that paints the model, and the `selector` is of type `AnimationSelector` with the `value` being a string that corresponds to the name of the animation in the model. +This pattern is also achieved with activating annotations, except that the body of the activating annotation references a _named animation_ in the model. The [`body`][prezi-40-model-body] is a Specific Resource, where the [`source`][prezi-40-model-source] is the Painting Annotation that paints the model, and the `selector` is of type [`AnimationSelector`][prezi-40-model-AnimationSelector] with the `value` being a string that corresponds to the name of the animation in the model. The format of the `value` string is implementation-specific, and will depend on how different 3D formats support addressing of animations within models. The same model can be painted multiple times into the scene, and you might want to activate only one painted instance of the model's animation, thus we need to refer to the annotation that paints the model, not the model directly. @@ -2447,7 +2478,7 @@ It is possible to associate a particular camera with a particular commenting ann } ``` -The client will render a UI that presents the two commenting annotations in some form and allows the user to navigate between them. An active Camera is not provided (while there is a Camera in the Scene it has `behavior` "hidden", i.e., it is inactive: not usable). The commenting annotations are ordered; while the user might explore them freely in the Scene they might also go "forward" from the first to the second commenting annotation and "back" to the first from the second. In either case the above example instructs the client to activate the Camera when the user interacts with the comment. The user is free to move away but any interaction with that comment will bring them back to the specific viewpoint. (forward ref to chains of activation example) +The client will render a UI that presents the two commenting annotations in some form and allows the user to navigate between them. An active Camera is not provided (while there is a Camera in the Scene it has [`behavior`][prezi-40-model-behavior] "hidden", i.e., it is inactive: not usable). The commenting annotations are ordered; while the user might explore them freely in the Scene they might also go "forward" from the first to the second commenting annotation and "back" to the first from the second. In either case the above example instructs the client to activate the Camera when the user interacts with the comment. The user is free to move away but any interaction with that comment will bring them back to the specific viewpoint. (forward ref to chains of activation example) Default camera: @@ -2493,21 +2524,21 @@ Repeat full example? no, link to external. Activating annotations add explicit mechanisms for interactive user experiences such as guided viewing and storytelling. A narrative might comprise an Annotation Page of `commenting` annotations that target different parts of the Container, for example a guided tour of a painting or a map. For a Canvas or Timeline it is usually sufficient to leave the interactivity to the client; the fact that comments target different extents implies the client must offer some affordance for those comments (typically the user can click each one), and in response the client will move the current play point of the Timeline to the commenting annotation target, or pan and zoom the viewport to show the relevant part of an image. For 3D this may not be enough; a particular comment may only make sense from a certain viewpoint (i.e., Camera), or different steps of the story require different Lights to be active. -In a storytelling or exhibition scenario, the non-painting `annotations` might be carrying informative text, or even rich HTML bodies. They can be considered to be _steps_ in the story. The use of activating annotations allows a precise storytelling experience to be specified, including: +In a storytelling or exhibition scenario, the non-painting [`annotations`][prezi-40-model-annotations] might be carrying informative text, or even rich HTML bodies. They can be considered to be _steps_ in the story. The use of activating annotations allows a precise storytelling experience to be specified, including: - providing a specific viewpoint for each step of the narrative (or even a choice of viewpoints) - modifying the lighting of the Scene for each step, for example shining a spotlight on a point of interest - hiding models in the Scene at a particular step - showing additional models at a particular step -All the annotations referred to by the activating annotations' `target` and `body` properties are already present in the Scene from the beginning. Initially, many of them may have the behavior `hidden`, invisible until activated. +All the annotations referred to by the activating annotations' [`target`][prezi-40-model-target] and [`body`][prezi-40-model-body] properties are already present in the Scene from the beginning. Initially, many of them may have the behavior `hidden`, invisible until activated. Interactive examples are provided as recipes in the [IIIF Cookbook](link). #### The `sequence` behavior -While all Annotation Page `items` are inherently ordered, an Annotation Page with the `behavior` "sequence" is explicitly a narrative, and clients should prevent (dissuade) users from jumping about - the annotations, and the effects of them _activating_ other contents of the Container, are intended to be experienced in order and individually. Normally, a client might display all the comments in an Annotation Page in a sidebar so they are all visible in the UI, but for an Annotation Page with `behavior` "sequence" only show the currently active annotation text, and next and previous UI. +While all Annotation Page [`items`][prezi-40-model-items] are inherently ordered, an Annotation Page with the [`behavior`][prezi-40-model-behavior] "sequence" is explicitly a narrative, and clients should prevent (dissuade) users from jumping about - the annotations, and the effects of them _activating_ other contents of the Container, are intended to be experienced in order and individually. Normally, a client might display all the comments in an Annotation Page in a sidebar so they are all visible in the UI, but for an Annotation Page with [`behavior`][prezi-40-model-behavior] "sequence" only show the currently active annotation text, and next and previous UI. @@ -2515,13 +2546,13 @@ While all Annotation Page `items` are inherently ordered, an Annotation Page wit In many cases, the dimensions of a Canvas, or the pixel density of a photograph, are not necessarily related to a real-world size of the object they show. A large wall painting and a tiny miniature may both be conveyed by 20 megapixel source images on a 4000 by 3000 unit Canvas. But it can be important to know how big something is or if there is a relationship between pixel density and physical length, especially when comparing objects together. Each pixel in an image may correspond precisely to a physical area, allowing measurement of real world distances from the image. A scanned 3D model may be constructed such that each 3D coordinate unit corresponds to one meter of physical distance. -The `spatialScale` property of a Canvas or Scene provides a corresponding real-world scale for a unit of the Canvas or Scene coordinate system, allowing clients to provide scale information to users, for example by an on-screen virtual ruler. In a 2-up viewer, a client could scale two views to convey the true relative sizes of two objects. +The [`spatialScale`][prezi-40-model-spatialScale] property of a Canvas or Scene provides a corresponding real-world scale for a unit of the Canvas or Scene coordinate system, allowing clients to provide scale information to users, for example by an on-screen virtual ruler. In a 2-up viewer, a client could scale two views to convey the true relative sizes of two objects. -The value of `spatialScale` is a `UnitValue` (ref) that has as a value a length unit. This specification defines only one length unit, "m", i.e., meters, though others may be defined externally as an [extension][prezi30-ldce]. If source size metadata is machine readable (or parse-able) in other measurement systems (e.g., feet and inches) then it should be converted to meters for use in `spatialScale`. Publishers may wish to present the original given measure (e.g., from catalogue metadata) in a `metadata` field for context. +The value of [`spatialScale`][prezi-40-model-spatialScale] is a `UnitValue` (ref) that has as a value a length unit. This specification defines only one length unit, "m", i.e., meters, though others may be defined externally as an [extension][prezi30-ldce]. If source size metadata is machine readable (or parse-able) in other measurement systems (e.g., feet and inches) then it should be converted to meters for use in [`spatialScale`][prezi-40-model-spatialScale]. Publishers may wish to present the original given measure (e.g., from catalogue metadata) in a [`metadata`][prezi-40-model-metadata] field for context. -The Presentation API also offers a corresponding `temporalScale` property for the `duration` dimension of a Container, when 1 second in the Container does not correspond to 1 second of real time. This is useful for speeded-up or slowed-down audio or video. +The Presentation API also offers a corresponding [`temporalScale`][prezi-40-model-temporalScale] property for the [`duration`][prezi-40-model-duration] dimension of a Container, when 1 second in the Container does not correspond to 1 second of real time. This is useful for speeded-up or slowed-down audio or video. -An extreme example of both physical dimension properties together is a Canvas showing an animation of continental drift over the course of Earth history, where the spatialScale could convey that each Canvas unit is several thousand meters, and each second of the Canvas `duration` is several million years. +An extreme example of both physical dimension properties together is a Canvas showing an animation of continental drift over the course of Earth history, where the spatialScale could convey that each Canvas unit is several thousand meters, and each second of the Canvas [`duration`][prezi-40-model-duration] is several million years. @@ -2614,9 +2645,9 @@ Clients are only expected to follow links to Presentation API resources. Unlike The format for all responses is JSON, as described above. It is good practice for all resources with an HTTP(S) URI to provide their description when the URI is dereferenced. If a resource is [referenced][prezi30-terminology] within a response, rather than being [embedded][prezi30-terminology], then it _MUST_ be able to be dereferenced. -If the server receives a request with an `Accept` header, it _SHOULD_ respond following the rules of [content negotiation][org-rfc-7231-conneg]. Note that content types provided in the `Accept` header of the request _MAY_ include parameters, for example `profile` or `charset`. +If the server receives a request with an `Accept` header, it _SHOULD_ respond following the rules of [content negotiation][org-rfc-7231-conneg]. Note that content types provided in the `Accept` header of the request _MAY_ include parameters, for example [`profile`][prezi-40-model-profile] or `charset`. -If the request does not include an `Accept` header, the HTTP `Content-Type` header of the response _SHOULD_ have the value `application/ld+json` (JSON-LD) with the `profile` parameter given as the context document: `http://iiif.io/api/presentation/4/context.json`. +If the request does not include an `Accept` header, the HTTP `Content-Type` header of the response _SHOULD_ have the value `application/ld+json` (JSON-LD) with the [`profile`][prezi-40-model-profile] parameter given as the context document: `http://iiif.io/api/presentation/4/context.json`. {% include api/code_header.html %} ``` @@ -2624,7 +2655,7 @@ Content-Type: application/ld+json;profile="http://iiif.io/api/presentation/4/con ``` {: .urltemplate} -If the `Content-Type` header `application/ld+json` cannot be generated due to server configuration details, then the `Content-Type` header _SHOULD_ instead be `application/json` (regular JSON), without a `profile` parameter. +If the `Content-Type` header `application/ld+json` cannot be generated due to server configuration details, then the `Content-Type` header _SHOULD_ instead be `application/json` (regular JSON), without a [`profile`][prezi-40-model-profile] parameter. {% include api/code_header.html %} ``` @@ -2642,7 +2673,7 @@ Responses _SHOULD_ be compressed by the server as there are significant performa (new section) -`provides` +[`provides`][prezi-40-model-provides] `provides[]` @@ -2674,3 +2705,5 @@ The key words _MUST_, _MUST NOT_, _REQUIRED_, _SHALL_, _SHALL NOT_, _SHOULD_, _S ## Acknowledgements ## Change Log + +{% include links.md %} diff --git a/source/presentation/4.0/model.md b/source/presentation/4.0/model.md index d958fac1b..91e2c600e 100644 --- a/source/presentation/4.0/model.md +++ b/source/presentation/4.0/model.md @@ -52,7 +52,14 @@ __Previous Version:__ [3.0][prezi30] ---- # IIIF Presentation API Data Model - +