Skip to content
This repository has been archived by the owner on May 24, 2021. It is now read-only.

Commit

Permalink
feat(marquee): Adds marquee effect to title if needed
Browse files Browse the repository at this point in the history
- fixes #460
  • Loading branch information
alexander-heimbuch committed Feb 9, 2018
1 parent 84f04e9 commit 0e982a8
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 15 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@
"ava": "0.18.2",
"babel-core": "6.22.0",
"babel-loader": "7.1.1",
"superagent-nock": "0.3.1",
"babel-plugin-add-module-exports": "0.2.1",
"babel-plugin-lodash": "3.2.11",
"babel-plugin-transform-object-rest-spread": "6.23.0",
Expand Down Expand Up @@ -115,6 +114,7 @@
"snazzy": "7.0.0",
"standard": "10.0.2",
"standard-changelog": "1.0.1",
"superagent-nock": "0.3.1",
"surge": "0.18.0",
"transform-runtime": "0.0.0",
"vue-loader": "13.7.0",
Expand Down
1 change: 1 addition & 0 deletions src/components/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
@import '~styles/transitions';
@import '~styles/animations';
@import '~styles/marquee';
.podlove {
display: block;
Expand Down
6 changes: 3 additions & 3 deletions src/components/header/Info.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
<a :href="show.link" target="_blank" class="truncate" v-if="display === 'embed' && show.link">{{ show.title }}</a>
<span class="truncate" v-else>{{ show.title }}</span>
</h2>
<h1 class="title" :style="titleStyle" v-if="hasEpisodeTitle">
<a :href="episode.link" target="_blank" class="truncate" v-if="display === 'embed' && episode.link">{{ episode.title }}</a>
<span class="truncate" v-else>{{ episode.title }}</span>
<h1 class="title" v-marquee :style="titleStyle" v-if="hasEpisodeTitle">
<a :href="episode.link" target="_blank" v-if="display === 'embed' && episode.link">{{ episode.title }}</a>
<span v-else>{{ episode.title }}</span>
</h1>
<div class="subtitle" :style="subtitleStyle" v-if="hasDescription">{{ episode.subtitle }}</div>
</div>
Expand Down
16 changes: 7 additions & 9 deletions src/components/shared/TabHeader.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<template>
<ul class="tab-header" :class="{ overflows }">
<ul class="tab-header" :class="{ overflows }" v-resize="resizeHandler">
<span class="header-shadow" :style="headerShadowStyle"></span>
<slot></slot>
</ul>
</template>

<script>
/* global MutationObserver */
import color from 'color'
export default {
Expand All @@ -22,18 +22,16 @@
}
}
},
mounted () {
const resizeHandler = () => {
methods: {
resizeHandler () {
this.$nextTick(() => {
this.overflows = this.$el.scrollWidth > this.$el.clientWidth
})
}
},
const tabsObserver = new MutationObserver(resizeHandler)
tabsObserver.observe(this.$el, { childList: true })
window.addEventListener('resize', resizeHandler)
resizeHandler()
mounted () {
this.resizeHandler()
}
}
</script>
Expand Down
6 changes: 5 additions & 1 deletion src/core/directives/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import clipboard from './directives/clipboard'
import clipboard from './clipboard'
import resize from './resize'
import marquee from './marquee'

const registerDirectives = context => {
context.Renderer.directive('clipboard', clipboard)
context.Renderer.directive('resize', resize)
context.Renderer.directive('marquee', marquee)

return context
}
Expand Down
38 changes: 38 additions & 0 deletions src/core/directives/marquee.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { setStyles, hasOverflow, addClasses, removeClasses } from 'utils/dom'

const marquee = el => {
const scroller = el.firstChild

setStyles({
'overflow-x': 'auto',
'white-space': 'nowrap'
})(scroller)

setStyles({
height: `${el.offsetHeight}px`
})(el)

setStyles({
height: `${scroller.offsetHeight}px`
})(scroller)

if (hasOverflow(scroller)) {
addClasses('marquee-container')(el)
addClasses('marquee')(scroller)
} else {
removeClasses('marquee-container')(el)
removeClasses('marquee')(scroller)
}

setStyles({
'overflow-x': 'visible'
})(scroller)
}

export default {
bind (el) {
marquee(el)
window.addEventListener('resize', () => marquee(el))
},
update: marquee
}
10 changes: 10 additions & 0 deletions src/core/directives/resize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* global MutationObserver */

export default {
bind (el, { value }) {
const observer = new MutationObserver(value)

observer.observe(el, { childList: true })
window.addEventListener('resize', value)
}
}
42 changes: 42 additions & 0 deletions src/styles/_marquee.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
.marquee-container {
overflow: hidden;
position: relative;

.marquee {
position: absolute;
width: 100%;
height: 100%;
margin: 0;
text-align: left;

/* Starting position */
transform: translateX(0%);

/* Apply animation to this element */
animation: scroll 10s linear infinite;
}

/* Move it (define the animation) */
@keyframes scroll {
0% {
opacity: 1;
transform: translateX(0%); }
20% {
opacity: 1;
transform: translateX(0%); }
40% {
opacity: 1;
transform: translateX(0%);
}
80% {
opacity: 1;
}
90% {
opacity: 0;
transform: translateX(-110%);
}
100% {
opacity: 0;
}
}
}
24 changes: 23 additions & 1 deletion src/utils/dom.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import curry from 'lodash/fp/curry'
import { curry, compose, uniq, concat, join, filter } from 'lodash/fp'

export const findNode = selector => document.querySelectorAll(selector)
export const createNode = tag => document.createElement(tag)
Expand All @@ -10,3 +10,25 @@ export const tag = curry((tag, value = '', attributes = {}) => {
attr = attr.join('')
return `<${tag}${attr}>${value}</${tag}>`
})

export const setStyles = (attrs = {}) => el => {
Object.keys(attrs).forEach(property => {
el.style[property] = attrs[property]
})
}

export const getClasses = el => el.className.split(' ')

export const hasOverflow = el => el.scrollWidth > el.clientWidth

export const addClasses = (...classes) => el => {
el.className = compose(join(' '), uniq, concat(classes), getClasses)(el)

return el
}

export const removeClasses = (...classes) => el => {
el.className = compose(join(' '), filter(className => !~classes.indexOf(className)), getClasses)(el)

return el
}

0 comments on commit 0e982a8

Please sign in to comment.