Created
September 20, 2019 03:53
-
-
Save samselikoff/2cb46731fda02984af357184b6fbea70 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/app/pods/components/animate/component.js b/app/pods/components/animate/component.js | |
new file mode 100644 | |
index 00000000..c959f943 | |
--- /dev/null | |
+++ b/app/pods/components/animate/component.js | |
@@ -0,0 +1,21 @@ | |
+import Component from "@ember/component"; | |
+import { fadeIn } from "ember-animated/motions/opacity"; | |
+import { wait } from "ember-animated"; | |
+import { easeExpOut } from "d3-ease"; | |
+ | |
+export default Component.extend({ | |
+ *fade({ duration, receivedSprites }) { | |
+ receivedSprites.forEach(sprite => { | |
+ sprite.applyStyles({ | |
+ opacity: 0 | |
+ }); | |
+ sprite.moveToFinalPosition(); | |
+ }); | |
+ | |
+ yield wait(duration * 0.5); | |
+ | |
+ receivedSprites.forEach(sprite => { | |
+ fadeIn(sprite, { from: 0, easing: easeExpOut }); | |
+ }); | |
+ } | |
+}); | |
diff --git a/app/pods/components/animate/template.hbs b/app/pods/components/animate/template.hbs | |
new file mode 100644 | |
index 00000000..cc6314b6 | |
--- /dev/null | |
+++ b/app/pods/components/animate/template.hbs | |
@@ -0,0 +1,3 @@ | |
+{{#animated-value @model use=this.fade}} | |
+ {{yield}} | |
+{{/animated-value}} | |
diff --git a/app/pods/components/ui-video-hero/component.js b/app/pods/components/ui-video-hero/component.js | |
index 6eb1283c..f1a60ae7 100644 | |
--- a/app/pods/components/ui-video-hero/component.js | |
+++ b/app/pods/components/ui-video-hero/component.js | |
@@ -1,6 +1,9 @@ | |
import { inject as service } from "@ember/service"; | |
import Component from "@ember/component"; | |
import diffAttrs from "ember-diff-attrs"; | |
+import resize from "ember-animated/motions/resize"; | |
+import move from "ember-animated/motions/move"; | |
+import { easeExpOut } from "d3-ease"; | |
export default Component.extend({ | |
video: null, | |
@@ -11,6 +14,17 @@ export default Component.extend({ | |
metrics: service(), | |
state: service("components/ui-video-hero"), | |
+ *transition({ duration, receivedSprites }) { | |
+ receivedSprites.forEach(sprite => { | |
+ sprite.applyStyles({ | |
+ zIndex: 1 | |
+ }); | |
+ | |
+ resize(sprite, { easing: easeExpOut, duration: duration * 0.5 }); | |
+ move(sprite, { easing: easeExpOut, duration: duration * 0.5 }); | |
+ }); | |
+ }, | |
+ | |
didInsertElement() { | |
this.setProperties({ | |
hasTrackedPlay: false, | |
diff --git a/app/pods/components/ui-video-hero/template.hbs b/app/pods/components/ui-video-hero/template.hbs | |
index 86494dc2..9cb97dc3 100644 | |
--- a/app/pods/components/ui-video-hero/template.hbs | |
+++ b/app/pods/components/ui-video-hero/template.hbs | |
@@ -13,7 +13,11 @@ | |
{{#can-watch-clip clip=video as |canWatch|}} | |
- <div class="bg-true-black"> | |
+ <div class="relative"> | |
+ <Animate @model={{video}}> | |
+ <div class='absolute pin bg-true-black'></div> | |
+ </Animate> | |
+ | |
{{#ui-container style='video gutterless'}} | |
{{#if video.isComingSoon}} | |
@@ -115,16 +119,21 @@ | |
{{! this should be a component that uses the js api }} | |
{{{video.vimeoVideo.embed}}} | |
{{else}} | |
- {{video-player | |
- sources=video.encodes | |
- poster=(img-url video.posterS3Key w=1280) | |
- data-test-id="video-player" | |
- playbackRate=state.playbackRate | |
- did-add-video-element=(action 'setVideoElement') | |
- on-end=(action 'onEnd') | |
- on-play=(action 'onPlay') | |
- on-pause=(action 'onPause') | |
- on-percent-complete=(action 'onPercentComplete')}} | |
+ <AnimatedContainer> | |
+ {{#animated-value video use=this.transition}} | |
+ {{video-player | |
+ sources=video.encodes | |
+ video=video | |
+ poster=(img-url video.posterS3Key w=1280) | |
+ data-test-id="video-player" | |
+ playbackRate=state.playbackRate | |
+ did-add-video-element=(action 'setVideoElement') | |
+ on-end=(action 'onEnd') | |
+ on-play=(action 'onPlay') | |
+ on-pause=(action 'onPause') | |
+ on-percent-complete=(action 'onPercentComplete')}} | |
+ {{/animated-value}} | |
+ </AnimatedContainer> | |
{{/if}} | |
{{/with-features}} | |
@@ -136,9 +145,12 @@ | |
{{/can-watch-clip}} | |
- | |
-{{#if screen.isSmallAndDown}} | |
- {{ui-video-hero/control-bar-collapsible clip=video}} | |
-{{else}} | |
- {{ui-video-hero/control-bar clip=video}} | |
-{{/if}} | |
+<AnimatedContainer> | |
+ <Animate @model={{video}}> | |
+ {{#if screen.isSmallAndDown}} | |
+ {{ui-video-hero/control-bar-collapsible clip=video}} | |
+ {{else}} | |
+ {{ui-video-hero/control-bar clip=video}} | |
+ {{/if}} | |
+ </Animate> | |
+</AnimatedContainer> | |
diff --git a/app/pods/components/video-player/template.hbs b/app/pods/components/video-player/template.hbs | |
index 5f609bea..00aabf11 100644 | |
--- a/app/pods/components/video-player/template.hbs | |
+++ b/app/pods/components/video-player/template.hbs | |
@@ -23,9 +23,11 @@ | |
{{else if isStopped}} | |
- <div class="video-player__play-button"> | |
- {{fa-icon 'play' prefix="fas"}} | |
- </div> | |
+ <Animate @model={{video}}> | |
+ <div class="video-player__play-button"> | |
+ {{fa-icon 'play' prefix="fas"}} | |
+ </div> | |
+ </Animate> | |
{{/if}} | |
diff --git a/app/pods/podcast/components/podcast-card/body/template.hbs b/app/pods/podcast/components/podcast-card/body/template.hbs | |
new file mode 100644 | |
index 00000000..8ec86779 | |
--- /dev/null | |
+++ b/app/pods/podcast/components/podcast-card/body/template.hbs | |
@@ -0,0 +1,22 @@ | |
+<div class='bg-white p-3 xs:px-20px'> | |
+ <div class="flex text-8 text-grey-dark font-semibold leading-normal"> | |
+ <span class="uppercase"> | |
+ {{moment-format episode.publishedAt 'MMMM D, YYYY'}} | |
+ </span> | |
+ <div class="ml-auto"> | |
+ Ep. {{episode.position}} | |
+ </div> | |
+ </div> | |
+ | |
+ {{ui-spacer style='xs'}} | |
+ | |
+ {{#ui-p style='leading-tight bold marginless'}} | |
+ {{episode.title}} | |
+ {{/ui-p}} | |
+ | |
+ {{ui-spacer style='xs'}} | |
+ | |
+ {{#ui-p style='small subtle marginless leading-1.4'}} | |
+ {{truncate episode.description words=14}}... | |
+ {{/ui-p}} | |
+</div> | |
diff --git a/app/pods/podcast/components/podcast-card/image/template.hbs b/app/pods/podcast/components/podcast-card/image/template.hbs | |
new file mode 100644 | |
index 00000000..ace13c9e | |
--- /dev/null | |
+++ b/app/pods/podcast/components/podcast-card/image/template.hbs | |
@@ -0,0 +1,10 @@ | |
+{{#aspect-ratio ratio='16:9'}} | |
+ <div | |
+ class="h-full w-full bg-cover rounded-t" | |
+ style={{html-safe (concat | |
+ 'background-image: url(' | |
+ (img-url episode.posterS3Key w=760) | |
+ ')' | |
+ )}} | |
+ ></div> | |
+{{/aspect-ratio}} | |
diff --git a/app/pods/podcast/components/podcast-card/template.hbs b/app/pods/podcast/components/podcast-card/template.hbs | |
index dabe57e5..d5fdf374 100644 | |
--- a/app/pods/podcast/components/podcast-card/template.hbs | |
+++ b/app/pods/podcast/components/podcast-card/template.hbs | |
@@ -4,39 +4,17 @@ | |
shadow-pickupable hover:shadow-picked-up hover:nudge-u-sm | |
transition rounded overflow-hidden | |
"> | |
- {{#aspect-ratio ratio='16:9'}} | |
- <div | |
- class="h-full w-full bg-cover rounded-t" | |
- style={{html-safe (concat | |
- 'background-image: url(' | |
- (img-url episode.posterS3Key w=760) | |
- ')' | |
- )}} | |
- ></div> | |
- {{/aspect-ratio}} | |
- <div class='bg-white p-3 xs:px-20px'> | |
- <div class="flex text-8 text-grey-dark font-semibold leading-normal"> | |
- <span class="uppercase"> | |
- {{moment-format episode.publishedAt 'MMMM D, YYYY'}} | |
- </span> | |
- <div class="ml-auto"> | |
- Ep. {{episode.position}} | |
- </div> | |
- </div> | |
+ {{#if (has-block)}} | |
+ {{yield (hash | |
+ Image=(component 'podcast/components/podcast-card/image' episode=episode) | |
+ Body=(component 'podcast/components/podcast-card/body' episode=episode) | |
+ )}} | |
+ {{else}} | |
+ <Podcast::Components::PodcastCard::Image @episode={{episode}} /> | |
+ <Podcast::Components::PodcastCard::Body @episode={{episode}} /> | |
+ {{/if}} | |
- {{ui-spacer style='xs'}} | |
- | |
- {{#ui-p style='leading-tight bold marginless'}} | |
- {{episode.title}} | |
- {{/ui-p}} | |
- | |
- {{ui-spacer style='xs'}} | |
- | |
- {{#ui-p style='small subtle marginless leading-1.4'}} | |
- {{truncate episode.description words=14}}... | |
- {{/ui-p}} | |
- </div> | |
</div> | |
{{/ui-link-to}} | |
</div> | |
diff --git a/app/pods/podcast/episode/controller.js b/app/pods/podcast/episode/controller.js | |
new file mode 100644 | |
index 00000000..de74ea9b | |
--- /dev/null | |
+++ b/app/pods/podcast/episode/controller.js | |
@@ -0,0 +1,15 @@ | |
+import Controller from "@ember/controller"; | |
+ | |
+export default Controller.extend({ | |
+ *fade({ receivedSprites }) { | |
+ console.log("fade: ", arguments[0]); | |
+ receivedSprites.forEach(sprite => { | |
+ sprite.applyStyles({ | |
+ opacity: 0 | |
+ }); | |
+ sprite.moveToFinalPosition(); | |
+ | |
+ fadeIn(sprite, { from: 0 }); | |
+ }); | |
+ } | |
+}); | |
diff --git a/app/pods/podcast/episode/template.hbs b/app/pods/podcast/episode/template.hbs | |
index 87434049..4e286362 100644 | |
--- a/app/pods/podcast/episode/template.hbs | |
+++ b/app/pods/podcast/episode/template.hbs | |
@@ -1,104 +1,108 @@ | |
{{ui-video-hero video=model}} | |
-{{#ui-container}} | |
- <div class="text-5 max-w-measure-wide mx-auto"> | |
- <div class="my-4 pb-2 lg:flex justify-between"> | |
- <div class="w-full flex-no-shrink"> | |
+<AnimatedContainer> | |
+ <Animate @model={{model}}> | |
+ {{#ui-container}} | |
+ <div class="text-5 max-w-measure-wide mx-auto"> | |
+ <div class="py-4 pb-2 lg:flex justify-between"> | |
+ <div class="w-full flex-no-shrink"> | |
- {{#ui-p style='uppercase xxs strong subtle marginless'}} | |
- {{moment-format model.publishedAt 'MMMM D, YYYY'}} | |
- {{/ui-p}} | |
+ {{#ui-p style='uppercase xxs strong subtle marginless'}} | |
+ {{moment-format model.publishedAt 'MMMM D, YYYY'}} | |
+ {{/ui-p}} | |
- {{ui-spacer style='xs'}} | |
+ {{ui-spacer style='xs'}} | |
- {{#ui-title style='headline marginless'}} | |
- <span class="leading-none"> | |
- {{model.title}} | |
- </span> | |
- {{/ui-title}} | |
+ {{#ui-title style='headline marginless'}} | |
+ <span class="leading-none"> | |
+ {{model.title}} | |
+ </span> | |
+ {{/ui-title}} | |
- <div class="py-1"></div> | |
+ <div class="py-1"></div> | |
- <p class="text-6 font-medium"> | |
- Episode {{model.position}} | |
- <span class='px-1'>//</span> | |
- The EmberMap Podcast | |
- </p> | |
+ <p class="text-6 font-medium"> | |
+ Episode {{model.position}} | |
+ <span class='px-1'>//</span> | |
+ The EmberMap Podcast | |
+ </p> | |
- {{ui-hr}} | |
+ {{ui-hr}} | |
- {{ui-spacer style='small'}} | |
+ {{ui-spacer style='small'}} | |
- <p class="text-5 md:text-4 mb-3" data-test-id="episode-description"> | |
- {{model.description}} | |
- </p> | |
+ <p class="text-5 md:text-4 mb-3" data-test-id="episode-description"> | |
+ {{model.description}} | |
+ </p> | |
- {{ui-spacer style='lg'}} | |
+ {{ui-spacer style='lg'}} | |
- {{#ui-title}} | |
- How to listen | |
- {{/ui-title}} | |
+ {{#ui-title}} | |
+ How to listen | |
+ {{/ui-title}} | |
- <p class="text-5 md:text-4 mb-3"> | |
- Watch above, or find us on your favorite channel: | |
- </p> | |
- | |
- <div class="flex flex-wrap"> | |
- <a href="https://itunes.apple.com/us/podcast/the-embermap-podcast/id1288274408?mt=2" class='mr-1'> | |
- {{svg-jar 'apple-podcasts-listen-badge' height="34" width=null}} | |
- </a> | |
- <a href="https://www.youtube.com/playlist?list=PLc_oqaQ4aMWGLL7iu2IoU30aOC9pykK_L" class='mr-1'> | |
- {{svg-jar 'youtube-watch-badge' height="34" width=null}} | |
- </a> | |
- </div> | |
+ <p class="text-5 md:text-4 mb-3"> | |
+ Watch above, or find us on your favorite channel: | |
+ </p> | |
- {{ui-spacer style='lg'}} | |
+ <div class="flex flex-wrap"> | |
+ <a href="https://itunes.apple.com/us/podcast/the-embermap-podcast/id1288274408?mt=2" class='mr-1'> | |
+ {{svg-jar 'apple-podcasts-listen-badge' height="34" width=null}} | |
+ </a> | |
+ <a href="https://www.youtube.com/playlist?list=PLc_oqaQ4aMWGLL7iu2IoU30aOC9pykK_L" class='mr-1'> | |
+ {{svg-jar 'youtube-watch-badge' height="34" width=null}} | |
+ </a> | |
+ </div> | |
- {{#ui-title}} | |
- Show notes | |
- {{/ui-title}} | |
+ {{ui-spacer style='lg'}} | |
- <div data-test-id="episode-summary"> | |
- {{ui-md source=model.summary}} | |
- </div> | |
+ {{#ui-title}} | |
+ Show notes | |
+ {{/ui-title}} | |
- </div> | |
- </div> | |
- </div> | |
-{{/ui-container}} | |
- | |
-<div class="bg-grey-lightest py-5"> | |
- {{#ui-container}} | |
- {{#ui-title style='center marginless'}} | |
- Recent episodes | |
- {{/ui-title}} | |
- | |
- <LoadRecords | |
- @modelName='podcast-episode' | |
- @params={{hash | |
- sort='-position' | |
- page=(hash limit=4) | |
- }} | |
- @backgroundReload={{false}} | |
- as |isLoading isError latestEpisodes|> | |
- | |
- {{#if latestEpisodes}} | |
- <Grid @columns='lg:3' @gutters='lg:3' as |grid|> | |
- {{#each (take 3 (without model latestEpisodes)) as |episode|}} | |
- <grid.Column> | |
- <Podcast::Components::PodcastCard @episode={{episode}} /> | |
- </grid.Column> | |
- {{/each}} | |
- </Grid> | |
- | |
- <div class="mt-5"> | |
- <p class='text-center'> | |
- or {{#link-to 'podcast' class='text-black font-semibold'}}View all episodes{{/link-to}} | |
- </p> | |
+ <div data-test-id="episode-summary"> | |
+ {{ui-md source=model.summary}} | |
+ </div> | |
+ | |
+ </div> | |
</div> | |
- {{/if}} | |
+ </div> | |
+ {{/ui-container}} | |
- </LoadRecords> | |
+ <div class="bg-grey-lightest py-5"> | |
+ {{#ui-container}} | |
+ {{#ui-title style='center marginless'}} | |
+ Recent episodes | |
+ {{/ui-title}} | |
- {{/ui-container}} | |
-</div> | |
+ <LoadRecords | |
+ @modelName='podcast-episode' | |
+ @params={{hash | |
+ sort='-position' | |
+ page=(hash limit=4) | |
+ }} | |
+ @backgroundReload={{false}} | |
+ as |isLoading isError latestEpisodes|> | |
+ | |
+ {{#if latestEpisodes}} | |
+ <Grid @columns='lg:3' @gutters='lg:3' as |grid|> | |
+ {{#each (take 3 (without model latestEpisodes)) as |episode|}} | |
+ <grid.Column> | |
+ <Podcast::Components::PodcastCard @episode={{episode}} /> | |
+ </grid.Column> | |
+ {{/each}} | |
+ </Grid> | |
+ | |
+ <div class="mt-5"> | |
+ <p class='text-center'> | |
+ or {{#link-to 'podcast' class='text-black font-semibold'}}View all episodes{{/link-to}} | |
+ </p> | |
+ </div> | |
+ {{/if}} | |
+ | |
+ </LoadRecords> | |
+ | |
+ {{/ui-container}} | |
+ </div> | |
+ </Animate> | |
+</AnimatedContainer> | |
diff --git a/app/pods/podcast/index/controller.js b/app/pods/podcast/index/controller.js | |
index 4b91afa9..963a4a64 100644 | |
--- a/app/pods/podcast/index/controller.js | |
+++ b/app/pods/podcast/index/controller.js | |
@@ -14,5 +14,9 @@ export default Controller.extend({ | |
episodes: computed("sortedEpisodes.[]", function() { | |
return this.sortedEpisodes.slice(1); | |
- }) | |
+ }), | |
+ | |
+ *transition() { | |
+ console.log("index: ", arguments[0]); | |
+ } | |
}); | |
diff --git a/app/pods/podcast/index/template.hbs b/app/pods/podcast/index/template.hbs | |
index 3f50669f..6a61675a 100644 | |
--- a/app/pods/podcast/index/template.hbs | |
+++ b/app/pods/podcast/index/template.hbs | |
@@ -40,7 +40,12 @@ | |
<Grid @columns='md:2 lg:3' @gutters='md:3' as |grid|> | |
{{#each sortedEpisodes as |episode|}} | |
<grid.Column> | |
- <Podcast::Components::PodcastCard @episode={{episode}} /> | |
+ <Podcast::Components::PodcastCard @episode={{episode}} as |card|> | |
+ {{#animated-value episode use=this.transition}} | |
+ <card.Image /> | |
+ {{/animated-value}} | |
+ <card.Body /> | |
+ </Podcast::Components::PodcastCard> | |
</grid.Column> | |
{{/each}} | |
</Grid> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment