Add mempool special block animation.
This commit is contained in:
parent
46a2854f67
commit
a3de75ebf4
@ -130,12 +130,11 @@ export const languages: Language[] = [
|
||||
{ code: 'zh', name: '中文' }, // Chinese
|
||||
];
|
||||
|
||||
|
||||
export const specialBlocks = {
|
||||
'708998': {
|
||||
labelEvent: '🌱 Taproot Activated!',
|
||||
'709632': {
|
||||
labelEvent: '🌱 Taproot activated!',
|
||||
},
|
||||
'840000': {
|
||||
labelEvent: '🥳 Halving Event!',
|
||||
labelEvent: '🥳 Halving',
|
||||
}
|
||||
};
|
||||
|
@ -120,33 +120,3 @@
|
||||
50% {opacity: 1.0;}
|
||||
100% {opacity: 0.7;}
|
||||
}
|
||||
|
||||
// Blinking block
|
||||
@keyframes shadowyBackground {
|
||||
0% {
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, 1);
|
||||
transform: rotate(0deg) translateY(0px);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(3deg) translateY(5px);
|
||||
}
|
||||
50% {
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, .3);
|
||||
transform: rotate(0deg) translateY(0px);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(-3deg) translateY(5px);
|
||||
}
|
||||
100% {
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, 1);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
.blink-bg {
|
||||
color: #fff;
|
||||
background: repeating-linear-gradient(rgb(45, 51, 72), rgb(45, 51, 72) 0.163525%, rgb(16, 95, 176) 100%, rgb(147, 57, 244) 0.163525%) !important;
|
||||
animation: shadowyBackground 1s infinite;
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, 1);
|
||||
transition: 100ms all ease-in;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
<ng-container *ngIf="(loadingBlocks$ | async) === false; else loadingBlocks">
|
||||
<div class="mempool-blocks-container" *ngIf="(timeAvg$ | async) as timeAvg;">
|
||||
<div class="flashing">
|
||||
<div class="flashing">
|
||||
<ng-template ngFor let-projectedBlock [ngForOf]="mempoolBlocks$ | async" let-i="index" [ngForTrackBy]="trackByFn">
|
||||
<div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="mempoolBlockStyles[i]">
|
||||
<div class="bitcoin-block text-center mempool-block" id="mempool-block-{{ i }}" [ngStyle]="mempoolBlockStyles[i]" [class.blink-bg]="projectedBlock.blink">
|
||||
<a [routerLink]="['/mempool-block/' | relativeUrl, i]" class="blockLink"> </a>
|
||||
<div class="block-body">
|
||||
<div class="fees">
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
.flashing {
|
||||
animation: opacityPulse 2s ease-out;
|
||||
animation-iteration-count: infinite;
|
||||
animation-iteration-count: infinite;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
}
|
||||
|
||||
.bitcoin-block::after {
|
||||
content: '';
|
||||
content: '';
|
||||
width: 125px;
|
||||
height: 24px;
|
||||
position:absolute;
|
||||
@ -68,7 +68,7 @@
|
||||
left: -20px;
|
||||
background-color: #232838;
|
||||
transform:skew(40deg);
|
||||
transform-origin:top;
|
||||
transform-origin:top;
|
||||
}
|
||||
|
||||
.bitcoin-block::before {
|
||||
@ -78,18 +78,18 @@
|
||||
position: absolute;
|
||||
top: -12px;
|
||||
left: -20px;
|
||||
background-color: #191c27;
|
||||
|
||||
background-color: #191c27;
|
||||
|
||||
transform: skewY(50deg);
|
||||
transform-origin: top;
|
||||
transform-origin: top;
|
||||
}
|
||||
|
||||
.mempool-block.bitcoin-block::after {
|
||||
background-color: #403834;
|
||||
background-color: #403834;
|
||||
}
|
||||
|
||||
.mempool-block.bitcoin-block::before {
|
||||
background-color: #2d2825;
|
||||
background-color: #2d2825;
|
||||
}
|
||||
|
||||
.black-background {
|
||||
@ -102,8 +102,8 @@
|
||||
position: relative;
|
||||
right: 75px;
|
||||
top: 140px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 35px solid transparent;
|
||||
border-right: 35px solid transparent;
|
||||
border-bottom: 35px solid #FFF;
|
||||
|
@ -5,6 +5,8 @@ import { StateService } from 'src/app/services/state.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { take, map, switchMap, share } from 'rxjs/operators';
|
||||
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
||||
import { specialBlocks } from 'src/app/app.constants';
|
||||
import { Block } from 'src/app/interfaces/electrs.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-mempool-blocks',
|
||||
@ -13,12 +15,13 @@ import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
|
||||
specialBlocks = specialBlocks;
|
||||
mempoolBlocks: MempoolBlock[] = [];
|
||||
mempoolEmptyBlocks: MempoolBlock[] = this.mountEmptyBlocks();
|
||||
mempoolBlocks$: Observable<MempoolBlock[]>;
|
||||
timeAvg$: Observable<number>;
|
||||
loadingBlocks$: Observable<boolean>;
|
||||
blocksSubscription: Subscription;
|
||||
|
||||
mempoolBlocksFull: MempoolBlock[] = [];
|
||||
mempoolBlockStyles = [];
|
||||
@ -74,26 +77,25 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
fromEvent(window, 'resize')
|
||||
)
|
||||
.pipe(
|
||||
switchMap(() => this.stateService.mempoolBlocks$),
|
||||
map((blocks) => {
|
||||
if (!blocks.length) {
|
||||
return [{ index: 0, blockSize: 0, blockVSize: 0, feeRange: [0, 0], medianFee: 0, nTx: 0, totalFees: 0 }];
|
||||
}
|
||||
return blocks;
|
||||
}),
|
||||
map((blocks) => {
|
||||
blocks.forEach((block, i) => {
|
||||
block.index = this.blockIndex + i;
|
||||
});
|
||||
const stringifiedBlocks = JSON.stringify(blocks);
|
||||
this.mempoolBlocksFull = JSON.parse(stringifiedBlocks);
|
||||
this.mempoolBlocks = this.reduceMempoolBlocksToFitScreen(JSON.parse(stringifiedBlocks));
|
||||
this.updateMempoolBlockStyles();
|
||||
this.calculateTransactionPosition();
|
||||
return this.mempoolBlocks;
|
||||
})
|
||||
);
|
||||
switchMap(() => combineLatest([
|
||||
this.stateService.blocks$.pipe(map(([block]) => block)),
|
||||
this.stateService.mempoolBlocks$
|
||||
])),
|
||||
map(([lastBlock, mempoolBlocks]) => {
|
||||
mempoolBlocks.forEach((block, i) => {
|
||||
block.index = this.blockIndex + i;
|
||||
block.height = lastBlock.height + i + 1;
|
||||
block.blink = specialBlocks[block.height] ? true : false;
|
||||
});
|
||||
const stringifiedBlocks = JSON.stringify(mempoolBlocks);
|
||||
this.mempoolBlocksFull = JSON.parse(stringifiedBlocks);
|
||||
this.mempoolBlocks = this.reduceMempoolBlocksToFitScreen(JSON.parse(stringifiedBlocks));
|
||||
this.updateMempoolBlockStyles();
|
||||
this.calculateTransactionPosition();
|
||||
|
||||
return this.mempoolBlocks;
|
||||
})
|
||||
);
|
||||
|
||||
this.timeAvg$ = timer(0, 1000)
|
||||
.pipe(
|
||||
@ -118,7 +120,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||
} else {
|
||||
timeAvgMins += Math.abs(timeAvgDiff);
|
||||
}
|
||||
|
||||
|
||||
return timeAvgMins * 60 * 1000;
|
||||
})
|
||||
);
|
||||
|
@ -26,6 +26,8 @@ export interface WebsocketResponse {
|
||||
}
|
||||
|
||||
export interface MempoolBlock {
|
||||
blink?: boolean;
|
||||
height?: number;
|
||||
blockSize: number;
|
||||
blockVSize: number;
|
||||
nTx: number;
|
||||
|
@ -941,3 +941,35 @@ th {
|
||||
width: 220px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Blinking block
|
||||
@keyframes shadowyBackground {
|
||||
0% {
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, 1);
|
||||
transform: rotate(0deg) translateY(0px);
|
||||
}
|
||||
25% {
|
||||
transform: rotate(3deg) translateY(5px);
|
||||
}
|
||||
50% {
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, .3);
|
||||
transform: rotate(0deg) translateY(0px);
|
||||
}
|
||||
75% {
|
||||
transform: rotate(-3deg) translateY(5px);
|
||||
}
|
||||
100% {
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, 1);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
|
||||
.blink-bg {
|
||||
color: #fff;
|
||||
background: repeating-linear-gradient(rgb(45, 51, 72), rgb(45, 51, 72) 0.163525%, rgb(16, 95, 176) 100%, rgb(147, 57, 244) 0.163525%) !important;
|
||||
animation: shadowyBackground 1s infinite;
|
||||
box-shadow: -10px -15px 75px rgba(#5E35B1, 1);
|
||||
transition: 100ms all ease-in;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user