mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
170 lines
4.1 KiB
JavaScript
170 lines
4.1 KiB
JavaScript
import {Component, Template, Inject, Parent, NgElement} from 'angular2/angular2';
|
|
import {Ion} from '../ion';
|
|
import {IonConfig} from '../../config';
|
|
import {SlideEdgeGesture} from '../../core/gestures/slide-edge-gesture';
|
|
import * as util from '../../util';
|
|
|
|
export var asideConfig = new IonConfig('aside');
|
|
|
|
// TODO defaults or bindings?
|
|
asideConfig.set({
|
|
side: 'left',
|
|
dragThreshold: 50
|
|
})
|
|
|
|
@Component({
|
|
selector: 'ion-aside',
|
|
bind: {
|
|
side: 'side',
|
|
dragThreshold: 'dragThreshold'
|
|
}
|
|
})
|
|
@Template({
|
|
inline: `<content></content>`
|
|
})
|
|
export class Aside {
|
|
constructor(
|
|
@Parent() asideParent: AsideParent,
|
|
@NgElement() element: NgElement
|
|
) {
|
|
this.domElement = element.domElement;
|
|
|
|
this._drag = {};
|
|
|
|
this.domElement.addEventListener('transitionend', ev => {
|
|
this.setChanging(false);
|
|
})
|
|
|
|
let gestureConstructor = {
|
|
left: LeftAsideSlideGesture,
|
|
top: TopAsideSlideGesture,
|
|
bottom: BottomAsideSlideGesture,
|
|
right: RightAsideSlideGesture
|
|
};
|
|
|
|
|
|
// TODO: remove this. setTimeout has to be done so the bindings can be applied
|
|
setTimeout(() => {
|
|
// asideConfig.invoke(this);
|
|
this.domElement.classList.add(this.side);
|
|
this.gesture = new gestureConstructor[this.side](this, asideParent.domElement);
|
|
this.gesture.listen();
|
|
});
|
|
}
|
|
setSliding(isSliding) {
|
|
this.domElement.classList[isSliding ? 'add' : 'remove']('sliding');
|
|
}
|
|
setChanging(isChanging) {
|
|
if (isChanging !== this.isChanging) {
|
|
this.isChanging = isChanging;
|
|
this.domElement.classList[isChanging ? 'add' : 'remove']('changing');
|
|
}
|
|
}
|
|
setOpen(isOpen) {
|
|
if (isOpen !== this.isOpen) {
|
|
this.isOpen = isOpen;
|
|
this.setChanging(true);
|
|
requestAnimationFrame(() => {
|
|
this.domElement.classList[isOpen ? 'add' : 'remove']('open');
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
@Component({
|
|
selector: 'ion-aside-parent'
|
|
})
|
|
@Template({
|
|
inline: '<content></content>'
|
|
})
|
|
export class AsideParent {
|
|
constructor(@NgElement() element: NgElement) {
|
|
this.domElement = element.domElement;
|
|
super();
|
|
}
|
|
}
|
|
|
|
class AsideSlideGesture extends SlideEdgeGesture {
|
|
constructor(aside: Aside, slideElement: Element) {
|
|
this.aside = aside;
|
|
super(slideElement, {
|
|
direction: (aside.side === 'left' || aside.side === 'right') ? 'x' : 'y',
|
|
edge: aside.side || 'left',
|
|
threshold: aside.dragThreshold || 100
|
|
});
|
|
}
|
|
|
|
canStart(ev) {
|
|
// Only restrict edges if the aside is closed
|
|
return this.aside.isOpen ? true : super.canStart(ev);
|
|
}
|
|
|
|
onSlideBeforeStart(slide, ev) {
|
|
this.aside.setSliding(true);
|
|
this.aside.setChanging(true);
|
|
return new Promise(resolve => {
|
|
requestAnimationFrame(resolve);
|
|
});
|
|
}
|
|
onSlide(slide, ev) {
|
|
this.aside.domElement.style.transform = 'translate3d(' + slide.distance + 'px,0,0)';
|
|
}
|
|
onSlideEnd(slide, ev) {
|
|
this.aside.domElement.style.transform = '';
|
|
this.aside.setSliding(false);
|
|
if (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5) {
|
|
this.aside.setOpen(!this.aside.isOpen);
|
|
}
|
|
}
|
|
|
|
getElementStartPos(slide, ev) {
|
|
return this.aside.isOpen ? slide.max : slide.min;
|
|
}
|
|
getSlideBoundaries() {
|
|
return {
|
|
min: 0,
|
|
max: this.aside.domElement.offsetWidth
|
|
};
|
|
}
|
|
}
|
|
|
|
class LeftAsideSlideGesture extends AsideSlideGesture {}
|
|
|
|
class RightAsideSlideGesture extends LeftAsideSlideGesture {
|
|
getElementStartPos(slide, ev) {
|
|
return this.aside.isOpen ? slide.min : slide.max;
|
|
}
|
|
getSlideBoundaries() {
|
|
return {
|
|
min: -this.aside.domElement.offsetWidth,
|
|
max: 0
|
|
};
|
|
}
|
|
|
|
}
|
|
|
|
import Hammer from 'hammer';
|
|
class TopAsideSlideGesture extends AsideSlideGesture {
|
|
onSlide(slide, ev) {
|
|
this.aside.domElement.style.transform = 'translate3d(0,' + slide.distance + 'px,0)';
|
|
}
|
|
getSlideBoundaries() {
|
|
return {
|
|
min: 0,
|
|
max: this.aside.domElement.offsetHeight
|
|
};
|
|
}
|
|
}
|
|
|
|
class BottomAsideSlideGesture extends TopAsideSlideGesture {
|
|
getElementStartPos(slide, ev) {
|
|
return this.aside.isOpen ? slide.min : slide.max;
|
|
}
|
|
getSlideBoundaries() {
|
|
return {
|
|
min: -this.aside.domElement.offsetHeight,
|
|
max: 0
|
|
};
|
|
}
|
|
}
|