Skip to content

Instantly share code, notes, and snippets.

@c0urg3tt3
Last active October 13, 2017 10:51
Show Gist options
  • Save c0urg3tt3/d776b42be517978e8581a6d6e65b9905 to your computer and use it in GitHub Desktop.
Save c0urg3tt3/d776b42be517978e8581a6d6e65b9905 to your computer and use it in GitHub Desktop.
having fun with glimmerjs building a basic fluid slider in glimmer-playground sandbox
import Component, { tracked } from "@glimmer/component";
export default class extends Component {
@tracked('args')
get isDisabled() {
return this.args.currentIndex === this.args.slideIndex
}
};
<button
class="slider__counter"
onclick={{@action}}
disabled={{isDisabled}}
></button>
import Component, { tracked } from "@glimmer/component";
export default class extends Component {
@tracked('args')
get isVisible() {
return this.args.slidesLength > 1
}
};
{{#if isVisible}}
<button class="slider__button" onclick={{@action}}>
{{yield}}
</button>
{{/if}}
import Component, { tracked } from '@glimmer/component'
export default class extends Component {
@tracked slideWidth = 0
@tracked currentIndex = 0
ratio: any = (5 / 1).toFixed(2)
@tracked('slideWidth')
get slideHeight() {
const { ratio = this.ratio } = this.args
return (this.slideWidth / ratio).toFixed(2)
}
@tracked('slideWidth', 'currentIndex')
get slidesOffset() {
return -(this.slideWidth * this.currentIndex)
}
constructor(options) {
super(options)
this.resize = this.resize.bind(this)
}
didInsertElement() {
setTimeout(() => {
this.resize()
window.addEventListener('optimizedResize', this.resize)
}, 0)
}
willDestroy() {
window.removeEventListener('optimizedResize')
}
resize(event = null) {
this.slideWidth = this.bounds.firstNode['clientWidth']
}
prevSlide() {
const prevIndex = this.currentIndex - 1
const max = this.args.slidesLength - 1
const slideIndex = (prevIndex >= 0) ? prevIndex : max
this.pickSlide(slideIndex)
}
pickSlide(slideIndex) {
this.currentIndex = slideIndex
}
nextSlide() {
const nextIndex = this.currentIndex + 1
const max = this.args.slidesLength - 1
const slideIndex = (nextIndex <= max) ? nextIndex : 0
this.pickSlide(slideIndex)
}
}
<div class="slider">
<header class="slider__header">
<h1>{{@title}}</h1>
</header>
<div class="slider__wrapper">
<ul
class="slider__slides"
style="transform: translateX({{slidesOffset}}px)"
>
{{#each @slides key="@index" as |slide|}}
<li class="slider__slide" style="width: {{slideWidth}}px; height: {{slideHeight}}px">
<p>{{slide.alt}}</p>
</li>
{{else}}
<li class="slider__slide" style="width: {{slideWidth}}px; height: {{slideHeight}}px">
<p>No Slides Available!</p>
</li>
{{/each}}
</ul>
</div>
<footer class="slider__footer">
<ButtonVisible
@action={{action prevSlide}}
@slidesLength={{@slidesLength}}
>
prev
</ButtonVisible>
{{#if @slidesLength}}
<div class="slider__counters">
{{#each @slides key="@index" as |slide index|}}
<ButtonPickSlide
@action={{action pickSlide index}}
@currentIndex={{currentIndex}}
@slideIndex={{index}}
/>
{{/each}}
</div>
{{/if}}
<ButtonVisible
@action={{action nextSlide}}
@slidesLength={{@slidesLength}}
>
next
</ButtonVisible>
</footer>
</div>
import Component from '@glimmer/component'
(function() {
// https://developer.mozilla.org/en-US/docs/Web/Events/resize
// requestAnimationFrame + customEvent
function throttle(type, name, obj = window) {
var running = false
var func = function() {
if (running) { return }
running = true
requestAnimationFrame(function() {
obj.dispatchEvent(new CustomEvent(name))
running = false
})
}
obj.addEventListener(type, func)
}
throttle("resize", "optimizedResize")
})()
export default class extends Component {
private _mapSlides = (item, index) => ({
src: `./assets/images/slide_${index}.png`,
alt: `slide #${index + 1}`
})
slides = new Array(7).fill(null).map(this._mapSlides)
slide = new Array(1).fill(null).map(this._mapSlides)
ratio_1_1 = (1 / 1).toFixed(2)
ratio_4_3 = (4 / 3).toFixed(2)
ratio_3_2 = (3 / 2).toFixed(2)
ratio_16_9 = (16 / 9).toFixed(2)
ratio_16_10 = (16 / 10).toFixed(2)
}
<div>
<FluidSlider
@title="fluid slider without slides"
/>
<hr/>
<FluidSlider
@title="fluid slider with one slide"
@slides={{slide}}
@slidesLength={{slide.length}}
/>
<hr/>
<FluidSlider
@title="fluid slider with many slides"
@slides={{slides}}
@slidesLength={{slides.length}}
/>
<hr/>
<FluidSlider
@title="fluid slider ratio:1/1"
@slides={{slides}}
@slidesLength={{slides.length}}
@ratio={{ratio_1_1}}
/>
<hr/>
<FluidSlider
@title="fluid slider ratio:4/3"
@slides={{slides}}
@slidesLength={{slides.length}}
@ratio={{ratio_4_3}}
/>
<hr/>
<FluidSlider
@title="fluid slider ratio:3/2"
@slides={{slides}}
@slidesLength={{slides.length}}
@ratio={{ratio_3_2}}
/>
<hr/>
<FluidSlider
@title="fluid slider ratio:16/10"
@slides={{slides}}
@slidesLength={{slides.length}}
@ratio={{ratio_16_10}}
/>
<hr/>
<FluidSlider
@title="fluid slider ratio:16/9"
@slides={{slides}}
@slidesLength={{slides.length}}
@ratio={{ratio_16_9}}
/>
</div>
<style>
@charset "UTF-8";
:root {
font-size: 1rem;
@media (min-width: 20rem) {
font-size: calc(1rem + ((1vw - .20rem) * 1));
}
@media (min-width: 120rem) {
font-size: 2rem;
}
}
.slider {
position: relative;
display: block;
box-sizing: border-box;
border: solid 1px black;
margin: 0 auto;
padding: 0;
counter-reset: sliderBtn;
}
.slider__header {
text-align: center;
font-size: 1.5rem;
margin: 0;
padding: 1rem 0;
border-bottom: solid 1px black;
}
.slider__header > h1 {
font-size: inherit
}
.slider__wrapper {
overflow: hidden;
margin: 0;
padding: 0;
}
.slider__slides {
position: relative;
display: flex;
flex-flow: row nowrap;
align-items: center;
justify-content: flex-start;
margin: 0;
padding: 0;
transition: all .5s;
text-align: center;
}
.slider__slide {
flex: 0 0 auto;
display: table;
max-width: 100%;
list-style: none;
margin: 0;
padding: 0;
color: white;
text-shadow: 0 .25rem .25rem black;
font-size: 2rem;
font-weight: 600;
}
.slider__slide > p {
display: table-cell;
vertical-align: middle;
}
.slider__slide:nth-child(7n+1) {
background: red;
}
.slider__slide:nth-child(7n+2) {
background: orange;
}
.slider__slide:nth-child(7n+3) {
background: yellow;
}
.slider__slide:nth-child(7n+4) {
background: green;
}
.slider__slide:nth-child(7n+5) {
background: blue;
}
.slider__slide:nth-child(7n+6) {
background: indigo;
}
.slider__slide:nth-child(7n+7) {
background: violet;
}
.slider__footer {
position: relative;
display: flex;
flex-flow: row nowrap;
align-items: flex-start;
justify-content: space-around;
margin: 0;
padding: .5rem;
transition: all .5s;
border-top: solid 1px black;
}
.slider__counters {
flex: 1 1 auto;
position: relative;
display: flex;
flex-flow: row wrap;
align-items: flex-start;
justify-content: center;
margin: 0;
padding: 0;
transition: all .5s;
text-align: center;
}
.slider__counter,
.slider__button {
font-size: .75rem;
}
.slider__counter {
width: 2rem;
height: 2rem;
padding: .125rem;
}
.slider__counter::before {
counter-increment: sliderBtn;
/* On incrémente le compteur section */
content: counter(sliderBtn);
}
.slider__button {
width: 2rem;
height: 2rem;
padding: .125rem;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment