tomgp
9/6/2017 - 4:58 PM

simple swiper

simple swiper

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Swiper test</title>
    <style>
      html{
    font-size: 100%;
}

article{
    width: 100%;
    overflow: hidden;
}

img{
    width:50vw;
    -webkit-user-drag: none;
    -khtml-user-drag: none;
    -moz-user-drag: none;
    -o-user-drag: none;
    user-drag: none;
}
/* these classes below should probably be added to the dom with javascript so that the no-script version is just a list*/
.slider-item{
    background-color: #eee;
    flex: 0 0 auto;
    justify-content: center;
    align-items: center;
    width:75vw;
}

.swipe-wrapper {
    transition-property: transform;
    transition-duration: 200ms;
    transition-timing-function: ease-out;
    display: -webkit-flex; /* Safari */
    display: flex;
    -webkit-flex-direction: row; /* Safari */
    flex-direction: row;
}
    </style>
</head>
<body>
<article>
    <h1>swiper</h2>

    <div class="swipe-wrapper">
        <div class="default slider-item">
            I'm a fashion designer and people think, what do I know? You can't just buy things for the label - it's ridiculous. Awkwardness gives me great comfort. I've never been cool, but I've felt cool. I've been in the cool place, but I wasn't really cool - I was trying to pass for hip or cool. It's the awkwardness that's nice. I've always thought of the T-shirt as the Alpha and Omega of the fashion alphabet. It is important to be chic. Fashion should be fun. It shouldn't be labelled intellectual. I adore the challenge of creating truly modern clothes, where a woman's personality and sense of self are revealed.
        </div>
        <div class="sticky slider-item">
            <figure>
                <img src="images/acne-1.png" alt="Acne 1"></img>
                <figcaption>short description <a href="">a link perhaps?</a></figcaption>
            </figure>
        </div>
        <div class="sticky slider-item">
            <figure>
                <img src="images/ann-1.png" alt="Ann 1"></img>
                <figcaption>short description <a href="">a link perhaps?</a></figcaption>
            </figure>
        </div>
        <div class="sticky slider-item">
            <figure>
                <img src="images/off-white-1.png" alt="Off White 1"></img>
                <figcaption>short description <a href="">a link perhaps?</a></figcaption>
            </figure>
        </div>
        <div class="sticky slider-item">
            <figure>
                <img src="images/roksanda-1.png" alt="Acne 1"></img>
                <figcaption>short description <a href="">a link perhaps?</a></figcaption>
            </figure>
        </div>  
    </div>
    <div>
        non swiper  stuff
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sagittis nulla a dolor dapibus, a suscipit arcu pretium. Aenean laoreet enim dolor, nec interdum tellus tincidunt eu. Mauris mollis elit tempor urna molestie, a porttitor enim volutpat. Etiam nec purus ac magna finibus maximus. Nulla eget elit fringilla nunc tristique imperdiet quis eget erat. Sed suscipit interdum nisl, a ornare justo. Nullam auctor dignissim ligula at facilisis. Duis at pretium eros. Sed gravida elit et turpis posuere, quis ornare enim molestie. Donec efficitur sed est eu fermentum.
        
        Cras et elit id ligula fringilla pulvinar. In pulvinar pharetra aliquam. Vivamus id felis et diam pretium rutrum nec in quam. Quisque vel sem facilisis, sollicitudin nisl non, pretium leo. Morbi interdum fringilla massa, a iaculis massa congue at. Cras vel tincidunt metus. Vivamus facilisis hendrerit ante, a rutrum risus luctus eu. Vestibulum nisl sapien, sagittis eget consectetur ut, bibendum id neque. Ut ac dignissim est. Proin pellentesque turpis fringilla orci rutrum, vitae elementum lorem finibus. Phasellus condimentum, nibh at varius pretium, massa ligula congue leo, a aliquam nisl tellus porttitor orci.
        
        Quisque pharetra dolor efficitur, euismod purus et, sagittis justo. Duis fermentum augue sit amet risus euismod volutpat. Sed eget nisl eget metus dapibus egestas. Aliquam ante magna, scelerisque ac eros in, dictum posuere turpis. Integer nec ligula ut risus fermentum rhoncus a et urna. Mauris leo nulla, consequat a molestie sed, vestibulum vitae est. Sed laoreet augue a lorem fringilla posuere. Proin aliquet maximus dui quis tincidunt. Morbi in fermentum quam. Vestibulum hendrerit a sapien non maximus. Phasellus lectus lectus, finibus et rhoncus at, venenatis sollicitudin purus. Pellentesque eleifend tellus eu ligula egestas, a dapibus lacus fringilla.
        
        In pharetra quam a finibus suscipit. Maecenas auctor nulla id leo porta, et facilisis libero ultrices. Vestibulum eu turpis mi. In rhoncus mauris ac augue cursus rhoncus. In nec justo cursus, pretium tellus non, auctor orci. In in neque sit amet quam finibus tristique. Maecenas luctus ipsum in diam lacinia posuere. Suspendisse eleifend sem ut porttitor sodales. Phasellus eu massa tortor. Sed tempor tempor nisl, et fermentum ante pharetra vitae. Vestibulum eu nunc accumsan, feugiat turpis at, molestie purus.
        
        Nulla hendrerit felis ut diam scelerisque convallis. Cras vitae facilisis ex. Donec euismod nisi sed arcu faucibus luctus. Mauris nec orci et dolor iaculis semper. Suspendisse auctor gravida dui at tincidunt. Cras vehicula massa augue, at bibendum sapien sagittis eget. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur egestas elit est, vel malesuada nulla varius id.
    </div>
