Skip to content

Commit

Permalink
feat: new "Custom" effect
Browse files Browse the repository at this point in the history
  • Loading branch information
nolimits4web committed Aug 9, 2021
1 parent 1f08e06 commit f72f5ba
Show file tree
Hide file tree
Showing 20 changed files with 233 additions and 7 deletions.
2 changes: 2 additions & 0 deletions package/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"./less/effect-cube": "./modules/effect-cube/effect-cube.less",
"./less/effect-fade": "./modules/effect-fade/effect-fade.less",
"./less/effect-flip": "./modules/effect-flip/effect-flip.less",
"./less/effect-custom": "./modules/effect-flip/effect-custom.less",
"./less/free-mode": "./modules/free-mode/free-mode.less",
"./less/grid": "./modules/grid/grid.less",
"./less/hash-navigation": "./modules/hash-navigation/hash-navigation.less",
Expand All @@ -45,6 +46,7 @@
"./scss/effect-cube": "./modules/effect-cube/effect-cube.scss",
"./scss/effect-fade": "./modules/effect-fade/effect-fade.scss",
"./scss/effect-flip": "./modules/effect-flip/effect-flip.scss",
"./scss/effect-custom": "./modules/effect-flip/effect-custom.scss",
"./scss/free-mode": "./modules/free-mode/free-mode.scss",
"./scss/grid": "./modules/grid/grid.scss",
"./scss/hash-navigation": "./modules/hash-navigation/hash-navigation.scss",
Expand Down
1 change: 1 addition & 0 deletions scripts/build-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module.exports = {
'effect-cube',
'effect-flip',
'effect-coverflow',
'effect-custom',
'thumbs',
'free-mode',
'grid',
Expand Down
1 change: 1 addition & 0 deletions src/angular/src/swiper.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ export class SwiperComponent implements OnInit {
@Input() cubeEffect: SwiperOptions['cubeEffect'];
@Input() fadeEffect: SwiperOptions['fadeEffect'];
@Input() flipEffect: SwiperOptions['flipEffect'];
@Input() customEffect: SwiperOptions['customEffect'];
@Input() hashNavigation: SwiperOptions['hashNavigation'];
@Input() history: SwiperOptions['history'];
@Input() keyboard: SwiperOptions['keyboard'];
Expand Down
1 change: 1 addition & 0 deletions src/angular/src/utils/params-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ export const paramsList = [
'cubeEffect',
'fadeEffect',
'flipEffect',
'customEffect',
'hashNavigation',
'history',
'keyboard',
Expand Down
2 changes: 1 addition & 1 deletion src/modules/effect-coverflow/effect-coverflow.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import $ from '../../shared/dom.js';

export default function Coverflow({ swiper, extendParams, on }) {
export default function EffectCoverflow({ swiper, extendParams, on }) {
extendParams({
coverflowEffect: {
rotate: 50,
Expand Down
2 changes: 1 addition & 1 deletion src/modules/effect-cube/effect-cube.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import $ from '../../shared/dom.js';

export default function Cube({ swiper, extendParams, on }) {
export default function EffectCube({ swiper, extendParams, on }) {
extendParams({
cubeEffect: {
slideShadows: true,
Expand Down
131 changes: 131 additions & 0 deletions src/modules/effect-custom/effect-custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
export default function EffectCustom({ swiper, extendParams, on }) {
extendParams({
customEffect: {
transformEl: null,
prev: {
translate: [0, 0, 0],
rotate: [0, 0, 0],
opacity: 1,
scale: 1,
},
next: {
translate: [0, 0, 0],
rotate: [0, 0, 0],
opacity: 1,
scale: 1,
},
},
});

const getTranslateValue = (value) => {
if (typeof value === 'string') return value;
return `${value}px`;
};

const setTranslate = () => {
const { slides } = swiper;
const params = swiper.params.customEffect;
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides.eq(i);
const progress = Math.min(Math.max($slideEl[0].progress, -1), 1);
const offset = $slideEl[0].swiperSlideOffset;
const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
const r = [0, 0, 0];
if (!swiper.isHorizontal()) {
t[1] = t[0];
t[0] = 0;
}
let data = {
translate: [0, 0, 0],
rotate: [0, 0, 0],
scale: 1,
opacity: 1,
};
if (progress < 0) {
data = params.next;
} else if (progress > 0) {
data = params.prev;
}
// set translate
t.forEach((value, index) => {
t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(
progress,
)}))`;
});
// set rotates
r.forEach((value, index) => {
r[index] = data.rotate[index] * Math.abs(progress);
});

$slideEl[0].style.zIndex = -Math.abs(Math.round(progress)) + slides.length;

const translateString = t.join(', ');
const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
const scaleString =
progress < 0
? `scale(${1 + (1 - data.scale) * progress})`
: `scale(${1 - (1 - data.scale) * progress})`;
const opacityString =
progress < 0 ? 1 + (1 - data.opacity) * progress : 1 - (1 - data.opacity) * progress;
const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;

if (params.transformEl) {
$slideEl
.find(params.transformEl)
.css({
'backface-visibility': 'hidden',
'-webkit-backface-visibility': 'hidden',
opacity: opacityString,
})
.transform(transform);
} else {
$slideEl.transform(transform).css({ opacity: opacityString });
}
}
};

const setTransition = (duration) => {
const { slides, activeIndex, $wrapperEl } = swiper;
const { transformEl } = swiper.params.customEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
$transitionElements.transition(duration);

if (swiper.params.virtualTranslate && duration !== 0) {
let eventTriggered = false;
const $transitionEndTarget = transformEl
? slides.eq(activeIndex).find(transformEl)
: slides.eq(activeIndex);
// eslint-disable-next-line
$transitionEndTarget.transitionEnd(() => {
if (eventTriggered) return;
if (!swiper || swiper.destroyed) return;
eventTriggered = true;
swiper.animating = false;
const triggerEvents = ['webkitTransitionEnd', 'transitionend'];
for (let i = 0; i < triggerEvents.length; i += 1) {
$wrapperEl.trigger(triggerEvents[i]);
}
});
}
};

on('beforeInit', () => {
if (swiper.params.effect !== 'custom') return;
swiper.classNames.push(`${swiper.params.containerModifierClass}custom`);
swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
const overwriteParams = {
watchSlidesProgress: true,
virtualTranslate: !swiper.params.cssMode,
};
Object.assign(swiper.params, overwriteParams);
Object.assign(swiper.originalParams, overwriteParams);
});
on('setTranslate', () => {
if (swiper.params.effect !== 'custom') return;
setTranslate();
});
on('setTransition', (_s, duration) => {
if (swiper.params.effect !== 'custom') return;
setTransition(duration);
});
}
Empty file.
Empty file.
2 changes: 1 addition & 1 deletion src/modules/effect-fade/effect-fade.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export default function Fade({ swiper, extendParams, on }) {
export default function EffectFade({ swiper, extendParams, on }) {
extendParams({
fadeEffect: {
crossFade: false,
Expand Down
4 changes: 2 additions & 2 deletions src/modules/effect-flip/effect-flip.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import $ from '../../shared/dom.js';

export default function Flip({ swiper, extendParams, on }) {
export default function EffectFlip({ swiper, extendParams, on }) {
extendParams({
flipEffect: {
slideShadows: true,
Expand Down Expand Up @@ -90,7 +90,7 @@ export default function Flip({ swiper, extendParams, on }) {
? slides.eq(activeIndex).find(transformEl)
: slides.eq(activeIndex);
// eslint-disable-next-line
$transitionEndTarget.transitionEnd(function onTransitionEnd() {
$transitionEndTarget.transitionEnd(() => {
if (eventTriggered) return;
if (!swiper || swiper.destroyed) return;
eventTriggered = true;
Expand Down
1 change: 1 addition & 0 deletions src/react/params-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const paramsList = [
'cubeEffect',
'fadeEffect',
'flipEffect',
'customEffect',
'hashNavigation',
'history',
'keyboard',
Expand Down
1 change: 1 addition & 0 deletions src/svelte/params-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const paramsList = [
'cubeEffect',
'fadeEffect',
'flipEffect',
'customEffect',
'hashNavigation',
'history',
'keyboard',
Expand Down
54 changes: 54 additions & 0 deletions src/types/modules/effect-custom.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { CSSSelector } from '../shared';

interface CustomEffectTransform {
translate: string[] | number[];
rotate: number[];
opacity: number;
scale: number;
}

export interface CustomEffectMethods {}

export interface CustomEffectEvents {}

export interface CustomEffectOptions {
/**
* Previous slide transformations. Accepts object of the following type:
* ```
* {
* // Array with translate X, Y and Z values
* translate: string[] | number[];
* // Array with rotate X, Y and Z values (in deg)
* rotate: number[];
* // Slide opacity
* opacity: number;
* // Slide scale
* scale: number;
* }
* ```
*
*/
prev?: CustomEffectTransform;
/**
* Next slide transformations. ```
* {
* // Array with translate X, Y and Z values
* translate: string[] | number[];
* // Array with rotate X, Y and Z values (in deg)
* rotate: number[];
* // Slide opacity
* opacity: number;
* // Slide scale
* scale: number;
* }
* ```
*
*/
next?: CustomEffectTransform;
/**
* CSS selector of the element inside of the slide to transform instead of the slide itself. Useful to use with cssMode
*
* @default null
*/
transformEl?: CSSSelector;
}
2 changes: 2 additions & 0 deletions src/types/swiper-class.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { CoverflowEffectMethods } from './modules/effect-coverflow';
import { CubeEffectMethods } from './modules/effect-cube';
import { FadeEffectMethods } from './modules/effect-fade';
import { FlipEffectMethods } from './modules/effect-flip';
import { CustomEffectMethods } from './modules/effect-custom';
import { HashNavigationMethods } from './modules/hash-navigation';
import { HistoryMethods } from './modules/history';
import { KeyboardMethods } from './modules/keyboard';
Expand Down Expand Up @@ -399,6 +400,7 @@ interface Swiper extends SwiperClass<SwiperEvents> {
cubeEffect: CubeEffectMethods;
fadeEffect: FadeEffectMethods;
flipEffect: FlipEffectMethods;
customEffect: CustomEffectMethods;
hashNavigation: HashNavigationMethods;
history: HistoryMethods;
keyboard: KeyboardMethods;
Expand Down
2 changes: 2 additions & 0 deletions src/types/swiper-events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { CoverflowEffectEvents } from './modules/effect-coverflow';
import { CubeEffectEvents } from './modules/effect-cube';
import { FadeEffectEvents } from './modules/effect-fade';
import { FlipEffectEvents } from './modules/effect-flip';
import { CustomEffectEvents } from './modules/effect-custom';
import { HashNavigationEvents } from './modules/hash-navigation';
import { HistoryEvents } from './modules/history';
import { KeyboardEvents } from './modules/keyboard';
Expand Down Expand Up @@ -343,6 +344,7 @@ interface SwiperEvents extends CoverflowEffectEvents {}
interface SwiperEvents extends CubeEffectEvents {}
interface SwiperEvents extends FadeEffectEvents {}
interface SwiperEvents extends FlipEffectEvents {}
interface SwiperEvents extends CustomEffectEvents {}
interface SwiperEvents extends HashNavigationEvents {}
interface SwiperEvents extends HistoryEvents {}
interface SwiperEvents extends KeyboardEvents {}
Expand Down
27 changes: 25 additions & 2 deletions src/types/swiper-options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { CoverflowEffectOptions } from './modules/effect-coverflow';
import { CubeEffectOptions } from './modules/effect-cube';
import { FadeEffectOptions } from './modules/effect-fade';
import { FlipEffectOptions } from './modules/effect-flip';
import { CustomEffectOptions } from './modules/effect-custom';
import { HashNavigationOptions } from './modules/hash-navigation';
import { HistoryOptions } from './modules/history';
import { KeyboardOptions } from './modules/keyboard';
Expand Down Expand Up @@ -172,11 +173,11 @@ export interface SwiperOptions {
uniqueNavElements?: boolean;

/**
* Transition effect. Can be `'slide'`, `'fade'`, `'cube'`, `'coverflow'` or `'flip'`
* Transition effect. Can be `'slide'`, `'fade'`, `'cube'`, `'coverflow'`, `'flip'` or `'custom'`
*
* @default 'slide'
*/
effect?: 'slide' | 'fade' | 'cube' | 'coverflow' | 'flip';
effect?: 'slide' | 'fade' | 'cube' | 'coverflow' | 'flip' | 'custom';

/**
* Fire Transition/SlideChange/Start/End events on swiper initialization.
Expand Down Expand Up @@ -946,6 +947,28 @@ export interface SwiperOptions {
*/
flipEffect?: FlipEffectOptions;

/**
* Object with Custom-effect parameters
*
* @example
* ```js
* const swiper = new Swiper('.swiper-container', {
* effect: 'custom',
* customEffect: {
* prev: {
* // will set `translateZ(-400px)` on previous slides
* translate: [0, 0, -400],
* },
* next: {
* // will set `translateX(100%)` on next slides
* translate: ['100%', 0, 0],
* },
* },
* });
* ```
*/
customEffect?: CustomEffectOptions;

/**
* Enables hash url navigation to for slides.
* Object with hash navigation parameters or boolean `true` to enable with default settings
Expand Down
1 change: 1 addition & 0 deletions src/vue/params-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ const paramsList = [
'cubeEffect',
'fadeEffect',
'flipEffect',
'customEffect',
'hashNavigation',
'history',
'keyboard',
Expand Down
5 changes: 5 additions & 0 deletions src/vue/swiper-vue.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
CubeEffectOptions,
FadeEffectOptions,
FlipEffectOptions,
CustomEffectOptions,
HashNavigationOptions,
HistoryOptions,
KeyboardOptions,
Expand Down Expand Up @@ -384,6 +385,10 @@ declare const Swiper: DefineComponent<
type: PropType<FlipEffectOptions>;
default: undefined;
};
customEffect: {
type: PropType<CustomEffectOptions>;
default: undefined;
};
hashNavigation: {
type: PropType<HashNavigationOptions | boolean>;
default: undefined;
Expand Down
1 change: 1 addition & 0 deletions src/vue/swiper.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const Swiper = {
cubeEffect: { type: Object, default: undefined },
fadeEffect: { type: Object, default: undefined },
flipEffect: { type: Object, default: undefined },
customEffect: { type: Object, default: undefined },
hashNavigation: { type: [Boolean, Object], default: undefined },
history: { type: [Boolean, Object], default: undefined },
keyboard: { type: [Boolean, Object], default: undefined },
Expand Down

0 comments on commit f72f5ba

Please sign in to comment.