All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.dominokit.domino.ui.carousel.Carousel Maven / Gradle / Ivy

/*
 * Copyright © 2019 Dominokit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.dominokit.domino.ui.carousel;

import static org.dominokit.domino.ui.carousel.CarouselStyles.*;
import static org.jboss.elemento.Elements.*;

import elemental2.dom.HTMLAnchorElement;
import elemental2.dom.HTMLDivElement;
import elemental2.dom.HTMLOListElement;
import java.util.ArrayList;
import java.util.List;
import org.dominokit.domino.ui.icons.Icons;
import org.dominokit.domino.ui.style.Styles;
import org.dominokit.domino.ui.utils.BaseDominoElement;
import org.dominokit.domino.ui.utils.DominoElement;
import org.dominokit.domino.ui.utils.ElementUtil;
import org.dominokit.domino.ui.utils.SwipeUtil;
import org.gwtproject.core.client.Scheduler;
import org.gwtproject.timer.client.Timer;

/**
 * A slideshow component for cycling through elements.
 *
 * 

The component provides APIs for going through all the elements by next/previous indicators. * Also, it provides automatic sliding with configurable duration. * *

Customize the component can be done by overwriting classes provided by {@link CarouselStyles} * *

For example: * *

 *     Carousel.create()
 *             .appendChild(
 *                 Slide.create(
 *                     GWT.getModuleBaseURL()
 *                         + "/images/image-gallery/11.jpg"))
 *             .appendChild(
 *                 Slide.create(
 *                     GWT.getModuleBaseURL()
 *                         + "/images/image-gallery/12.jpg"))
 *             .appendChild(
 *                 Slide.create(
 *                     GWT.getModuleBaseURL()
 *                         + "/images/image-gallery/19.jpg"))
 *             .appendChild(
 *                 Slide.create(
 *                     GWT.getModuleBaseURL() + "/images/image-gallery/9.jpg"))
 *             .appendChild(
 *                 Slide.create(
 *                     GWT.getModuleBaseURL()
 *                         + "/images/image-gallery/6.jpg")))
 * 
* * @see BaseDominoElement * @see CarouselStyles */ public class Carousel extends BaseDominoElement { private final HTMLOListElement indicatorsElement = DominoElement.of(ol()).css(CAROUSEL_INDICATORS).element(); private final HTMLDivElement slidesElement = DominoElement.of(div()).css(CAROUSEL_INNER).element(); private boolean autoSlide = false; private final HTMLAnchorElement prevElement = DominoElement.of(a()) .css(LEFT, CAROUSEL_CONTROL) .attr("role", "button") .add(Icons.ALL.chevron_left().addCss(Styles.vertical_center).setFontSize("60px")) .element(); private final HTMLAnchorElement nextElement = DominoElement.of(a()) .css(RIGHT, CAROUSEL_CONTROL) .attr("role", "button") .add(Icons.ALL.chevron_right().addCss(Styles.vertical_center).setFontSize("60px")) .element(); private final HTMLDivElement element = DominoElement.of(div()) .add(indicatorsElement) .add(slidesElement) .add(prevElement) .add(nextElement) .css(CAROUSEL) .element(); private final List slides = new ArrayList<>(); private final Timer timer; private Slide activeSlide; private Slide targetSlide; private int autoSlideDuration = 3000; private boolean attached = false; public Carousel() { nextElement.addEventListener( "click", evt -> { resetTimer(); nextSlide(); }); prevElement.addEventListener( "click", evt -> { resetTimer(); prevSlide(); }); timer = new Timer() { @Override public void run() { nextSlide(); } }; addAttachListener(); addDetachListener(); init(this); } private void resetTimer() { if (autoSlide) { timer.cancel(); timer.scheduleRepeating(autoSlideDuration); } } private void addDetachListener() { ElementUtil.onDetach( element(), mutationRecord -> { this.attached = false; this.stopAutoSlide(); }); } private void addAttachListener() { ElementUtil.onAttach( this.element(), mutationRecord -> { this.attached = true; if (autoSlide) { timer.scheduleRepeating(autoSlideDuration); } addDetachListener(); }); } /** * Creates new carousel * * @return new instance */ public static Carousel create() { return new Carousel(); } /** * Adds new {@link Slide}, event listeners will be added to the slide for removing the motion * styles * * @param slide a {@link Slide} to be added * @return same instance */ public Carousel appendChild(Slide slide) { getIndicatorsElement().appendChild(slide.getIndicatorElement().element()); slidesElement.appendChild(slide.element()); slide .getIndicatorElement() .addEventListener( "click", evt -> { resetTimer(); goToSlide(slide, ""); }); slide.element().addEventListener("webkitTransitionEnd", evt -> removeMotionStyles()); slide.element().addEventListener("MSTransitionEnd", evt -> removeMotionStyles()); slide.element().addEventListener("mozTransitionEnd", evt -> removeMotionStyles()); slide.element().addEventListener("otransitionend", evt -> removeMotionStyles()); slide.element().addEventListener("transitionend", evt -> removeMotionStyles()); if (slides.isEmpty()) { slide.activate(); this.activeSlide = slide; } slides.add(slide); SwipeUtil.addSwipeListener(SwipeUtil.SwipeDirection.LEFT, slide.element(), evt -> nextSlide()); SwipeUtil.addSwipeListener(SwipeUtil.SwipeDirection.RIGHT, slide.element(), evt -> prevSlide()); return this; } private void nextSlide() { Slide nextSlide; if (slides.indexOf(activeSlide) < slides.size() - 1) { nextSlide = slides.get(slides.indexOf(activeSlide) + 1); } else { nextSlide = slides.get(0); } goToSlide(nextSlide, NEXT); } private void prevSlide() { Slide prevSlide; if (slides.indexOf(activeSlide) > 0) { prevSlide = slides.get(slides.indexOf(activeSlide) - 1); } else { prevSlide = slides.get(slides.size() - 1); } goToSlide(prevSlide, PREV); } private void goToSlide(Slide slide, String source) { if (!slide.hasActiveStyle()) { this.targetSlide = slide; slide.getIndicatorElement().addCss(ACTIVE); activeSlide.getIndicatorElement().removeCss(ACTIVE); slide.addCss(getPositionStyle(slide, source)); Scheduler.get() .scheduleFixedDelay( () -> { activeSlide.getIndicatorElement().removeCss(ACTIVE); String directionStyle = getDirectionStyle(slide, source); slide.addCss(directionStyle); activeSlide.addCss(directionStyle); return false; }, 50); } } private String getPositionStyle(Slide target, String source) { if ((slides.indexOf(target) > slides.indexOf(activeSlide) && !PREV.equals(source)) || (NEXT.equals(source))) { return NEXT; } else { return PREV; } } private String getDirectionStyle(Slide target, String source) { if ((slides.indexOf(target) > slides.indexOf(activeSlide) && !PREV.equals(source)) || (NEXT.equals(source))) { return LEFT; } else { return RIGHT; } } private void removeMotionStyles() { activeSlide.removeCss(LEFT).removeCss(RIGHT).removeCss(NEXT).removeCss(PREV); activeSlide.deActivate(); targetSlide.removeCss(LEFT).removeCss(RIGHT).removeCss(NEXT).removeCss(PREV); targetSlide.activate(); this.activeSlide = targetSlide; } /** * Slides through items every {@code slideDuration} * * @param slideDuration the time between slide between each element * @return same instance */ public Carousel startAutoSlide(int slideDuration) { this.autoSlide = true; this.autoSlideDuration = slideDuration; if (attached) { timer.scheduleRepeating(slideDuration); } return this; } /** * Stops the automatic sliding * * @return same instance */ public Carousel stopAutoSlide() { if (timer.isRunning()) { timer.cancel(); } addAttachListener(); return this; } /** {@inheritDoc} */ @Override public HTMLDivElement element() { return element; } /** @return the indicator element */ public DominoElement getIndicatorsElement() { return DominoElement.of(indicatorsElement); } /** @return the slides element which has all the slides */ public DominoElement getSlidesElement() { return DominoElement.of(slidesElement); } /** @return All the added slides */ public List getSlides() { return slides; } /** @return the currently active slide */ public Slide getActiveSlide() { return activeSlide; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy