Skip to content

Commit

Permalink
Add docs, tests, license, attributions
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Joel committed Mar 14, 2019
1 parent 1d2fbde commit f5559bf
Show file tree
Hide file tree
Showing 19 changed files with 561 additions and 42 deletions.
166 changes: 166 additions & 0 deletions examples/animation.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<!--
/*
* Copyright 2018 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<!DOCTYPE html>
<html lang="en">
<head>
<title>&lt;model-viewer&gt; Lighting &amp; Environment</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no,
minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" href="styles/examples.css" rel="stylesheet" />
<link rel="shortcut icon" type="image/png" href="assets/favicon.png"/>
<script src="../node_modules/resize-observer-polyfill/dist/ResizeObserver.js"></script>

<!-- The following libraries and polyfills are recommended to maximize browser support -->

<!-- 🚨 REQUIRED: Web Components polyfill to support Edge and Firefox < 63 -->
<script src="../node_modules/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script>

<!-- 💁 OPTIONAL: Intersection Observer polyfill for better performance in Safari and IE11 -->
<script src="../node_modules/intersection-observer/intersection-observer.js"></script>

<!-- 💁 OPTIONAL: Resize Observer polyfill improves resize behavior in non-Chrome browsers -->
<script src="../node_modules/resize-observer-polyfill/dist/ResizeObserver.js"></script>

<!-- 💁 OPTIONAL: Fullscreen polyfill is required for experimental AR features in Canary -->
<script src="../node_modules/fullscreen-polyfill/dist/fullscreen.polyfill.js"></script>

<!-- 💁 OPTIONAL: Include prismatic.js for Magic Leap support -->
<!--<script src="../node_modules/@magicleap/prismatic/prismatic.min.js"></script>-->

</head>
<body class="multiple-samples">

<div id="header">
<a class="icon-button icon-return" href="../index.html"></a>
<a class="icon-github icon-button" href="https://github.com/GoogleWebComponents/model-viewer/blob/master/examples/lighting-and-environment.html"></a>
</div>

<div class="center intro">
<h2>Animation</h2>
<h4>This page showcases how you can control models with animations</h4>
</div>

<div class="sample">
<div class="demo" id="demo-container-1"></div>
<div class="content">
<div class="wrapper">
<div class="index">1</div>
<h2>Activate animations with the
<span class="attribute">animated</span> attribute</h2>
<example-snippet stamp-to="demo-container-1" highlight-as="html">
<template>
<model-viewer
controls
animated
src="assets/RobotExpressive.glb"
background-color="#622dcf"
exposure="2"
environment-intensity="0"
alt="An animated 3D model of a robot"></model-viewer>
</template>
</example-snippet>
</div>
</div>
</div>

<div class="sample">
<div class="demo" id="demo-container-2"></div>
<div class="content">
<div class="wrapper">
<div class="index">2</div>
<h2>Select a specific animation with <span class="attribute">animation-name</span></h2>
<example-snippet stamp-to="demo-container-2" highlight-as="html">
<template>
<model-viewer
controls
animated
animation-name="Running"
src="assets/RobotExpressive.glb"
background-color="#25997c"
exposure="2"
environment-intensity="0"
alt="An animated 3D model of a robot"></model-viewer>
</template>
</example-snippet>
</div>
</div>
</div>

<div class="sample">
<div class="demo" id="demo-container-3"></div>
<div class="content">
<div class="wrapper">
<div class="index">3</div>
<h2>Animations crossfade when you change them</h2>
<example-snippet stamp-to="demo-container-3" highlight-as="html">
<template>
<model-viewer
id="xfade-demo"
controls
animated
animation-name="Running"
src="assets/RobotExpressive.glb"
background-color="#622dcf"
exposure="2"
environment-intensity="0"
alt="An animated 3D model of a robot"></model-viewer>
<script>
(() => {
const modelViewer = document.querySelector('#xfade-demo');

self.setInterval(() => {
modelViewer.animationName = modelViewer.animationName === 'Running' ?
'Wave' : 'Running';
}, 1500.0);
})();
</script>
</template>
</example-snippet>
</div>
</div>
</div>

<div class="footer">
<div class="attribution">
RobotExpressive by <a href="https://www.patreon.com/quaternius">Tomás Laulhé</a>,
licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>
(<a href="https://github.com/mrdoob/three.js/tree/dev/examples/models/gltf/RobotExpressive">source</a>)
</div>
<div class="copyright">©Copyright 2018 Google Inc. Licensed under the Apache License 2.0.</div>

<script src="./scripts/helpers.js"></script>

<!-- Documentation-specific dependencies: -->
<script type="module"
src="./built/dependencies.js">
</script>
<script nomodule
src="./built/dependencies-legacy.js">
</script>

<!-- Loads <model-viewer> only on modern browsers: -->
<script type="module"
src="../dist/model-viewer.js">
</script>

<!-- Loads <model-viewer> only on old browsers like IE11: -->
<script nomodule
src="../dist/model-viewer-legacy.js">
</script>
</body>
</html>
Binary file added examples/assets/RobotExpressive.glb
Binary file not shown.
6 changes: 6 additions & 0 deletions examples/assets/attributions.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ licensed under <a href="https://hdrihaven.com/p/license.php">CC0</a>
(<a href="https://hdrihaven.com/hdri/?h=whipple_creek_regional_park_04">source</a>)
Originally in HDR format

## RobotExpressive

RobotExpressive by <a href="https://www.patreon.com/quaternius">Tomás Laulhé</a>,
licensed under <a href="https://creativecommons.org/publicdomain/zero/1.0/">CC0</a>
(<a href="https://github.com/mrdoob/three.js/tree/dev/examples/models/gltf/RobotExpressive">source</a>)

## small_hangar_01

small_hangar_01_1k.jpg by <a href="https://hdrihaven.com">HDRI Haven</a>
Expand Down
33 changes: 32 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
<example-snippet stamp-to="demo-container" highlight-as="html">
<template>
<model-viewer
src="examples/assets/Horse.glb"
src="examples/assets/Astronaut.glb"
alt="A 3D model of an astronaut"
controls
auto-rotate
Expand Down Expand Up @@ -136,6 +136,10 @@ <h3 class="grouping-title">EXAMPLES</h3>
<a href="examples/rendering-showcase.html"><h4>Rendering Showcase</h4></a>
<p>Demos of &lt;model-viewer&gt; rendering quality and stress tests</p>
</li>
<li>
<a href="examples/animation.html"><h4>Animation</h4></a>
<p>Use &lt;model-viewer&gt; to show off your animated models</p>
</li>
</ul>

<h3 class="grouping-title">ATTRIBUTES</h3>
Expand All @@ -149,6 +153,27 @@ <h4>src<a href="#required-for-display">*</a></h4>
<h4>alt</h4>
<p>Configures the model with custom text that will be used to describe the model to viewers who use a screen reader or otherwise depend on additional semantic context to understand what they are viewing.</p>
</li>
<li>
<h4>animated</h4>
<p>Enables animations. If a model has animations, they will
automatically begin to play when this attribute is set (or when the
property is set to true). If no animation-name is specified, plays
the first animation.</p>
</li>
<li>
<h4>animation-name</h4>
<p>Selects an animation to play by name when the
&lt;model-viewer&gt; is configured to be animated. If no
animation-name is specified, &lt;model-viewer&gt; always picks the
first animation it finds in the model.</p>
</li>
<li>
<h4>animation-crossfade-duration</h4>
<p>When the current animation is changed, &lt;model-viewer&gt;
automatically crossfades between the previous and next animations.
This attribute controls how long the crossfade is in milliseconds.
Defaults to 300.</p>
</li>
<li>
<h4>auto-rotate</h4>
<p>Enables the auto rotation of the model.</p>
Expand Down Expand Up @@ -242,6 +267,12 @@ <h4>environment-change</h4>
<h4>load</h4>
<p>Fired when a model is loaded. Can fire multiple times per <span class="attribute">&lt;model-viewer&gt;</span> if the src attribute is changed.</p>
</li>
<li>
<h4>poster-visibility</h4>
<p>This event is fired when the visiblity of the poster image
changes. The current visibility state can be read from the
<span class="attribute">event.detail.visible</span> property</p>
</li>
<li>
<h4>preload</h4>
<p>When preload is enabled this event is fired when preloading is done.</p>
Expand Down
15 changes: 15 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// NOTE(cdata): The HAS_WEBXR_* constants can be enabled in Chrome by turning on
// the appropriate flags. However, just because we have the API does not
// guarantee that AR will work.
Expand Down
26 changes: 26 additions & 0 deletions src/features/animation.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/*
* Copyright 2019 Google Inc. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import {property} from 'lit-element';

import ModelViewerElementBase, {$needsRender, $scene, $tick, $updateSource} from '../model-viewer-base.js';
Expand Down Expand Up @@ -30,6 +45,17 @@ export const AnimationMixin =
this[$updateModelLoadsPromise]();
}

/**
* Returns an array
*/
get availableAnimations(): Array<string> {
if (this.loaded) {
return (this as any)[$scene].model.animationNames;
}

return [];
}

