Skip to content

Commit 5eed813

Browse files
committed
feat: allow to register custom transformers
1 parent e7dcc88 commit 5eed813

File tree

7 files changed

+100
-85
lines changed

7 files changed

+100
-85
lines changed

packages/ui-pager/blueprint.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,20 @@ Vue.use(Pager);
112112
- [Static Pager](demo-snippets/vue/StaticPager.vue)
113113
- A simple pager example using static content.
114114
- [Basic Pager](demo-snippets/vue/BasicPager.vue)
115-
- A simple pager example using dynamic content.
115+
- A simple pager example using dynamic content.
116+
117+
118+
## Custom Transformer
119+
120+
You can define custom transformer for iOS/Android
121+
122+
You can follow the `Scale` example for [iOS](src/ui-pager/transformers/Scale.ios.ts) and [Android](src/ui-pager/transformers/Scale.android.ts) to create your custom transformer.
123+
124+
Then you can register your transformer on app start with (this example registered the included but not registered Scale transformer):
125+
```ts
126+
import { Pager } from '@nativescript-community/ui-pager';
127+
import transformer from '@nativescript-community/ui-pager/transformers/Scale';
128+
129+
Pager.registerTransformer('scale', transformer)
130+
```
131+
Then you can use that transformer with the `transformer` property of `Pager`

src/ui-pager/index.android.ts