<hr>
</article>
</body>
<script>
function initSwiper(selector, startPosition){
    const windowWidth = window.innerWidth;
    const wrapperElement = document.querySelector('.swipe-wrapper');
    const positionMax = wrapperElement.querySelectorAll('.slider-item').length - 1;
    const sliderOffsets = []
    const sliderItemsSelection = wrapperElement.querySelectorAll('.slider-item');

    let acc = 0, dragOrigin, carouselOrigin;
    let position = startPosition;

    if(isNaN(position) || position === null) position = 0;
    for(let i = 0; i < sliderItemsSelection.length; i++){
        const boundingBox = sliderItemsSelection[i].getBoundingClientRect();
        sliderOffsets[i] = acc + (windowWidth-boundingBox.width)/2;
        if(i===0){ //the frst item is a special case
            sliderOffsets[i] = acc;
        }
        acc -= boundingBox.width;
        if(i === sliderItemsSelection.length - 1){ //the last item is a special case
            sliderOffsets[i] = acc + windowWidth;
        }
    }

    function move(){
        console.log('move to' , position + ' / ' + positionMax);
        console.log(sliderOffsets[position], translationString({x:sliderOffsets[position], y:0}));
        wrapperElement.style.transform = translationString({x:sliderOffsets[position], y:0});
    }

    function normaliseEvent(e){
        let x = e.clientX;
        let y = e.clientY;
        if(e.touches){
            x = e.touches[0].clientX;
            y = e.touches[0].clientY;
        }
        return {x, y};
    }
    function extractTranslationCoords(str){
                //example string 'translate(-0.54px, 32px)'
        const translatePattern = /translate\((-?\d+\.?\d*)px, (-?\d+\.?\d*)px\)/;
        const coords = translatePattern.exec(str);
        if(coords !== null){ 
            return { x: +coords[1],  y: +coords[2] };
        }
        return {x:0, y:0};

    }

    function translationString(coords){
        return 'translate('+coords.x+'px,'+coords.y+'px)';
    }

    function startDrag(e){
        dragOrigin = normaliseEvent(e);
        carouselOrigin = extractTranslationCoords(wrapperElement.style.transform);
        wrapperElement.style['transition-duration'] = '0ms';
    }

    function endDrag(e){
        wrapperElement.style['transition-duration'] = '';
        //determine the nearest item and snap to it
        let found = false;
        wrapperPosition = extractTranslationCoords(wrapperElement.style.transform);
        console.log(wrapperPosition);
        let nearestItem = 0;
        position = sliderOffsets.reduce((item, current, i, a)=>{
            if(current > wrapperPosition.x) return i;
            return item;
        }, 0)
        move();
        dragOrigin = undefined;
    }

    function drag(e){
        let current = normaliseEvent(e);
        const dragDif = current.x - dragOrigin.x;
        wrapperElement.style.transform = translationString({x:carouselOrigin.x + dragDif, y:0});
    }

    wrapperElement.addEventListener('mousedown', startDrag, false);
    wrapperElement.addEventListener('touchstart', startDrag, false);
    wrapperElement.addEventListener('mousemove', drag, false);
    wrapperElement.addEventListener('touchmove', drag, false);
    document.addEventListener('mouseup', endDrag, false);
    document.addEventListener('touchend', endDrag, false);
    
    move();

    return {
        increment: ()=>{
            position = Math.min(positionMax, position+1);
            move();
        },
        decrement: ()=>{
            position = Math.max(0, position-1);
            move();
        },
        goTo: (targetPosition)=>{
            if(targetPosition > positionMax || targetPosition < 0) return;
            position = targetPosition;
            move();
        },
    }
}

const swiper = initSwiper('.swipe-wraper');

</script>
</html>