Directly on the code, annotations, simple small function, good understanding!
import { Directive,ElementRef,HostBinding,OnInit,Input } from '@angular/core';
import { fromEvent, merge, animationFrameScheduler, generate } from 'rxjs';
import { map, tap, throttleTime, debounceTime } from 'rxjs/operators';
import { TouchService } from './touch.service';
@Directive({
selector: '[dragmove]'
})
export class DragmoveDirective implements OnInit {
@HostBinding('style.left.px') _left: number;
@HostBinding('style.top.px') _top: number;
@HostBinding('style.position') _position: string = 'absolute'; _cacheKey: string; @Input()set dragmove(val: string) {
if (val) {
this._cacheKey = val;
let p = localStorage.getItem(val);
if (p) {
let point = JSON.parse(p);
this._left = point.left;
this._top = point.top;
}
}
}
isStart: boolean = false;
constructor(public ele: ElementRef) {}
ngOnInit() {
this.onDrag();
}
onDrag() {
const mousemove = fromEvent(this.ele.nativeElement, 'mousemove');
const touchmove = fromEvent(this.ele.nativeElement, 'touchmove');
const nodeRect = this.ele.nativeElement.getBoundingClientRect();
const rect = {
height: nodeRect.height,
width: nodeRect.width
};
const move = merge(
mousemove.pipe(
map((evt: MouseEvent) => {
return {
x: evt.clientX,
y: evt.clientY
};
})
),
touchmove.pipe(
map((evt: TouchEvent) => {
return {
x: evt.touches[0].pageX,
y: evt.touches[0].pageY
};
})
),
animationFrameScheduler
).pipe(
map(res => {
this._top = res.y - rect.height / 2;
this._left = res.x - rect.width / 2;
return {
left: this._left,
top: this._top
};
}),
debounceTime(300),
tap(res => this._cacheKey && localStorage.setItem(this._cacheKey, JSON.stringify(res))) ); move.subscribe((res: any) => {}); }}Copy the code
use
<! --> <div class="cube"dragmove></div> <! --> <div class="cube" dragmove="dragmove-1"></div>
Copy the code
- Super compact gesture control
import {
Directive,
OnInit,
ElementRef,
Input,
Output,
EventEmitter
} from '@angular/core';
import { fromEvent } from 'rxjs';
import { map, switchMap, takeUntil, debounceTime, tap } from 'rxjs/operators';
@Directive({
selector: '[swipeMove]'
})
exportSwipeMoveDirective implements OnInit {// SwipeMoveDirective implements OnInit @output () swipeMove: Emitter<any> = New EventEmitter(); len: number = 10; constructor(public ele: ElementRef) {}ngOnInit() {
this.handler(this.ele.nativeElement);
}
handler(ele: Element) {
let start = fromEvent(ele, 'touchstart');
let move = fromEvent(ele, 'touchmove');
let end = fromEvent(ele, 'touchend');
document.oncontextmenu = () => false;
let t = (evt: TouchEvent) => ({
x: evt.touches[0].pageX,
y: evt.touches[0].pageY,
t: new Date().getTime(),
type: evt.type }); // |start---------------------------- // -----------|move------------------ // --------------------------|end---- // | -- -- -- -- -- -- -- -- -- -- -- -- -- - | start. Pipe (/ / neat map (t), switchMap (poi1 = > move. The pipe (/ / neat map (t), / / until the end takeUntil (end), X, dy: end.y-poi1. y, dt: end.t-poi1. t})), map(res => {// x is leadingif (Math.abs(res.dx) > Math.abs(res.dy)) {
if (res.dx > this.len) return 'right';
else if (res.dx < -this.len) return 'left';
else return 'tap';
} else {
if (res.dy > this.len) return 'down';
else if (res.dy < -this.len) return 'up';
else return 'tap'; } }), tap(res=>this.swipeMove.next(res)), debounceTime(100) ) ) ) .subscribe(res => {}); }}Copy the code
<! --left right up down tap-->
<div class="cube" (swipeMove) ="swipeMove($event)"></div>
Copy the code
summary
The power of RXJS streaming responsive programming