Lines changed: 6 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,9 @@ export class Pager extends PagerBase {
5858
lastEvent = 0;
5959
private _lastSpacing = 0;
6060
private _lastPeaking = 0;
61-
private compositeTransformer: any;
62-
private marginTransformer: any;
63-
private _transformers: any[];
64-
private _selectedIndexBeforeLoad = 0;
65-
// private _pager: androidx.viewpager2.widget.ViewPager2;
61+
private compositeTransformer: androidx.viewpager2.widget.CompositePageTransformer;
62+
private marginTransformer: androidx.viewpager2.widget.MarginPageTransformer;
63+
private _transformers: androidx.viewpager2.widget.ViewPager2.PageTransformer[];
6664

6765
constructor() {
6866
super();
@@ -216,9 +214,9 @@ export class Pager extends PagerBase {
216214
this.compositeTransformer.removeTransformer(transformer);
217215
});
218216
for (const transformer of transformsArray) {
219-
if (transformer === Transformer.SCALE) {
220-
initZoomOutPageTransformer();
221-
const nativeTransformer = new ZoomOutPageTransformer();
217+
const nativeTransformerClass = Pager.mRegisteredTransformers[transformer];
218+
if (nativeTransformerClass) {
219+
const nativeTransformer = new nativeTransformerClass();
222220
nativeTransformer.owner = new WeakRef<Pager>(this);
223221
this._transformers.push(nativeTransformer);
224222
this.compositeTransformer.addTransformer(nativeTransformer);
@@ -1000,66 +998,3 @@ function initPagerViewHolder() {
1000998

1001999
PagerViewHolder = PagerViewHolderImpl as any;
10021000
}
1003-
1004-
let ZoomOutPageTransformer;
1005-
1006-
function initZoomOutPageTransformer() {
1007-
if (ZoomOutPageTransformer) {
1008-
return;
1009-
}
1010-
1011-
@NativeClass
1012-
@Interfaces([androidx.viewpager2.widget.ViewPager2.PageTransformer])
1013-
class ZoomOutPageTransformerImpl extends java.lang.Object {
1014-
owner: WeakRef<Pager>;
1015-
1016-
constructor() {
1017-
super();
1018-
return global.__native(this);
1019-
}
1020-
1021-
public transformPage(view, position) {
1022-
const MIN_SCALE = 0.85;
1023-
if (position <= 1 || position >= -1) {
1024-
const scale = Math.max(MIN_SCALE, 1 - Math.abs(position));
1025-
view.setScaleX(scale);
1026-
view.setScaleY(scale);
1027-
} else {
1028-
view.setScaleX(1);
1029-
view.setScaleY(1);
1030-
}
1031-
}
1032-
}
1033-
1034-
ZoomOutPageTransformer = ZoomOutPageTransformerImpl as any;
1035-
}
1036-
1037-
let ZoomInPageTransformer;
1038-
1039-
function initZoomInPageTransformer() {
1040-
if (ZoomInPageTransformer) {
1041-
return;
1042-
}
1043-
1044-
@NativeClass
1045-
@Interfaces([androidx.viewpager2.widget.ViewPager2.PageTransformer])
1046-
class ZoomInPageTransformerImpl extends java.lang.Object {
1047-
owner: WeakRef<Pager>;
1048-
1049-
constructor() {
1050-
super();
1051-
return global.__native(this);
1052-
}
1053-
1054-
public transformPage(view, position) {
1055-
const scale = position < 0 ? position + 1.0 : Math.abs(1.0 - position);
1056-
view.setScaleX(scale);
1057-
view.setScaleY(scale);
1058-
view.setPivotX(view.getWidth() * 0.5);
1059-
view.setPivotY(view.getHeight() * 0.5);
1060-
view.setAlpha(view < -1.0 || position > 1.0 ? 0.0 : 1.0 - (scale - 1.0));
1061-
}
1062-
}
1063-
1064-
ZoomInPageTransformer = ZoomInPageTransformerImpl as any;
1065-
}

src/ui-pager/index.common.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ export abstract class PagerBase extends ContainerView implements AddChildFromBui
109109

110110
abstract refresh(): void;
111111

112+
static mRegisteredTransformers = {};
113+
public static registerTransformer(key: string, transformer) {
114+
PagerBase.mRegisteredTransformers[key] = transformer;
115+
}
116+
112117
public indicator: {
113118
setProgress(position: number, progress: number);
114119
setSelection(index: number, animated?: boolean);

src/ui-pager/index.ios.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,26 +1117,29 @@ class UICollectionViewFlowLinearLayoutImpl extends UICollectionViewFlowLayout {
11171117
const owner = this._owner ? this._owner.get() : null;
11181118
const originalLayoutAttribute = super.layoutAttributesForElementsInRect(rect);
11191119
const visibleLayoutAttributes = [];
1120-
if (owner) {
1121-
if (owner.transformers && owner.transformers.indexOf('scale') > -1) {
1120+
if (owner && owner.transformers) {
1121+
const transformsArray = owner.transformers
1122+
.split(' ')
1123+
.map((s) => Pager.mRegisteredTransformers[s])
1124+
.filter((s) => !!s);
1125+
if (transformsArray.length) {
1126+
const collectionView = this.collectionView;
11221127
const count = originalLayoutAttribute.count;
11231128
for (let i = 0; i < count; i++) {
11241129
const attributes = originalLayoutAttribute.objectAtIndex(i);
11251130
visibleLayoutAttributes[i] = attributes;
1126-
const frame = attributes.frame;
1127-
const width = attributes.frame.size.width * 0.75;
1128-
const height = attributes.frame.size.height * 0.75;
1129-
attributes.frame.size.width = width;
1130-
attributes.frame.size.height = height;
1131-
const spacing = owner.convertToSize(owner.spacing);
1132-
const distance = Math.abs(this.collectionView.contentOffset.x + this.collectionView.contentInset.left + spacing - frame.origin.x);
1133-
const scale = Math.min(Math.max(1 - distance / this.collectionView.bounds.size.width, 0.75), 1);
1134-
attributes.transform = CGAffineTransformScale(attributes.transform, 1, scale);
1131+
for (const transformer of transformsArray) {
1132+
const nativeTransformer = Pager.mRegisteredTransformers[transformer];
1133+
if (nativeTransformer) {
1134+
nativeTransformer(i, attributes, owner, collectionView);
1135+
}
1136+
}
11351137
}
1136-
} else {
1137-
return originalLayoutAttribute;
11381138
}
1139+
} else {
1140+
return originalLayoutAttribute;
11391141
}
1142+
11401143
return visibleLayoutAttributes as any;
11411144
}
11421145

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Pager } from '..';
2+
3+
@NativeClass
4+
@Interfaces([androidx.viewpager2.widget.ViewPager2.PageTransformer])
5+
export default class Scale extends java.lang.Object {
6+
owner: WeakRef<Pager>;
7+
8+
constructor() {
9+
super();
10+
return global.__native(this);
11+
}
12+
13+
public transformPage(view, position) {
14+
const MIN_SCALE = 0.85;
15+
if (position <= 1 || position >= -1) {
16+
const scale = Math.max(MIN_SCALE, 1 - Math.abs(position));
17+
view.setScaleX(scale);
18+
view.setScaleY(scale);
19+
} else {
20+
view.setScaleX(1);
21+
view.setScaleY(1);
22+
}
23+
}
24+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export default function (i, attributes, owner, collectionView) {
2+
const frame = attributes.frame;
3+
const width = attributes.frame.size.width * 0.75;
4+
const height = attributes.frame.size.height * 0.75;
5+
attributes.frame.size.width = width;
6+
attributes.frame.size.height = height;
7+
const spacing = owner.convertToSize(owner.spacing);
8+
const distance = Math.abs(collectionView.contentOffset.x + collectionView.contentInset.left + spacing - frame.origin.x);
9+
const scale = Math.min(Math.max(1 - distance / collectionView.bounds.size.width, 0.75), 1);
10+
attributes.transform = CGAffineTransformScale(attributes.transform, 1, scale);
11+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Pager } from '..';
2+
3+
@NativeClass
4+
@Interfaces([androidx.viewpager2.widget.ViewPager2.PageTransformer])
5+
export default class ZoomInPageTransformer extends java.lang.Object {
6+
owner: WeakRef<Pager>;
7+
8+
constructor() {
9+
super();
10+
return global.__native(this);
11+
}
12+
13+
public transformPage(view, position) {
14+
const scale = position < 0 ? position + 1.0 : Math.abs(1.0 - position);
15+
view.setScaleX(scale);
16+
view.setScaleY(scale);
17+
view.setPivotX(view.getWidth() * 0.5);
18+
view.setPivotY(view.getHeight() * 0.5);
19+
view.setAlpha(view < -1.0 || position > 1.0 ? 0.0 : 1.0 - (scale - 1.0));
20+
}
21+
}

0 commit comments

Comments
 (0)