/**
* Creates a promise that resolves when a model is loaded. The
* promise resolves immediately if there is currently a loaded
Expand Down
47 changes: 32 additions & 15 deletions src/features/loading.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,14 @@ export const LoadingMixin = (ModelViewerElement) => {
}

get loaded() {
return super.loaded || (this.src && loader.hasFinishedLoading(this.src));
return super.loaded ||
(this.src && CachingGLTFLoader.hasFinishedLoading(this.src));
}

constructor() {
super();

this[$posterHidden] = false;
this[$posterHidden] = true;
this[$preloadAnnounced] = false;

// Used to determine whether or not to display a poster image or
Expand Down Expand Up @@ -116,22 +117,28 @@ export const LoadingMixin = (ModelViewerElement) => {
[$hidePoster]() {
const posterElement = this[$posterElement];
const posterOpacity = self.getComputedStyle(posterElement).opacity;
const onPosterHidden = () => {
requestAnimationFrame(() => {
console.warn('POSTER HIDDEN');
this.dispatchEvent(
new CustomEvent('poster-visibility', {detail: {visible: false}}));
this[$canvas].focus();
});
};

this[$posterHidden] = true;

if (posterOpacity > 0) {
// NOTE(cdata): The canvas cannot receive focus until the poster has
// been completely hidden:
posterElement.addEventListener('transitionend', () => {
this[$canvas].focus();
}, {once: true});
posterElement.addEventListener(
'transitionend', onPosterHidden, {once: true});
} else {
// NOTE(cdata): Depending on timing, the opacity may already be 0, in
// which case we will never receive a transitionend event. So, just
// focus on the next animation frame:
requestAnimationFrame(() => {
this[$canvas].focus();
});
onPosterHidden();
// requestAnimationFrame(onPosterHidden);
}

posterElement.classList.remove('show');
Expand All @@ -146,6 +153,9 @@ export const LoadingMixin = (ModelViewerElement) => {
posterElement.tabIndex = 1;

this[$posterHidden] = false;

this.dispatchEvent(
new CustomEvent('poster-visibility', {detail: {visible: true}}));
}

[$onClick]() {
Expand All @@ -167,7 +177,7 @@ export const LoadingMixin = (ModelViewerElement) => {

get[$shouldDismissPoster]() {
return !this.poster ||
(loader.hasFinishedLoading(this.src) &&
(CachingGLTFLoader.hasFinishedLoading(this.src) &&
(this.revealWhenLoaded || this[$userDismissedPoster]));
}

Expand Down Expand Up @@ -195,16 +205,23 @@ export const LoadingMixin = (ModelViewerElement) => {
this[$preloadAnnounced] = false;
}

const preloaded = loader.hasFinishedLoading(this.src);
const preloaded = CachingGLTFLoader.hasFinishedLoading(this.src);

if (this[$shouldAttemptPreload]) {
const detail = {url: this.src};

if (preloaded) {
this.dispatchEvent(new CustomEvent('preload'));
this.dispatchEvent(new CustomEvent('preload', {detail}));
} else {
loader.preload(this.src).then(() => {
this.dispatchEvent(new CustomEvent('preload'));
this.requestUpdate();
});
loader.preload(this.src)
.then(() => {
this.dispatchEvent(new CustomEvent('preload', {detail}));
this.requestUpdate();
})
.catch((error) => {
this.dispatchEvent(new CustomEvent(
'error', {detail: {type: 'preload', sourceError: error}}));
});
}

this[$preloadAnnounced] = true;
Expand Down
Loading

0 comments on commit f5559bf

Please sign in to comment.