a zip code crypto-currency system good for red ONLY

picker-column.js 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. (function (factory) {
  2. if (typeof module === "object" && typeof module.exports === "object") {
  3. var v = factory(require, exports);
  4. if (v !== undefined) module.exports = v;
  5. }
  6. else if (typeof define === "function" && define.amd) {
  7. define(["require", "exports", "@angular/core", "../../util/util", "../../config/config", "../../platform/dom-controller", "../../tap-click/haptic", "./picker-options", "../../platform/platform", "../../util/dom", "../../gestures/ui-event-manager"], factory);
  8. }
  9. })(function (require, exports) {
  10. "use strict";
  11. Object.defineProperty(exports, "__esModule", { value: true });
  12. var core_1 = require("@angular/core");
  13. var util_1 = require("../../util/util");
  14. var config_1 = require("../../config/config");
  15. var dom_controller_1 = require("../../platform/dom-controller");
  16. var haptic_1 = require("../../tap-click/haptic");
  17. var picker_options_1 = require("./picker-options");
  18. var platform_1 = require("../../platform/platform");
  19. var dom_1 = require("../../util/dom");
  20. var ui_event_manager_1 = require("../../gestures/ui-event-manager");
  21. /**
  22. * @hidden
  23. */
  24. var PickerColumnCmp = (function () {
  25. function PickerColumnCmp(config, _plt, elementRef, _zone, _haptic, plt, domCtrl) {
  26. this._plt = _plt;
  27. this.elementRef = elementRef;
  28. this._zone = _zone;
  29. this._haptic = _haptic;
  30. this.y = 0;
  31. this.pos = [];
  32. this.startY = null;
  33. this.ionChange = new core_1.EventEmitter();
  34. this.events = new ui_event_manager_1.UIEventManager(plt);
  35. this.rotateFactor = config.getNumber('pickerRotateFactor', 0);
  36. this.scaleFactor = config.getNumber('pickerScaleFactor', 1);
  37. this.decelerateFunc = this.decelerate.bind(this);
  38. this.debouncer = domCtrl.debouncer();
  39. }
  40. PickerColumnCmp.prototype.ngAfterViewInit = function () {
  41. // get the scrollable element within the column
  42. var colEle = this.colEle.nativeElement;
  43. this.colHeight = colEle.clientHeight;
  44. // get the height of one option
  45. this.optHeight = (colEle.firstElementChild ? colEle.firstElementChild.clientHeight : 0);
  46. // Listening for pointer events
  47. this.events.pointerEvents({
  48. element: this.elementRef.nativeElement,
  49. pointerDown: this.pointerStart.bind(this),
  50. pointerMove: this.pointerMove.bind(this),
  51. pointerUp: this.pointerEnd.bind(this),
  52. capture: true,
  53. zone: false
  54. });
  55. };
  56. PickerColumnCmp.prototype.ngOnDestroy = function () {
  57. this._plt.cancelRaf(this.rafId);
  58. this.events.destroy();
  59. };
  60. PickerColumnCmp.prototype.pointerStart = function (ev) {
  61. (void 0) /* console.debug */;
  62. this._haptic.gestureSelectionStart();
  63. // We have to prevent default in order to block scrolling under the picker
  64. // but we DO NOT have to stop propagation, since we still want
  65. // some "click" events to capture
  66. ev.preventDefault();
  67. // cancel any previous raf's that haven't fired yet
  68. this._plt.cancelRaf(this.rafId);
  69. // remember where the pointer started from`
  70. this.startY = dom_1.pointerCoord(ev).y;
  71. // reset everything
  72. this.velocity = 0;
  73. this.pos.length = 0;
  74. this.pos.push(this.startY, Date.now());
  75. var options = this.col.options;
  76. var minY = (options.length - 1);
  77. var maxY = 0;
  78. for (var i = 0; i < options.length; i++) {
  79. if (!options[i].disabled) {
  80. minY = Math.min(minY, i);
  81. maxY = Math.max(maxY, i);
  82. }
  83. }
  84. this.minY = (minY * this.optHeight * -1);
  85. this.maxY = (maxY * this.optHeight * -1);
  86. return true;
  87. };
  88. PickerColumnCmp.prototype.pointerMove = function (ev) {
  89. var _this = this;
  90. ev.preventDefault();
  91. ev.stopPropagation();
  92. var currentY = dom_1.pointerCoord(ev).y;
  93. this.pos.push(currentY, Date.now());
  94. this.debouncer.write(function () {
  95. if (_this.startY === null) {
  96. return;
  97. }
  98. // update the scroll position relative to pointer start position
  99. var y = _this.y + (currentY - _this.startY);
  100. if (y > _this.minY) {
  101. // scrolling up higher than scroll area
  102. y = Math.pow(y, 0.8);
  103. _this.bounceFrom = y;
  104. }
  105. else if (y < _this.maxY) {
  106. // scrolling down below scroll area
  107. y += Math.pow(_this.maxY - y, 0.9);
  108. _this.bounceFrom = y;
  109. }
  110. else {
  111. _this.bounceFrom = 0;
  112. }
  113. _this.update(y, 0, false, false);
  114. var currentIndex = Math.max(Math.abs(Math.round(y / _this.optHeight)), 0);
  115. if (currentIndex !== _this.lastTempIndex) {
  116. // Trigger a haptic event for physical feedback that the index has changed
  117. _this._haptic.gestureSelectionChanged();
  118. _this.lastTempIndex = currentIndex;
  119. }
  120. });
  121. };
  122. PickerColumnCmp.prototype.pointerEnd = function (ev) {
  123. ev.preventDefault();
  124. this.debouncer.cancel();
  125. if (this.startY === null) {
  126. return;
  127. }
  128. (void 0) /* console.debug */;
  129. this.velocity = 0;
  130. if (this.bounceFrom > 0) {
  131. // bounce back up
  132. this.update(this.minY, 100, true, true);
  133. return;
  134. }
  135. else if (this.bounceFrom < 0) {
  136. // bounce back down
  137. this.update(this.maxY, 100, true, true);
  138. return;
  139. }
  140. var endY = dom_1.pointerCoord(ev).y;
  141. this.pos.push(endY, Date.now());
  142. var endPos = (this.pos.length - 1);
  143. var startPos = endPos;
  144. var timeRange = (Date.now() - 100);
  145. // move pointer to position measured 100ms ago
  146. for (var i = endPos; i > 0 && this.pos[i] > timeRange; i -= 2) {
  147. startPos = i;
  148. }
  149. if (startPos !== endPos) {
  150. // compute relative movement between these two points
  151. var timeOffset = (this.pos[endPos] - this.pos[startPos]);
  152. var movedTop = (this.pos[startPos - 1] - this.pos[endPos - 1]);
  153. // based on XXms compute the movement to apply for each render step
  154. var velocity = ((movedTop / timeOffset) * picker_options_1.FRAME_MS);
  155. this.velocity = util_1.clamp(-picker_options_1.MAX_PICKER_SPEED, velocity, picker_options_1.MAX_PICKER_SPEED);
  156. }
  157. if (Math.abs(endY - this.startY) > 3) {
  158. var y = this.y + (endY - this.startY);
  159. this.update(y, 0, true, true);
  160. }
  161. this.startY = null;
  162. this.decelerate();
  163. };
  164. PickerColumnCmp.prototype.decelerate = function () {
  165. var y = 0;
  166. if (isNaN(this.y) || !this.optHeight) {
  167. // fallback in case numbers get outta wack
  168. this.update(y, 0, true, true);
  169. this._haptic.gestureSelectionEnd();
  170. }
  171. else if (Math.abs(this.velocity) > 0) {
  172. // still decelerating
  173. this.velocity *= picker_options_1.DECELERATION_FRICTION;
  174. // do not let it go slower than a velocity of 1
  175. this.velocity = (this.velocity > 0)
  176. ? Math.max(this.velocity, 1)
  177. : Math.min(this.velocity, -1);
  178. y = Math.round(this.y - this.velocity);
  179. if (y > this.minY) {
  180. // whoops, it's trying to scroll up farther than the options we have!
  181. y = this.minY;
  182. this.velocity = 0;
  183. }
  184. else if (y < this.maxY) {
  185. // gahh, it's trying to scroll down farther than we can!
  186. y = this.maxY;
  187. this.velocity = 0;
  188. }
  189. var notLockedIn = (y % this.optHeight !== 0 || Math.abs(this.velocity) > 1);
  190. this.update(y, 0, true, !notLockedIn);
  191. if (notLockedIn) {
  192. // isn't locked in yet, keep decelerating until it is
  193. this.rafId = this._plt.raf(this.decelerateFunc);
  194. }
  195. }
  196. else if (this.y % this.optHeight !== 0) {
  197. // needs to still get locked into a position so options line up
  198. var currentPos = Math.abs(this.y % this.optHeight);
  199. // create a velocity in the direction it needs to scroll
  200. this.velocity = (currentPos > (this.optHeight / 2) ? 1 : -1);
  201. this._haptic.gestureSelectionEnd();
  202. this.decelerate();
  203. }
  204. var currentIndex = Math.max(Math.abs(Math.round(y / this.optHeight)), 0);
  205. if (currentIndex !== this.lastTempIndex) {
  206. // Trigger a haptic event for physical feedback that the index has changed
  207. this._haptic.gestureSelectionChanged();
  208. }
  209. this.lastTempIndex = currentIndex;
  210. };
  211. PickerColumnCmp.prototype.optClick = function (ev, index) {
  212. if (!this.velocity) {
  213. ev.preventDefault();
  214. ev.stopPropagation();
  215. this.setSelected(index, 150);
  216. }
  217. };
  218. PickerColumnCmp.prototype.setSelected = function (selectedIndex, duration) {
  219. // if there is a selected index, then figure out it's y position
  220. // if there isn't a selected index, then just use the top y position
  221. var y = (selectedIndex > -1) ? ((selectedIndex * this.optHeight) * -1) : 0;
  222. this._plt.cancelRaf(this.rafId);
  223. this.velocity = 0;
  224. // so what y position we're at
  225. this.update(y, duration, true, true);
  226. };
  227. PickerColumnCmp.prototype.update = function (y, duration, saveY, emitChange) {
  228. // ensure we've got a good round number :)
  229. y = Math.round(y);
  230. var i;
  231. var button;
  232. var opt;
  233. var optOffset;
  234. var visible;
  235. var translateX;
  236. var translateY;
  237. var translateZ;
  238. var rotateX;
  239. var transform;
  240. var selected;
  241. var parent = this.colEle.nativeElement;
  242. var children = parent.children;
  243. var length = children.length;
  244. var selectedIndex = this.col.selectedIndex = Math.min(Math.max(Math.round(-y / this.optHeight), 0), length - 1);
  245. var durationStr = (duration === 0) ? null : duration + 'ms';
  246. var scaleStr = "scale(" + this.scaleFactor + ")";
  247. for (i = 0; i < length; i++) {
  248. button = children[i];
  249. opt = this.col.options[i];
  250. optOffset = (i * this.optHeight) + y;
  251. visible = true;
  252. transform = '';
  253. if (this.rotateFactor !== 0) {
  254. rotateX = optOffset * this.rotateFactor;
  255. if (Math.abs(rotateX) > 90) {
  256. visible = false;
  257. }
  258. else {
  259. translateX = 0;
  260. translateY = 0;
  261. translateZ = 90;
  262. transform = "rotateX(" + rotateX + "deg) ";
  263. }
  264. }
  265. else {
  266. translateX = 0;
  267. translateZ = 0;
  268. translateY = optOffset;
  269. if (Math.abs(translateY) > 170) {
  270. visible = false;
  271. }
  272. }
  273. selected = selectedIndex === i;
  274. if (visible) {
  275. transform += "translate3d(0px," + translateY + "px," + translateZ + "px) ";
  276. if (this.scaleFactor !== 1 && !selected) {
  277. transform += scaleStr;
  278. }
  279. }
  280. else {
  281. transform = 'translate3d(-9999px,0px,0px)';
  282. }
  283. // Update transition duration
  284. if (duration !== opt._dur) {
  285. opt._dur = duration;
  286. button.style[this._plt.Css.transitionDuration] = durationStr;
  287. }
  288. // Update transform
  289. if (transform !== opt._trans) {
  290. opt._trans = transform;
  291. button.style[this._plt.Css.transform] = transform;
  292. }
  293. // Update selected item
  294. if (selected !== opt._selected) {
  295. opt._selected = selected;
  296. if (selected) {
  297. button.classList.add(picker_options_1.PICKER_OPT_SELECTED);
  298. }
  299. else {
  300. button.classList.remove(picker_options_1.PICKER_OPT_SELECTED);
  301. }
  302. }
  303. }
  304. this.col.prevSelected = selectedIndex;
  305. if (saveY) {
  306. this.y = y;
  307. }
  308. if (emitChange) {
  309. if (this.lastIndex === undefined) {
  310. // have not set a last index yet
  311. this.lastIndex = this.col.selectedIndex;
  312. }
  313. else if (this.lastIndex !== this.col.selectedIndex) {
  314. // new selected index has changed from the last index
  315. // update the lastIndex and emit that it has changed
  316. this.lastIndex = this.col.selectedIndex;
  317. var ionChange = this.ionChange;
  318. if (ionChange.observers.length > 0) {
  319. this._zone.run(ionChange.emit.bind(ionChange, this.col.options[this.col.selectedIndex]));
  320. }
  321. }
  322. }
  323. };
  324. PickerColumnCmp.prototype.refresh = function () {
  325. var min = this.col.options.length - 1;
  326. var max = 0;
  327. var options = this.col.options;
  328. for (var i = 0; i < options.length; i++) {
  329. if (!options[i].disabled) {
  330. min = Math.min(min, i);
  331. max = Math.max(max, i);
  332. }
  333. }
  334. var selectedIndex = util_1.clamp(min, this.col.selectedIndex, max);
  335. if (this.col.prevSelected !== selectedIndex) {
  336. var y = (selectedIndex * this.optHeight) * -1;
  337. this._plt.cancelRaf(this.rafId);
  338. this.velocity = 0;
  339. this.update(y, 150, true, false);
  340. }
  341. };
  342. PickerColumnCmp.decorators = [
  343. { type: core_1.Component, args: [{
  344. selector: '.picker-col',
  345. template: '<div *ngIf="col.prefix" class="picker-prefix" [style.width]="col.prefixWidth">{{col.prefix}}</div>' +
  346. '<div class="picker-opts" #colEle [style.max-width]="col.optionsWidth">' +
  347. '<button *ngFor="let o of col.options; let i=index"' +
  348. '[class.picker-opt-disabled]="o.disabled" ' +
  349. 'class="picker-opt" disable-activated (click)="optClick($event, i)">' +
  350. '{{o.text}}' +
  351. '</button>' +
  352. '</div>' +
  353. '<div *ngIf="col.suffix" class="picker-suffix" [style.width]="col.suffixWidth">{{col.suffix}}</div>',
  354. host: {
  355. '[style.max-width]': 'col.columnWidth',
  356. '[class.picker-opts-left]': 'col.align=="left"',
  357. '[class.picker-opts-right]': 'col.align=="right"',
  358. }
  359. },] },
  360. ];
  361. /** @nocollapse */
  362. PickerColumnCmp.ctorParameters = function () { return [
  363. { type: config_1.Config, },
  364. { type: platform_1.Platform, },
  365. { type: core_1.ElementRef, },
  366. { type: core_1.NgZone, },
  367. { type: haptic_1.Haptic, },
  368. { type: platform_1.Platform, },
  369. { type: dom_controller_1.DomController, },
  370. ]; };
  371. PickerColumnCmp.propDecorators = {
  372. 'colEle': [{ type: core_1.ViewChild, args: ['colEle',] },],
  373. 'col': [{ type: core_1.Input },],
  374. 'ionChange': [{ type: core_1.Output },],
  375. };
  376. return PickerColumnCmp;
  377. }());
  378. exports.PickerColumnCmp = PickerColumnCmp;
  379. });
  380. //# sourceMappingURL=picker-column.js.map