Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Unified Diff: third_party/polymer/components/core-animated-pages/core-animated-pages.html

Issue 582873003: Polymer elements added to third_party/polymer. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/polymer/components/core-animated-pages/core-animated-pages.html
diff --git a/third_party/polymer/components/core-animated-pages/core-animated-pages.html b/third_party/polymer/components/core-animated-pages/core-animated-pages.html
new file mode 100644
index 0000000000000000000000000000000000000000..bef086d58a753c1da031779f7e81f8e93a7651f7
--- /dev/null
+++ b/third_party/polymer/components/core-animated-pages/core-animated-pages.html
@@ -0,0 +1,427 @@
+<link href="../core-selector/core-selector.html" rel="import">
+
+<link href="transitions/hero-transition.html" rel="import">
+<link href="transitions/cross-fade.html" rel="import">
+
+<!--
+
+`core-animated-pages` selects one of its children "pages" to show and runs a transition
+when switching between them. The transitions are designed to be pluggable, and can
+accept any object that is an instance of a `core-transition-pages`. Transitions to run
+are specified in the `transitions` attribute as a space-delimited string of `id`s of
+transition elements. Several transitions are available with `core-animated-pages` by
+default, including `hero-transition`, `cross-fade`, and `tile-cascade`.
+
+Example:
+
+ <style>
+ #hero1 {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 300px;
+ height: 300px;
+ background-color: orange;
+ }
+ #hero2 {
+ position: absolute;
+ top: 200px;
+ left: 300px;
+ width: 300px;
+ height: 300px;
+ background-color: orange;
+ }
+ #bottom1, #bottom2 {
+ position: absolute;
+ bottom: 0;
+ top: 0;
+ left: 0;
+ height: 50px;
+ }
+ #bottom1 {
+ background-color: blue;
+ }
+ #bottom2 {
+ background-color: green;
+ }
+ </style>
+ // hero-transition and cross-fade are declared elsewhere
+ <core-animated-pages transitions="hero-transition cross-fade">
+ <section id="page1">
+ <div id="hero1" hero-id="hero" hero></div>
+ <div id="bottom1" cross-fade></div>
+ </section>
+ <section id="page2">
+ <div id="hero2" hero-id="hero" hero></div>
+ <div id="bottom2" cross-fade></div>
+ </section>
+ </core-animated-pages>
+
+In the above example, two transitions (`hero-transition` and `cross-fade`) are run when switching
+between `page1` and `page2`. `hero-transition` transforms elements with the same `hero-id` such
+that they appear to be shared across different pages. `cross-fade` fades out the elements marked
+`cross-fade` in the outgoing page, and fades in those in the incoming page. See the individual
+transition's documentation for specific details.
+
+Finding elements to transition
+------------------------------
+
+In general, a transition is applied to elements marked with a certain attribute. For example,
+`hero-transition` applies the transition on elements with the `hero` and `hero-id` attribute.
+Among the transitions included with `core-animated-pages`, script-based transitions such as
+`hero-transition` generally look for elements up to one level of shadowRoot from the
+`core-animated-pages` element, and CSS-based transitions such as `cross-fade` look for elements
+within any shadowRoot within the `core-animated-pages` element. This means you can use
+custom elements as pages and mark elements in their shadowRoots as heroes, or mark
+elements in deeper shadowRoots with other transitions.
+
+Example:
+
+ <polymer-element name="x-el" noscript>
+ <template>
+ <style>
+ #hero {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 50px;
+ height: 300px;
+ background-color: blue;
+ }
+ </style>
+ <div id="hero" hero-id="bar" hero></div>
+ </template>
+ </polymer-element>
+
+ <polymer-element name="x-page-1" noscript>
+ <template>
+ <style>
+ #hero1 {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 300px;
+ height: 300px;
+ background-color: orange;
+ }
+ </style>
+ <div id="hero1" hero-id="foo" hero></div>
+ <div id="hero2" hero-id="bar" hero></div>
+ </template>
+ </polymer-element>
+
+ <polymer-element name="x-page-2" noscript>
+ <template>
+ <style>
+ #hero1 {
+ position: absolute;
+ top: 200px;
+ left: 300px;
+ width: 300px;
+ height: 300px;
+ background-color: orange;
+ }
+ #hero2 {
+ background-color: blue;
+ height: 150px;
+ width: 400px;
+ }
+ </style>
+ // The below element is one level of shadow from the core-animated-pages and will
+ // be transitioned.
+ <div id="hero1" hero-id="foo" hero></div>
+ // The below element contains a hero inside its shadowRoot making it two levels away
+ // from the core-animated-pages, and will not be transitioned.
+ <x-el></x-el>
+ </template>
+ </polymer-element>
+
+ <core-animated-pages transitions="hero-transition">
+ <x-page-1></x-page-1>
+ <x-page-2></x-page-2>
+ </core-animated-pages>
+
+Note that the container element of the page does not participate in the transition.
+
+ // This does not work
+ <core-animated-pages transitions="cross-fade">
+ <section cross-fade></section>
+ <section cross-fade></section>
+ </core-animated-pages>
+
+ // This works
+ <core-animated-pages transitions="cross-fade">
+ <section>
+ <div cross-fade></div>
+ </section>
+ <section>
+ <div cross-fade></div>
+ </section>
+ </core-animated-pages>
+
+Dynamically setting up transitions
+----------------------------------
+
+An easy way to dynamically set up transitions dynamically is to use property binding on
+the transition attributes.
+
+Example:
+
+ <core-animated-pages selected="{{selected}}">
+ <section id="page1">
+ <div hero-id="hero" hero></div>
+ </section>
+ <section id="page2">
+ <div id="foo" hero-id="hero" hero?="{{selected === 1 || selected === 0}}" cross-fade="{{selected === 2}}"></div>
+ </section>
+ <section id="page3">
+ </section>
+ </core-animated-pages>
+
+In the above example, the "foo" element only behaves as a hero element if transitioning between
+`#page1` and `#page2`. It gets cross-faded when transition to or from `#page3`.
+
+Nesting pages
+-------------
+
+It is possible to nest core-animated-pages elements for organization. Excessive nesting is
+not encouraged, however, since it makes setting up the transition more complex.
+
+To nest core-animated-pages, the page containing the nested core-animated-pages element should
+have a `selectedItem` property bound to the `selectedItem` property of the nested element. This
+will allow the outer core-animated-pages to know which nested page it is actually transitioning
+to.
+
+Example:
+
+ <polymer-element name="nested-page" attributes="selectedItem">
+ <template>
+ <core-animated-pages selectedItem="{{selectedItem}}">
+ ...
+ </core-animated-pages>
+ </template>
+ </polymer-element>
+
+ <core-animated-pages>
+ <section id="page1"></section>
+ <nested-page id="page2"></section>
+ </core-animated-pages>
+
+@element core-animated-pages
+@extends core-selector
+@status beta
+@homepage github.io
+-->
+<!--
+Fired before a page transition occurs. Both pages involved in the transition are visible when
+this event fires. This is useful if there is something the client needs to do when a page becomes
+visible.
+
+@event core-animated-pages-transition-prepare
+-->
+<!--
+Fired when a page transition completes.
+
+@event core-animated-pages-transition-end
+-->
+<polymer-element name="core-animated-pages" extends="core-selector" notap attributes="transitions">
+
+<template>
+
+ <link href="core-animated-pages.css" rel="stylesheet">
+
+ <shadow></shadow>
+
+</template>
+
+<script>
+
+ Polymer({
+
+ eventDelegates: {
+ 'core-transitionend': 'transitionEnd'
+ },
+
+ /**
+ * A space-delimited string of transitions to use when switching between pages in this element.
+ * The strings are `id`s of `core-transition-pages` elements included elsewhere. See the
+ * individual transition's document for specific details.
+ *
+ * @attribute transitions
+ * @type string
+ * @default ''
+ */
+ transitions: '',
+
+ selected: 0,
+
+ /**
+ * The last page selected. This property is useful to dynamically set transitions based
+ * on incoming and outgoing pages.
+ *
+ * @attribute lastSelected
+ * @type Object
+ * @default null
+ */
+ lastSelected: null,
+
+ registerCallback: function() {
+ this.tmeta = document.createElement('core-transition');
+ },
+
+ created: function() {
+ this._transitions = [];
+ this.transitioning = [];
+ },
+
+ transitionsChanged: function() {
+ this._transitions = this.transitions.split(' ');
+ },
+
+ _transitionsChanged: function(old) {
+ if (this._transitionElements) {
+ this._transitionElements.forEach(function(t) {
+ t.teardown(this);
+ }, this);
+ }
+ this._transitionElements = [];
+ this._transitions.forEach(function(transitionId) {
+ var t = this.getTransition(transitionId);
+ if (t) {
+ this._transitionElements.push(t);
+ t.setup(this);
+ }
+ }, this);
+ },
+
+ getTransition: function(transitionId) {
+ return this.tmeta.byId(transitionId);
+ },
+
+ selectionSelect: function(e, detail) {
+ this.updateSelectedItem();
+ // Wait to call applySelection when we run the transition
+ },
+
+ applyTransition: function(src, dst) {
+ if (this.animating) {
+ this.cancelAsync(this.animating);
+ this.animating = null;
+ }
+
+ Platform.flush();
+
+ if (this.transitioning.indexOf(src) === -1) {
+ this.transitioning.push(src);
+ }
+ if (this.transitioning.indexOf(dst) === -1) {
+ this.transitioning.push(dst);
+ }
+ // force src, dst to display
+ src.setAttribute('animate', '');
+ dst.setAttribute('animate', '');
+ //
+ var options = {
+ src: src,
+ dst: dst,
+ easing: 'cubic-bezier(0.4, 0, 0.2, 1)'
+ }
+
+ // fire an event so clients have a chance to do something when the
+ // new page becomes visible but before it draws.
+ this.fire('core-animated-pages-transition-prepare');
+
+ //
+ // prepare transition
+ this._transitionElements.forEach(function(transition) {
+ transition.prepare(this, options);
+ }, this);
+ //
+ // force layout!
+ src.offsetTop;
+
+ //
+ // apply selection
+ this.applySelection(dst, true);
+ this.applySelection(src, false);
+ //
+ // start transition
+ this._transitionElements.forEach(function(transition) {
+ transition.go(this, options);
+ }, this);
+
+ if (!this._transitionElements.length) {
+ this.complete();
+ } else {
+ this.animating = this.async(this.complete.bind(this), null, 5000);
+ }
+ },
+
+ complete: function() {
+ if (this.animating) {
+ this.cancelAsync(this.animating);
+ this.animating = null;
+ }
+
+ this.transitioning.forEach(function(t) {
+ t.removeAttribute('animate');
+ });
+ this.transitioning = [];
+
+ this._transitionElements.forEach(function(transition) {
+ transition.ensureComplete(this);
+ }, this);
+
+ this.fire('core-animated-pages-transition-end');
+ },
+
+ transitionEnd: function(e) {
+ if (this.transitioning.length) {
+ var completed = true;
+ this._transitionElements.forEach(function(transition) {
+ if (!transition.completed) {
+ completed = false;
+ }
+ });
+ if (completed) {
+ this.job('transitionWatch', function() {
+ this.complete();
+ }, 100);
+ }
+ }
+ },
+
+ selectedChanged: function(old) {
+ this.lastSelected = old;
+ this.super(arguments);
+ },
+
+ selectedItemChanged: function(oldItem) {
+ this.super(arguments);
+
+ if (!oldItem) {
+ this.applySelection(this.selectedItem, true);
+ return;
+ }
+
+ if (this.hasAttribute('no-transition') || !this._transitionElements || !this._transitionElements.length) {
+ this.applySelection(oldItem, false);
+ this.applySelection(this.selectedItem, true);
+ return;
+ }
+
+ if (oldItem && this.selectedItem) {
+ // TODO(sorvell): allow bindings to update first?
+ var self = this;
+ Platform.flush();
+ Platform.endOfMicrotask(function() {
+ self.applyTransition(oldItem, self.selectedItem);
+ });
+ }
+ }
+
+ });
+
+</script>
+
+</polymer-element>

Powered by Google App Engine
This is Rietveld 408576698