Advertisement
Guest User

Untitled

a guest
Sep 19th, 2019
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.74 KB | None | 0 0
  1. export class VirtualSliderComponent implements OnChanges, AfterViewInit, OnInit {
  2. @Input() numberItemsToSkip = 2;
  3. @Input() margin = 20;
  4. @Input() itemWidth = 300;
  5. @Input() itemTemplate;
  6. @Input() data = [];
  7. @Input() moveToItemIndex: number;
  8. @Output() scrollEnds = new EventEmitter();
  9. @ContentChildren(VirtualSliderItemDirective, { read: ElementRef }) items
  10. : QueryList<ElementRef<HTMLDivElement>>;
  11. @ViewChild('slides') slidesContainer: ElementRef<HTMLDivElement>;
  12. disabledLeftArrow = true;
  13. disabledRightArrow = false;
  14. isView$ = new BehaviorSubject(false);
  15. isData$ = new BehaviorSubject(false);
  16. isItemIndexToMove$ = new BehaviorSubject(undefined);
  17.  
  18. ngOnChanges(changes) {
  19. if (changes.moveToItemIndex && this.moveToItemIndex) {
  20. this.isItemIndexToMove$.next(true);
  21. }
  22. if (changes.data && this.data) {
  23. this.isData$.next(true);
  24. }
  25. this.disabledRightArrow = false;
  26. }
  27.  
  28. ngAfterViewInit() {
  29. this.isView$.next(true);
  30. }
  31.  
  32. ngOnInit() {
  33. this.subscribeOnViewAndIndexToActivate();
  34. }
  35.  
  36. subscribeOnViewAndIndexToActivate() {
  37. combineLatest(this.isView$, this.isItemIndexToMove$, this.isData$)
  38. .pipe(filter(res => res[0] && res[1] && res[2]))
  39. .subscribe(() => {
  40. setTimeout(() => {
  41. this.moveToSpecificIndexItem(this.moveToItemIndex);
  42. });
  43. });
  44. }
  45.  
  46. moveToSpecificIndexItem(index) {
  47. const position = (this.itemWidth * index) + (this.margin * index);
  48. this.slidesContainer.nativeElement.scrollLeft = position;
  49. }
  50.  
  51. onClickLeft() {
  52. this.slidesContainer.nativeElement.scrollLeft -=
  53. (this.itemWidth * this.numberItemsToSkip) + (this.margin * this.numberItemsToSkip);
  54. }
  55.  
  56. onClickRight() {
  57. this.slidesContainer.nativeElement.scrollLeft +=
  58. (this.itemWidth * this.numberItemsToSkip) + (this.margin * this.numberItemsToSkip);
  59. }
  60.  
  61. onScroll() {
  62. this.disabledLeftArrow = this.slidesContainer.nativeElement.scrollLeft === 0;
  63. this.disabledRightArrow = this.slidesContainer.nativeElement.offsetWidth +
  64. this.slidesContainer.nativeElement.scrollLeft === this.slidesContainer.nativeElement.scrollWidth;
  65. }
  66.  
  67. onScrollEnds(event) {
  68. if (!this.data || !this.data.length) return;
  69. if (event.endIndex !== this.data.length - 1) return;
  70. this.scrollEnds.emit();
  71. }
  72. }
  73.  
  74.  
  75. //////
  76.  
  77. <div class="wrapper">
  78. <div class="click-panel click-panel_left" (click)="onClickLeft()" [ngClass]="{'disabled': disabledLeftArrow}">
  79. <i class="material-icons icon-left">
  80. keyboard_arrow_left
  81. </i>
  82. </div>
  83.  
  84. <div class="slides" #slides (scroll)="onScroll()" #scrollingBlock>
  85. <ng-container *ngIf="data && data.length; else spinner">
  86. <virtual-scroller
  87. [horizontal]="true"
  88. #scroll
  89. [items]="data"
  90. [parentScroll]="scrollingBlock"
  91. (vsEnd)="onScrollEnds($event)">
  92. <ng-container
  93. #sliderItem
  94. *ngFor="let item of scroll.viewPortItems"
  95. appVirtualSliderItem>
  96. <ng-content *ngTemplateOutlet="itemTemplate; context: {$implicit: item}"></ng-content>
  97. </ng-container>
  98. </virtual-scroller>
  99. </ng-container>
  100.  
  101. </div>
  102.  
  103. <div class="click-panel click-panel_right" (click)="onClickRight()" [ngClass]="{'disabled': disabledRightArrow}">
  104. <i class="material-icons icon-right">
  105. keyboard_arrow_right
  106. </i>
  107. </div>
  108. </div>
  109.  
  110. <ng-template #spinner>
  111. <div class="spinner">
  112. <app-spinner></app-spinner>
  113. </div>
  114. </ng-template>
  115. ////
  116.  
  117. @import "../../../../../../shared/styles/color";
  118. @import "../../../../../../shared/styles/mixins";
  119. :host {
  120. width: 100%;
  121. }
  122.  
  123. .wrapper {
  124. display: flex;
  125. align-items: center;
  126. width: 100%;
  127. justify-content: space-between;
  128. i {
  129. font-size: 45px;
  130. cursor: pointer;
  131. color: $color002;
  132. @include transition(color);
  133. }
  134. .icon-left {
  135. margin-left: -15px;
  136. }
  137. .icon-right {
  138. margin-right: -15px;
  139. }
  140. .active {
  141. @include transition(color);
  142. color: $color002;
  143. }
  144. .disabled {
  145. box-shadow: none;
  146. i {
  147. @include transition(color);
  148. color: $color014;
  149. cursor: default;
  150. }
  151. }
  152.  
  153. }
  154.  
  155. .click-panel {
  156. height: 230px;
  157. display: flex;
  158. align-items: center;
  159. user-select: none;
  160. margin-bottom: 20px;
  161. z-index: 1;
  162. &_right {
  163. box-shadow: -11px 0px 20px 11px #1c1e2c;;
  164. }
  165. &_left {
  166. box-shadow: 11px 0px 20px 11px #1c1e2c;;
  167. }
  168. }
  169.  
  170. .content-wrapper {
  171. overflow: hidden;
  172. }
  173.  
  174. .slides {
  175. display: flex;
  176. overflow-x: scroll;
  177. scroll-behavior: smooth;
  178. width: 100%;
  179. padding-bottom: 20px;
  180. &::-webkit-scrollbar {
  181. display: none;
  182. }
  183. }
  184.  
  185. virtual-scroller {
  186. width: 100%;
  187. height: 224px;
  188. }
  189.  
  190. .spinner {
  191. width: 100%;
  192. display: flex;
  193. margin-top: 40px;
  194. align-items: center;
  195. justify-content: center;
  196. }
  197. ///
  198. @Directive({
  199. selector: '[appVirtualSliderItem]'
  200. })
  201. export class VirtualSliderItemDirective {
  202. constructor() {}
  203.  
  204. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement