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
|
{ code: 'zh', name: '中文' }, // Chinese
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
export const specialBlocks = {
|
export const specialBlocks = {
|
||||||
'708998': {
|
'709632': {
|
||||||
labelEvent: '🌱 Taproot Activated!',
|
labelEvent: '🌱 Taproot activated!',
|
||||||
},
|
},
|
||||||
'840000': {
|
'840000': {
|
||||||
labelEvent: '🥳 Halving Event!',
|
labelEvent: '🥳 Halving',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -120,33 +120,3 @@
|
|||||||
50% {opacity: 1.0;}
|
50% {opacity: 1.0;}
|
||||||
100% {opacity: 0.7;}
|
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">
|
<ng-container *ngIf="(loadingBlocks$ | async) === false; else loadingBlocks">
|
||||||
<div class="mempool-blocks-container" *ngIf="(timeAvg$ | async) as timeAvg;">
|
<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">
|
<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>
|
<a [routerLink]="['/mempool-block/' | relativeUrl, i]" class="blockLink"> </a>
|
||||||
<div class="block-body">
|
<div class="block-body">
|
||||||
<div class="fees">
|
<div class="fees">
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
.flashing {
|
.flashing {
|
||||||
animation: opacityPulse 2s ease-out;
|
animation: opacityPulse 2s ease-out;
|
||||||
animation-iteration-count: infinite;
|
animation-iteration-count: infinite;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.bitcoin-block::after {
|
.bitcoin-block::after {
|
||||||
content: '';
|
content: '';
|
||||||
width: 125px;
|
width: 125px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
position:absolute;
|
position:absolute;
|
||||||
@ -68,7 +68,7 @@
|
|||||||
left: -20px;
|
left: -20px;
|
||||||
background-color: #232838;
|
background-color: #232838;
|
||||||
transform:skew(40deg);
|
transform:skew(40deg);
|
||||||
transform-origin:top;
|
transform-origin:top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bitcoin-block::before {
|
.bitcoin-block::before {
|
||||||
@ -78,18 +78,18 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: -12px;
|
top: -12px;
|
||||||
left: -20px;
|
left: -20px;
|
||||||
background-color: #191c27;
|
background-color: #191c27;
|
||||||
|
|
||||||
transform: skewY(50deg);
|
transform: skewY(50deg);
|
||||||
transform-origin: top;
|
transform-origin: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mempool-block.bitcoin-block::after {
|
.mempool-block.bitcoin-block::after {
|
||||||
background-color: #403834;
|
background-color: #403834;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mempool-block.bitcoin-block::before {
|
.mempool-block.bitcoin-block::before {
|
||||||
background-color: #2d2825;
|
background-color: #2d2825;
|
||||||
}
|
}
|
||||||
|
|
||||||
.black-background {
|
.black-background {
|
||||||
@ -102,8 +102,8 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
right: 75px;
|
right: 75px;
|
||||||
top: 140px;
|
top: 140px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-left: 35px solid transparent;
|
border-left: 35px solid transparent;
|
||||||
border-right: 35px solid transparent;
|
border-right: 35px solid transparent;
|
||||||
border-bottom: 35px solid #FFF;
|
border-bottom: 35px solid #FFF;
|
||||||
|
@ -5,6 +5,8 @@ import { StateService } from 'src/app/services/state.service';
|
|||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { take, map, switchMap, share } from 'rxjs/operators';
|
import { take, map, switchMap, share } from 'rxjs/operators';
|
||||||
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
||||||
|
import { specialBlocks } from 'src/app/app.constants';
|
||||||
|
import { Block } from 'src/app/interfaces/electrs.interface';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-mempool-blocks',
|
selector: 'app-mempool-blocks',
|
||||||
@ -13,12 +15,13 @@ import { feeLevels, mempoolFeeColors } from 'src/app/app.constants';
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
||||||
|
specialBlocks = specialBlocks;
|
||||||
mempoolBlocks: MempoolBlock[] = [];
|
mempoolBlocks: MempoolBlock[] = [];
|
||||||
mempoolEmptyBlocks: MempoolBlock[] = this.mountEmptyBlocks();
|
mempoolEmptyBlocks: MempoolBlock[] = this.mountEmptyBlocks();
|
||||||
mempoolBlocks$: Observable<MempoolBlock[]>;
|
mempoolBlocks$: Observable<MempoolBlock[]>;
|
||||||
timeAvg$: Observable<number>;
|
timeAvg$: Observable<number>;
|
||||||
loadingBlocks$: Observable<boolean>;
|
loadingBlocks$: Observable<boolean>;
|
||||||
|
blocksSubscription: Subscription;
|
||||||
|
|
||||||
mempoolBlocksFull: MempoolBlock[] = [];
|
mempoolBlocksFull: MempoolBlock[] = [];
|
||||||
mempoolBlockStyles = [];
|
mempoolBlockStyles = [];
|
||||||
@ -74,26 +77,25 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
|||||||
fromEvent(window, 'resize')
|
fromEvent(window, 'resize')
|
||||||
)
|
)
|
||||||
.pipe(
|
.pipe(
|
||||||
switchMap(() => this.stateService.mempoolBlocks$),
|
switchMap(() => combineLatest([
|
||||||
map((blocks) => {
|
this.stateService.blocks$.pipe(map(([block]) => block)),
|
||||||
if (!blocks.length) {
|
this.stateService.mempoolBlocks$
|
||||||
return [{ index: 0, blockSize: 0, blockVSize: 0, feeRange: [0, 0], medianFee: 0, nTx: 0, totalFees: 0 }];
|
])),
|
||||||
}
|
map(([lastBlock, mempoolBlocks]) => {
|
||||||
return blocks;
|
mempoolBlocks.forEach((block, i) => {
|
||||||
}),
|
block.index = this.blockIndex + i;
|
||||||
map((blocks) => {
|
block.height = lastBlock.height + i + 1;
|
||||||
blocks.forEach((block, i) => {
|
block.blink = specialBlocks[block.height] ? true : false;
|
||||||
block.index = this.blockIndex + i;
|
});
|
||||||
});
|
const stringifiedBlocks = JSON.stringify(mempoolBlocks);
|
||||||
const stringifiedBlocks = JSON.stringify(blocks);
|
this.mempoolBlocksFull = JSON.parse(stringifiedBlocks);
|
||||||
this.mempoolBlocksFull = JSON.parse(stringifiedBlocks);
|
this.mempoolBlocks = this.reduceMempoolBlocksToFitScreen(JSON.parse(stringifiedBlocks));
|
||||||
this.mempoolBlocks = this.reduceMempoolBlocksToFitScreen(JSON.parse(stringifiedBlocks));
|
this.updateMempoolBlockStyles();
|
||||||
this.updateMempoolBlockStyles();
|
this.calculateTransactionPosition();
|
||||||
this.calculateTransactionPosition();
|
|
||||||
return this.mempoolBlocks;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
|
return this.mempoolBlocks;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
this.timeAvg$ = timer(0, 1000)
|
this.timeAvg$ = timer(0, 1000)
|
||||||
.pipe(
|
.pipe(
|
||||||
@ -118,7 +120,7 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
|
|||||||
} else {
|
} else {
|
||||||
timeAvgMins += Math.abs(timeAvgDiff);
|
timeAvgMins += Math.abs(timeAvgDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
return timeAvgMins * 60 * 1000;
|
return timeAvgMins * 60 * 1000;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -26,6 +26,8 @@ export interface WebsocketResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface MempoolBlock {
|
export interface MempoolBlock {
|
||||||
|
blink?: boolean;
|
||||||
|
height?: number;
|
||||||
blockSize: number;
|
blockSize: number;
|
||||||
blockVSize: number;
|
blockVSize: number;
|
||||||
nTx: number;
|
nTx: number;
|
||||||
|
@ -941,3 +941,35 @@ th {
|
|||||||
width: 220px;
|
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