Add taproot activation fireworks.
This commit is contained in:
parent
033f066abf
commit
46a2854f67
@ -129,3 +129,13 @@ export const languages: Language[] = [
|
||||
{ code: 'vi', name: 'Tiếng Việt' }, // Vietnamese
|
||||
{ code: 'zh', name: '中文' }, // Chinese
|
||||
];
|
||||
|
||||
|
||||
export const specialBlocks = {
|
||||
'708998': {
|
||||
labelEvent: '🌱 Taproot Activated!',
|
||||
},
|
||||
'840000': {
|
||||
labelEvent: '🥳 Halving Event!',
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="blocks-container blockchain-blocks-container" *ngIf="(loadingBlocks$ | async) === false; else loadingBlocksTemplate">
|
||||
<div *ngFor="let block of blocks; let i = index; trackBy: trackByBlocksFn" >
|
||||
<div class="text-center bitcoin-block mined-block blockchain-blocks-{{ i }}" id="bitcoin-block-{{ block.height }}" [ngStyle]="blockStyles[i]">
|
||||
<div class="text-center bitcoin-block mined-block blockchain-blocks-{{ i }}" id="bitcoin-block-{{ block.height }}" [ngStyle]="blockStyles[i]" [class.blink-bg]="(specialBlocks[block.height] !== undefined)">
|
||||
<a [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }" class="blockLink"> </a>
|
||||
<div class="block-height">
|
||||
<a [routerLink]="['/block/' | relativeUrl, block.id]" [state]="{ data: { block: block } }">{{ block.height }}</a>
|
||||
|
@ -111,7 +111,7 @@
|
||||
|
||||
.flashing {
|
||||
animation: opacityPulse 2s ease-out;
|
||||
animation-iteration-count: infinite;
|
||||
animation-iteration-count: infinite;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@ -119,4 +119,34 @@
|
||||
0% {opacity: 0.7;}
|
||||
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,9 @@
|
||||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, Input } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { Block } from 'src/app/interfaces/electrs.interface';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { Router } from '@angular/router';
|
||||
import { specialBlocks } from 'src/app/app.constants';
|
||||
|
||||
@Component({
|
||||
selector: 'app-blockchain-blocks',
|
||||
@ -11,7 +12,7 @@ import { Router } from '@angular/router';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class BlockchainBlocksComponent implements OnInit, OnDestroy {
|
||||
|
||||
specialBlocks = specialBlocks;
|
||||
network = '';
|
||||
blocks: Block[] = [];
|
||||
emptyBlocks: Block[] = this.mountEmptyBlocks();
|
||||
|
@ -1,3 +1,10 @@
|
||||
<ng-container *ngIf="specialEvent">
|
||||
<div class="pyro">
|
||||
<div class="before"></div>
|
||||
<div class="after"></div>
|
||||
</div>
|
||||
<div class="warning-label">{{ eventName }}</div>
|
||||
</ng-container>
|
||||
<div id="blockchain-container" dir="ltr">
|
||||
<app-blockchain></app-blockchain>
|
||||
</div>
|
||||
|
@ -7,5 +7,144 @@
|
||||
}
|
||||
|
||||
#blockchain-container::-webkit-scrollbar {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.warning-label {
|
||||
position: absolute;
|
||||
width: 150px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
padding: 6px 4px;
|
||||
border-radius: 4px;
|
||||
margin-top: -10px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
// Fireworks
|
||||
|
||||
$particles: 50;
|
||||
$width: 500;
|
||||
$height: 500;
|
||||
|
||||
// Create the explosion...
|
||||
$box-shadow: ();
|
||||
$box-shadow2: ();
|
||||
@for $i from 0 through $particles {
|
||||
$box-shadow: $box-shadow,
|
||||
random($width)-$width / 2 + px
|
||||
random($height)-$height / 1.2 + px
|
||||
hsl(random(360), 100, 50);
|
||||
$box-shadow2: $box-shadow2, 0 0 #fff
|
||||
}
|
||||
@mixin keyframes ($animationName) {
|
||||
@-webkit-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
|
||||
@-moz-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
|
||||
@-o-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
|
||||
@-ms-keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
|
||||
@keyframes #{$animationName} {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin animation-delay ($settings) {
|
||||
-moz-animation-delay: $settings;
|
||||
-webkit-animation-delay: $settings;
|
||||
-o-animation-delay: $settings;
|
||||
-ms-animation-delay: $settings;
|
||||
animation-delay: $settings;
|
||||
}
|
||||
|
||||
@mixin animation-duration ($settings) {
|
||||
-moz-animation-duration: $settings;
|
||||
-webkit-animation-duration: $settings;
|
||||
-o-animation-duration: $settings;
|
||||
-ms-animation-duration: $settings;
|
||||
animation-duration: $settings;
|
||||
}
|
||||
|
||||
@mixin animation ($settings) {
|
||||
-moz-animation: $settings;
|
||||
-webkit-animation: $settings;
|
||||
-o-animation: $settings;
|
||||
-ms-animation: $settings;
|
||||
animation: $settings;
|
||||
}
|
||||
|
||||
@mixin transform ($settings) {
|
||||
transform: $settings;
|
||||
-moz-transform: $settings;
|
||||
-webkit-transform: $settings;
|
||||
-o-transform: $settings;
|
||||
-ms-transform: $settings;
|
||||
}
|
||||
|
||||
body {
|
||||
margin:0;
|
||||
padding:0;
|
||||
background: #000;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pyro > .before, .pyro > .after {
|
||||
z-index: 100;
|
||||
position: absolute;
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
box-shadow: $box-shadow2;
|
||||
@include animation((1s bang ease-out infinite backwards, 1s gravity ease-in infinite backwards, 5s position linear infinite backwards));
|
||||
}
|
||||
|
||||
.pyro > .after {
|
||||
@include animation-delay((1.25s, 1.25s, 1.25s));
|
||||
@include animation-duration((1.25s, 1.25s, 6.25s));
|
||||
}
|
||||
|
||||
@include keyframes(bang) {
|
||||
to {
|
||||
box-shadow:$box-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
@include keyframes(gravity) {
|
||||
to {
|
||||
@include transform(translateY(200px));
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@include keyframes(position) {
|
||||
0%, 19.9% {
|
||||
margin-top: 10%;
|
||||
margin-left: 40%;
|
||||
}
|
||||
20%, 39.9% {
|
||||
margin-top: 40%;
|
||||
margin-left: 30%;
|
||||
}
|
||||
40%, 59.9% {
|
||||
margin-top: 20%;
|
||||
margin-left: 70%
|
||||
}
|
||||
60%, 79.9% {
|
||||
margin-top: 30%;
|
||||
margin-left: 20%;
|
||||
}
|
||||
80%, 99.9% {
|
||||
margin-top: 30%;
|
||||
margin-left: 80%;
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,53 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { WebsocketService } from 'src/app/services/websocket.service';
|
||||
import { StateService } from 'src/app/services/state.service';
|
||||
import { specialBlocks } from 'src/app/app.constants';
|
||||
|
||||
@Component({
|
||||
selector: 'app-start',
|
||||
templateUrl: './start.component.html',
|
||||
styleUrls: ['./start.component.scss'],
|
||||
})
|
||||
export class StartComponent {
|
||||
constructor() { }
|
||||
export class StartComponent implements OnInit {
|
||||
|
||||
interval = 60;
|
||||
colors = ['#5E35B1', '#ffffff'];
|
||||
|
||||
specialEvent = false;
|
||||
eventName = '';
|
||||
optionsLeft = {
|
||||
particleCount: 2,
|
||||
angle: 70,
|
||||
spread: 50,
|
||||
origin: { x: 0 },
|
||||
colors: this.colors,
|
||||
};
|
||||
optionsRight = {
|
||||
particleCount: 2,
|
||||
angle: 110,
|
||||
spread: 50,
|
||||
origin: { x: 1 },
|
||||
colors: this.colors,
|
||||
};
|
||||
|
||||
constructor(
|
||||
private websocketService: WebsocketService,
|
||||
private stateService: StateService,
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.websocketService.want(['blocks', 'stats', 'mempool-blocks']);
|
||||
this.stateService.blocks$
|
||||
.subscribe((blocks: any) => {
|
||||
const block = blocks[0];
|
||||
if(specialBlocks[block.height]) {
|
||||
this.specialEvent = true;
|
||||
this.eventName = specialBlocks[block.height].labelEvent;
|
||||
setTimeout(() => {
|
||||
this.specialEvent = false;
|
||||
}, 60 * 60 * 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user