frontend как раз таки запущен на node.jsсейчас, на этапе разработки я пользуюсь обычным browsersync-ом, который разворачивает свой мини-сервер, который да фактически написан на ноде, но это не принцыпиально, можно и на apache развернуть фронт, это не играет особой роли.
gulp.task('js', function (done) {
gulp.src('entry file')
.pipe(webpackStream(args.production ? webpackDevConfig : webpackProdConfig, webpack))
.pipe(gulp.dest('dest path'));
done();
});
//home-slider
if ($(".home-slider-wrap-in").length > 0) {
let homeSlider = new Swiper(".home-slider-wrap-in", {
init: false,
loop: true,
speed: 600,
autoplay: 5000,
effect: "slide", // "slide", "fade", "cube", "coverflow" or "flip"
slidesPerView: 1, // 'auto'
pagination: {
el: ".home-slider-pagination",
type: "bullets",
clickable: true
},
spaceBetween: 0,
// grabCursor: true,
lazyLoading: true,
simulateTouch: false,
allowTouchMove: false
});
setTimeout(() => {
homeSlider.init();
//bubbles creating
if (window.matchMedia("(min-width: 768px)").matches) {
setTimeout(() => {
function createBubbles() {
const randomLeft = Math.floor(Math.random() * 100) + 1;
const getBubbleSize = ["large", "small"];
let rand = Math.random();
rand *= getBubbleSize.length;
const bubbleSize = getBubbleSize[Math.floor(rand)];
const randomOpacity = Math.floor(Math.random() * (9 - 8 + 1)) + 8;
const scaleValue = Math.floor(Math.random() * (9 - 5 + 1)) + 5;
const randomScale = "scale(0." + scaleValue + ")";
const verticalSpeed = Math.floor(Math.random() * (25 - 5 + 1)) + 5;
const frequency = Math.floor(Math.random() * (6 - 1 + 1)) + 1;
const randomAnimation =
"moveBubbleVerticaly " +
verticalSpeed +
"s linear infinite, moveBubbleHorizontaly " +
frequency +
"s ease-in-out infinite alternate";
$(".swiper-slide-active .bubbles").append(
`<div class="bubble ${bubbleSize}" style="left:${randomLeft}%;opacity:0.${randomOpacity};transform:${randomScale};-moz-transform:${randomScale};-webkit-transform:${randomScale};-webkit-animation:${randomAnimation};-moz-animation:${randomAnimation};--o-animation:${randomAnimation};"></div>`
);
}
for (let i = 0; i < 47; i++) {
//create bubble every .5 seconds
(function(i) {
window.setTimeout(function() {
createBubbles();
}, i * 500);
})(i);
}
}, 10);
}
}, 50);
homeSlider.on("slideChangeTransitionEnd", () => {
$(homeSlider.el)
.find(".swiper-slide-active [data-animate]")
.each(function() {
const animation = $(this).data("animate");
const delay = $(this).data("delay");
const duration = $(this).data("duration");
const animating = new Promise((resolve, reject) => {
$(this)
.addClass(`animated ${animation}`)
.css({
visibility: "visible",
animationDelay: delay,
animationDuration: duration
});
resolve("resolve");
});
animating.then((resolve) => {
$(homeSlider.el)
.find("[data-animate]")
.each(function() {
if ($(this).closest(".swiper-slide-active").length) return;
const animation = $(this).data("animate");
$(this)
.removeAttr("style")
.removeClass("animated")
.removeClass(animation);
});
});
});
});
}
//models-thumbs-slider
if ($(".models-thumbs-slider-wrap-in").length > 0) {
let swiperInstances = [];
$(".models-thumbs-slider-wrap-in").each(function(index, element) {
const $this = $(this);
$this.addClass("models-thumbs-instance-" + index);
$this
.parent()
.find(".swiper-button-prev")
.addClass("models-thumbs-btn-prev-" + index);
$this
.parent()
.find(".swiper-button-next")
.addClass("models-thumbs-btn-next-" + index);
swiperInstances[index] = new Swiper(".models-thumbs-instance-" + index, {
effect: "slide", // "slide", "fade", "cube", "coverflow" or "flip"
slidesPerView: "auto", // 'auto'
navigation: {
prevEl: ".models-thumbs-btn-prev-" + index,
nextEl: ".models-thumbs-btn-next-" + index
},
spaceBetween: 5,
// grabCursor: true,
simulateTouch: false,
allowTouchMove: false,
lazyLoading: true,
breakpoints: {
1140: {
simulateTouch: true,
allowTouchMove: true,
slidesPerView: 5
},
768: {
simulateTouch: true,
allowTouchMove: true,
slidesPerView: 4
},
480: {
simulateTouch: true,
allowTouchMove: true,
slidesPerView: 3
}
}
});
});
setTimeout(function() {
for (const slider of swiperInstances) {
slider.update();
}
}, 50);
//sync models-thumbs to models
$(document).on("click", ".models-thumbs-slide", function() {
const index = $(this).index();
const instanceClass = $(this)
.closest('[class*="models-thumbs-instance-"]')
.attr("class")
.match(/models-thumbs-instance-\d/g)
.join("");
const instanceNr = instanceClass.match(/\d/g).join("");
modelsSliderInstances[instanceNr].slideTo(index);
$(this)
.addClass("active")
.siblings(".models-thumbs-slide")
.removeClass("active");
//scroll to block
const scrollTarget = $(this).closest(".models-block");
if (Math.floor(scrollTarget.offset().top - 68) !== $(window).scrollTop()) {
$("html, body")
.stop()
.animate({ scrollTop: scrollTarget.offset().top - 68 }, 500);
}
});
}
//models-slider
let modelsSliderInstances = [];
if ($(".models-slider-wrap-in").length > 0) {
$(".models-slider-wrap-in").each(function(index, element) {
const $this = $(this);
$this.addClass("models-instance-" + index);
$this
.parent()
.find(".swiper-button-prev")
.addClass("models-slider-btn-prev-" + index);
$this
.parent()
.find(".swiper-button-next")
.addClass("models-slider-btn-next-" + index);
modelsSliderInstances[index] = new Swiper(".models-instance-" + index, {
effect: "slide", // "slide", "fade", "cube", "coverflow" or "flip"
slidesPerView: 1, // 'auto'
navigation: {
prevEl: ".models-slider-btn-prev-" + index,
nextEl: ".models-slider-btn-next-" + index
},
spaceBetween: 0,
// grabCursor: true,
simulateTouch: false,
allowTouchMove: false,
lazyLoading: true
});
});
setTimeout(function() {
for (const slider of modelsSliderInstances) {
slider.update();
//sync gallery to gallery-thumbs
slider.on("slideChange", () => {
let thumbs = $(slider.el)
.closest(".models-slider-section")
.prev(".models-thumbs")
.find(".models-thumbs-slide");
thumbs.not(thumbs[slider.activeIndex]).removeClass("active");
$(thumbs[slider.activeIndex]).addClass("active");
});
}
}, 50);
}
//gallery-slider
let gallerySliderInstances = [];
if ($(".gallery-slider-wrap-in").length > 0) {
$(".gallery-slider-wrap-in").each(function(index, element) {
const $this = $(this);
$this.addClass("gallery-instance-" + index);
$this
.parent()
.find(".swiper-pagination")
.addClass("gallery-slider-pagination-" + index);
gallerySliderInstances[index] = new Swiper(".gallery-instance-" + index, {
effect: "slide", // "slide", "fade", "cube", "coverflow" or "flip"
slidesPerView: 1, // 'auto'
pagination: {
el: ".gallery-slider-pagination-" + index,
type: "bullets",
clickable: true
},
// observer: true,
spaceBetween: 0,
// grabCursor: true,
lazyLoading: true
});
});
setTimeout(function() {
for (const slider of gallerySliderInstances) {
slider.update();
//sync gallery to gallery-thumbs
slider.on("slideChange", () => {
//add class active
let thumbs = $(slider.el)
.closest(".gallery")
.next(".gallery-thumbs")
.find(".gallery-thumbs-slide");
thumbs.not(thumbs[slider.activeIndex]).removeClass("active");
$(thumbs[slider.activeIndex]).addClass("active");
//change slide
const instanceClass = $(slider.el)
.closest('[class*="gallery-instance-"]')
.attr("class")
.match(/gallery-instance-\d/g)
.join("");
const instanceNr = instanceClass.match(/\d/g).join("");
galleryThumbsInstances[instanceNr].slideTo(slider.activeIndex);
});
}
}, 50);
}