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>
 | 
			
		||||
      </ng-template>
 | 
			
		||||
    </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>
 | 
			
		||||
</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 { MempoolBlock } from '../../interfaces/websocket.interface';
 | 
			
		||||
import { StateService } from '../../services/state.service';
 | 
			
		||||
@ -77,6 +77,9 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
  maxArrowPosition = 0;
 | 
			
		||||
  rightPosition = 0;
 | 
			
		||||
  transition = 'background 2s, right 2s, transform 1s';
 | 
			
		||||
  @ViewChild('arrowUp')
 | 
			
		||||
  arrowElement: ElementRef<HTMLDivElement>;
 | 
			
		||||
  acceleratingArrow: boolean = false;
 | 
			
		||||
 | 
			
		||||
  markIndex: number;
 | 
			
		||||
  txPosition: MempoolPosition;
 | 
			
		||||
@ -201,6 +204,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
 | 
			
		||||
    this.markBlocksSubscription = this.stateService.markBlock$
 | 
			
		||||
      .subscribe((state) => {
 | 
			
		||||
        const oldTxPosition = this.txPosition;
 | 
			
		||||
        this.markIndex = undefined;
 | 
			
		||||
        this.txPosition = undefined;
 | 
			
		||||
        this.txFeePerVSize = undefined;
 | 
			
		||||
@ -209,6 +213,12 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
 | 
			
		||||
        }
 | 
			
		||||
        if (state.mempoolPosition) {
 | 
			
		||||
          this.txPosition = state.mempoolPosition;
 | 
			
		||||
          if (this.txPosition.accelerated && !oldTxPosition.accelerated) {
 | 
			
		||||
            this.acceleratingArrow = true;
 | 
			
		||||
            setTimeout(() => {
 | 
			
		||||
              this.acceleratingArrow = false;
 | 
			
		||||
            }, 2000);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        if (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 { PendingStatsComponent } from '../components/acceleration/pending-stats/pending-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 { EightBlocksComponent } from '../components/eight-blocks/eight-blocks.component';
 | 
			
		||||
@ -225,6 +226,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
 | 
			
		||||
    AccelerationsListComponent,
 | 
			
		||||
    AccelerationStatsComponent,
 | 
			
		||||
    PendingStatsComponent,
 | 
			
		||||
    AccelerationSparklesComponent,
 | 
			
		||||
    HttpErrorComponent,
 | 
			
		||||
    TwitterWidgetComponent,
 | 
			
		||||
    FaucetComponent,
 | 
			
		||||
@ -355,6 +357,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
 | 
			
		||||
    AccelerationsListComponent,
 | 
			
		||||
    AccelerationStatsComponent,
 | 
			
		||||
    PendingStatsComponent,
 | 
			
		||||
    AccelerationSparklesComponent,
 | 
			
		||||
    HttpErrorComponent,
 | 
			
		||||
    TwitterWidgetComponent,
 | 
			
		||||
    TwitterLogin,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user