make accelerations magical again
This commit is contained in:
		
							parent
							
								
									fc5b99f93f
								
							
						
					
					
						commit
						b8cfeb579b
					
				@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					<div class="sparkles" #sparkleAnchor>
 | 
				
			||||||
 | 
					  <div *ngFor="let sparkle of sparkles" class="sparkle" [style]="sparkle.style">
 | 
				
			||||||
 | 
					    <span class="inner-sparkle" [style]="sparkle.rotation">+</span>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					.sparkles {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  top: var(--block-size);
 | 
				
			||||||
 | 
					  height: 50px;
 | 
				
			||||||
 | 
					  right: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.sparkle {
 | 
				
			||||||
 | 
					  position: absolute;
 | 
				
			||||||
 | 
					  color: rgba(152, 88, 255, 0.75);
 | 
				
			||||||
 | 
					  opacity: 0;
 | 
				
			||||||
 | 
					  transform: scale(0.8) rotate(0deg);
 | 
				
			||||||
 | 
					  animation: pop ease 2000ms forwards, sparkle ease 500ms infinite;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.inner-sparkle {
 | 
				
			||||||
 | 
					  display: block;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes pop {
 | 
				
			||||||
 | 
					  0% {
 | 
				
			||||||
 | 
					    transform: scale(0.8) rotate(0deg);
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  20% {
 | 
				
			||||||
 | 
					    transform: scale(1) rotate(72deg);
 | 
				
			||||||
 | 
					    opacity: 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  100% {
 | 
				
			||||||
 | 
					    transform: scale(0) rotate(360deg);
 | 
				
			||||||
 | 
					    opacity: 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@keyframes sparkle {
 | 
				
			||||||
 | 
					  0% {
 | 
				
			||||||
 | 
					    color: rgba(152, 88, 255, 0.75);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  50% {
 | 
				
			||||||
 | 
					    color: rgba(198, 162, 255, 0.75);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  100% {
 | 
				
			||||||
 | 
					    color: rgba(152, 88, 255, 0.75);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Component({
 | 
				
			||||||
 | 
					  selector: 'app-acceleration-sparkles',
 | 
				
			||||||
 | 
					  templateUrl: './acceleration-sparkles.component.html',
 | 
				
			||||||
 | 
					  styleUrls: ['./acceleration-sparkles.component.scss'],
 | 
				
			||||||
 | 
					  changeDetection: ChangeDetectionStrategy.OnPush,
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					export class AccelerationSparklesComponent implements OnChanges {
 | 
				
			||||||
 | 
					  @Input() arrow: ElementRef<HTMLDivElement>;
 | 
				
			||||||
 | 
					  @Input() run: boolean = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @ViewChild('sparkleAnchor')
 | 
				
			||||||
 | 
					  sparkleAnchor: ElementRef<HTMLDivElement>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(
 | 
				
			||||||
 | 
					    private cd: ChangeDetectorRef,
 | 
				
			||||||
 | 
					  ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  endTimeout: any;
 | 
				
			||||||
 | 
					  lastSparkle: number = 0;
 | 
				
			||||||
 | 
					  sparkleWidth: number = 0;
 | 
				
			||||||
 | 
					  sparkles: any[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ngOnChanges(changes: SimpleChanges): void {
 | 
				
			||||||
 | 
					    if (changes.run) {
 | 
				
			||||||
 | 
					      if (this.endTimeout) {
 | 
				
			||||||
 | 
					        clearTimeout(this.endTimeout);
 | 
				
			||||||
 | 
					        this.endTimeout = null;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (this.run) {
 | 
				
			||||||
 | 
					        this.doSparkle();
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.endTimeout = setTimeout(() => {
 | 
				
			||||||
 | 
					          this.sparkles = [];
 | 
				
			||||||
 | 
					        }, 2000);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  doSparkle(): void {
 | 
				
			||||||
 | 
					    if (this.run) {
 | 
				
			||||||
 | 
					      const now = performance.now();
 | 
				
			||||||
 | 
					      if (now - this.lastSparkle > 30) {
 | 
				
			||||||
 | 
					        this.lastSparkle = now;
 | 
				
			||||||
 | 
					        if (this.arrow?.nativeElement && this.sparkleAnchor?.nativeElement) {
 | 
				
			||||||
 | 
					          const anchor = this.sparkleAnchor.nativeElement.getBoundingClientRect().right;
 | 
				
			||||||
 | 
					          const right = this.arrow.nativeElement.getBoundingClientRect().right;
 | 
				
			||||||
 | 
					          const dx = (anchor - right) + 37.5;
 | 
				
			||||||
 | 
					          this.sparkles.push({
 | 
				
			||||||
 | 
					            style: {
 | 
				
			||||||
 | 
					              right: dx + 'px',
 | 
				
			||||||
 | 
					              top: (Math.random() * 30) + 'px',
 | 
				
			||||||
 | 
					              animationDelay: (Math.random() * 50) + 'ms',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            rotation: {
 | 
				
			||||||
 | 
					              transform: `rotate(${Math.random() * 360}deg)`,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          while (this.sparkles.length > 100) {
 | 
				
			||||||
 | 
					            this.sparkles.shift();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.cd.markForCheck();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      requestAnimationFrame(() => {
 | 
				
			||||||
 | 
					        this.doSparkle();
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -51,7 +51,8 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </ng-template>
 | 
					      </ng-template>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div *ngIf="arrowVisible" id="arrow-up" [ngStyle]="{'right': rightPosition + (blockWidth * 0.3) + containerOffset + 'px', transition: transition }" [class.blink]="txPosition?.accelerated"></div>
 | 
					    <app-acceleration-sparkles [style]="{ position: 'absolute', right: 0}" [arrow]="arrowElement" [run]="acceleratingArrow"></app-acceleration-sparkles>
 | 
				
			||||||
 | 
					    <div *ngIf="arrowVisible" #arrowUp id="arrow-up" [ngStyle]="{'right': rightPosition + (blockWidth * 0.3) + containerOffset + 'px', transition: transition }" [class.blink]="txPosition?.accelerated"></div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</ng-container>
 | 
					</ng-container>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, HostListener, Input, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core';
 | 
					import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, HostListener, Input, OnChanges, SimpleChanges, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
 | 
				
			||||||
import { Subscription, Observable, of, combineLatest } from 'rxjs';
 | 
					import { Subscription, Observable, of, combineLatest } from 'rxjs';
 | 
				
			||||||
import { MempoolBlock } from '../../interfaces/websocket.interface';
 | 
					import { MempoolBlock } from '../../interfaces/websocket.interface';
 | 
				
			||||||
import { StateService } from '../../services/state.service';
 | 
					import { StateService } from '../../services/state.service';
 | 
				
			||||||
@ -77,6 +77,9 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
  maxArrowPosition = 0;
 | 
					  maxArrowPosition = 0;
 | 
				
			||||||
  rightPosition = 0;
 | 
					  rightPosition = 0;
 | 
				
			||||||
  transition = 'background 2s, right 2s, transform 1s';
 | 
					  transition = 'background 2s, right 2s, transform 1s';
 | 
				
			||||||
 | 
					  @ViewChild('arrowUp')
 | 
				
			||||||
 | 
					  arrowElement: ElementRef<HTMLDivElement>;
 | 
				
			||||||
 | 
					  acceleratingArrow: boolean = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  markIndex: number;
 | 
					  markIndex: number;
 | 
				
			||||||
  txPosition: MempoolPosition;
 | 
					  txPosition: MempoolPosition;
 | 
				
			||||||
@ -201,6 +204,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    this.markBlocksSubscription = this.stateService.markBlock$
 | 
					    this.markBlocksSubscription = this.stateService.markBlock$
 | 
				
			||||||
      .subscribe((state) => {
 | 
					      .subscribe((state) => {
 | 
				
			||||||
 | 
					        const oldTxPosition = this.txPosition;
 | 
				
			||||||
        this.markIndex = undefined;
 | 
					        this.markIndex = undefined;
 | 
				
			||||||
        this.txPosition = undefined;
 | 
					        this.txPosition = undefined;
 | 
				
			||||||
        this.txFeePerVSize = undefined;
 | 
					        this.txFeePerVSize = undefined;
 | 
				
			||||||
@ -209,6 +213,12 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        if (state.mempoolPosition) {
 | 
					        if (state.mempoolPosition) {
 | 
				
			||||||
          this.txPosition = state.mempoolPosition;
 | 
					          this.txPosition = state.mempoolPosition;
 | 
				
			||||||
 | 
					          if (this.txPosition.accelerated && !oldTxPosition.accelerated) {
 | 
				
			||||||
 | 
					            this.acceleratingArrow = true;
 | 
				
			||||||
 | 
					            setTimeout(() => {
 | 
				
			||||||
 | 
					              this.acceleratingArrow = false;
 | 
				
			||||||
 | 
					            }, 2000);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (state.txFeePerVSize) {
 | 
					        if (state.txFeePerVSize) {
 | 
				
			||||||
          this.txFeePerVSize = state.txFeePerVSize;
 | 
					          this.txFeePerVSize = state.txFeePerVSize;
 | 
				
			||||||
 | 
				
			|||||||
@ -100,6 +100,7 @@ import { MempoolErrorComponent } from './components/mempool-error/mempool-error.
 | 
				
			|||||||
import { AccelerationsListComponent } from '../components/acceleration/accelerations-list/accelerations-list.component';
 | 
					import { AccelerationsListComponent } from '../components/acceleration/accelerations-list/accelerations-list.component';
 | 
				
			||||||
import { PendingStatsComponent } from '../components/acceleration/pending-stats/pending-stats.component';
 | 
					import { PendingStatsComponent } from '../components/acceleration/pending-stats/pending-stats.component';
 | 
				
			||||||
import { AccelerationStatsComponent } from '../components/acceleration/acceleration-stats/acceleration-stats.component';
 | 
					import { AccelerationStatsComponent } from '../components/acceleration/acceleration-stats/acceleration-stats.component';
 | 
				
			||||||
 | 
					import { AccelerationSparklesComponent } from '../components/acceleration/sparkles/acceleration-sparkles.component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { BlockViewComponent } from '../components/block-view/block-view.component';
 | 
					import { BlockViewComponent } from '../components/block-view/block-view.component';
 | 
				
			||||||
import { EightBlocksComponent } from '../components/eight-blocks/eight-blocks.component';
 | 
					import { EightBlocksComponent } from '../components/eight-blocks/eight-blocks.component';
 | 
				
			||||||
@ -225,6 +226,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
 | 
				
			|||||||
    AccelerationsListComponent,
 | 
					    AccelerationsListComponent,
 | 
				
			||||||
    AccelerationStatsComponent,
 | 
					    AccelerationStatsComponent,
 | 
				
			||||||
    PendingStatsComponent,
 | 
					    PendingStatsComponent,
 | 
				
			||||||
 | 
					    AccelerationSparklesComponent,
 | 
				
			||||||
    HttpErrorComponent,
 | 
					    HttpErrorComponent,
 | 
				
			||||||
    TwitterWidgetComponent,
 | 
					    TwitterWidgetComponent,
 | 
				
			||||||
    FaucetComponent,
 | 
					    FaucetComponent,
 | 
				
			||||||
@ -355,6 +357,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
 | 
				
			|||||||
    AccelerationsListComponent,
 | 
					    AccelerationsListComponent,
 | 
				
			||||||
    AccelerationStatsComponent,
 | 
					    AccelerationStatsComponent,
 | 
				
			||||||
    PendingStatsComponent,
 | 
					    PendingStatsComponent,
 | 
				
			||||||
 | 
					    AccelerationSparklesComponent,
 | 
				
			||||||
    HttpErrorComponent,
 | 
					    HttpErrorComponent,
 | 
				
			||||||
    TwitterWidgetComponent,
 | 
					    TwitterWidgetComponent,
 | 
				
			||||||
    TwitterLogin,
 | 
					    TwitterLogin,
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user