diff --git a/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.css b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.css new file mode 100644 index 0000000..b1588ae --- /dev/null +++ b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.css @@ -0,0 +1,207 @@ +.control { + z-index: 1500; +} + +.gacha-button-group { + width: 100%; + display: flex; +} + +.gacha-button-group button { + margin: auto; + width: 128px; + height: 128px; + background-color: dimgray; +} + +.full-screen { + z-index: 1000; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + height: 100%; + width: 100%; + background: url("//static.samnyan.icu/ongeki/gameUi/Evt_BattleStart_UI_CMN_Transition_bg.png") no-repeat center; + background-size: cover; +} + +/* Wide screen */ +.card-container { + padding: 0 5%; + height: 100%; + margin: 0; + display: flex; + flex-wrap: wrap; + justify-content: center; + overflow: scroll; + -ms-overflow-style: none; +} + +.card-container::-webkit-scrollbar { + display: none; +} + +.result-card { + margin: 30px 20px; + width: 30%; + height: fit-content; + max-width: 200px; + overflow: hidden; + position: relative; +} + +.result-card .overlay { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + height: 100%; + width: 100%; +} + +.result-card .overlay img { + left: 0; + position: absolute; + height: 100%; + transform: scaleX(-1); + opacity: 60%; + animation-duration: 3s; + animation-name: overlay-glow; + animation-iteration-count: infinite; + animation-direction: normal; +} + +.result-card .overlay-rarity { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + height: 100%; + width: 100%; +} + +.result-card .overlay-rarity img { + left: 0; + position: absolute; + height: 100%; + opacity: 0; + animation-duration: 2.5s; + animation-name: overlay-rarity; + animation-iteration-count: infinite; + animation-direction: alternate; +} + +@keyframes overlay-glow { + from { + left: -1000%; + } + + to { + left: 300%; + } +} + +@keyframes overlay-rarity { + 20% { + opacity: 0; + } + + 50% { + opacity: 60%; + } + + 80% { + opacity: 0; + } +} + +.flip { + transform: rotateY(180deg); +} + +.card-image { + transition: transform 0.8s; + transform-style: preserve-3d; +} + +.card-image .image-back { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + height: 100%; + width: 100%; + transform: rotateY(180deg); +} + +.card-image .image-back img { + left: 0; + position: absolute; + height: 100%; +} + +.image-front, .image-back { + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} + +.image-front img, .image-back img { + width: 100%; +} + +@media screen and (max-width: 600px) { + .result-card { + margin: 30px 15px; + max-width: 150px; + } + + .gacha-button-group button { + width: 72px; + height: 72px; + } +} + +@media screen and (max-height: 500px) { + .result-card { + max-width: 110px; + } +} + +@media screen and (max-width: 420px) { + .result-card { + margin: 30px 5px; + max-width: 100px; + } +} + + +/** +Card animation part + */ + +.card-animation-full-screen { + z-index: 1200; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + height: 100%; + width: 100%; + display: none; +} + +#card_animation { + margin: auto; + max-height: 100%; + max-width: 100%; +} + +#image_loader { + display: none; +} diff --git a/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.html b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.html new file mode 100644 index 0000000..c57b618 --- /dev/null +++ b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.html @@ -0,0 +1,55 @@ + + +

Regular Gacha

+

This is still work in progress. Animation isn't implemented.

+
+ + + +
+

Detail:
+ R: 70%
+ SR: 25%
+ SSR: 5% +

+

+ Card data saved in server: {{submitSuccessful}} , failed {{cardResultList.length - submitSuccessful}} +

+
+
+ +
+
+
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+ +
+ +
+ + + + + +
diff --git a/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.spec.ts b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.spec.ts new file mode 100644 index 0000000..6902713 --- /dev/null +++ b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {OngekiCardGachaComponent} from './ongeki-card-gacha.component'; + +describe('OngekiCardGachaComponent', () => { + let component: OngekiCardGachaComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [OngekiCardGachaComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(OngekiCardGachaComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.ts b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.ts new file mode 100644 index 0000000..1ff7c59 --- /dev/null +++ b/src/app/sega/ongeki/ongeki-card-gacha/ongeki-card-gacha.component.ts @@ -0,0 +1,151 @@ +import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/core'; +import {environment} from '../../../../environments/environment'; +import {OngekiCard} from '../model/OngekiCard'; +import {ApiService} from '../../../api.service'; +import {AuthenticationService} from '../../../auth/authentication.service'; +import {MessageService} from '../../../message.service'; +import {NgxIndexedDBService} from 'ngx-indexed-db'; +import {animate, style, transition, trigger} from '@angular/animations'; + +@Component({ + selector: 'app-ongeki-card-gacha', + templateUrl: './ongeki-card-gacha.component.html', + styleUrls: ['./ongeki-card-gacha.component.css'], + animations: [ + trigger('control', [ + transition(':enter', [ + style({opacity: 0}), + animate('1s 0.5s ease-out', + style({opacity: 1})) + ]), + transition(':leave', [ + style({opacity: 1}), + animate('1s ease-in', + style({opacity: 0})) + ]) + ]) + ] +}) +export class OngekiCardGachaComponent implements OnInit, AfterViewInit { + + @ViewChild('card_animation', {static: true}) + canvas: ElementRef; + + host = environment.assetsHost; + assets = environment.assetsHost + 'ongeki/gameUi/'; + + isStarted = false; + + rarity: number[] = []; + rList: OngekiCard[] = []; + srList: OngekiCard[] = []; + ssrList: OngekiCard[] = []; + + cardResultList: CardResult[] = []; + currentShowedIndex = 0; + + submitSuccessful = 0; + + constructor( + private api: ApiService, + private auth: AuthenticationService, + private messageService: MessageService, + private dbService: NgxIndexedDBService + ) { + } + + ngOnInit() { + this.rarity = Array(70).fill(1); + this.rarity = this.rarity.concat(Array(25).fill(2)); + this.rarity = this.rarity.concat(Array(5).fill(3)); + this.dbService.getAll('ongekiCard').then( + x => { + x.forEach(y => { + switch (y.rarity) { + case 'R': + this.rList.push(y); + break; + case 'SR': + this.srList.push(y); + break; + case 'SSR': + this.ssrList.push(y); + break; + } + }); + } + ); + + } + + ngAfterViewInit() { + // const ctx = this.canvas.nativeElement.getContext('2d'); + // + // const img = new Image(); + // img.onload = () => ctx.drawImage(img, 0, 0); + // img.src = this.assets + 'UI_CMN_CardGet_NEW.png'; + } + + start(count: number) { + this.cardResultList = []; + this.currentShowedIndex = 0; + this.isStarted = true; + this.submitSuccessful = 0; + + for (let i = 0; i < count; i++) { + const rarity = this.rarity[Math.floor(Math.random() * 99)]; + console.log('rarity: ' + rarity); + let card; + switch (rarity) { + case 1: + card = this.rList[Math.floor(Math.random() * this.rList.length)]; + break; + case 2: + card = this.srList[Math.floor(Math.random() * this.srList.length)]; + break; + case 3: + card = this.ssrList[Math.floor(Math.random() * this.ssrList.length)]; + break; + } + console.log('card: ' + JSON.stringify(card)); + this.cardResultList.push({ + show: false, + card + }); + } + this.submitCardData(); + return; + } + + open() { + console.log('clicked'); + if (this.currentShowedIndex < this.cardResultList.length) { + const card = this.cardResultList[this.currentShowedIndex]; + card.show = true; + this.currentShowedIndex = this.currentShowedIndex + 1; + } else { + this.isStarted = false; + } + } + + submitCardData() { + const aimeId = this.auth.currentUserValue.extId; + this.cardResultList.forEach(x => { + this.api.post('api/game/ongeki/card', { + aimeId, + cardId: x.card.id + }).subscribe( + data => { + this.submitSuccessful = this.submitSuccessful + 1; + return; + }, + error => this.messageService.notice(error) + ); + }); + } +} + +interface CardResult { + show: boolean; + card: OngekiCard; +} diff --git a/src/app/sega/ongeki/ongeki-card/ongeki-card.component.html b/src/app/sega/ongeki/ongeki-card/ongeki-card.component.html index 57dd0a2..29daab4 100644 --- a/src/app/sega/ongeki/ongeki-card/ongeki-card.component.html +++ b/src/app/sega/ongeki/ongeki-card/ongeki-card.component.html @@ -11,7 +11,7 @@

- +
diff --git a/src/app/sega/ongeki/ongeki.module.ts b/src/app/sega/ongeki/ongeki.module.ts index e49c69b..c83c8f9 100644 --- a/src/app/sega/ongeki/ongeki.module.ts +++ b/src/app/sega/ongeki/ongeki.module.ts @@ -17,6 +17,7 @@ import {OngekiRatingComponent} from './ongeki-rating/ongeki-rating.component'; import {ToLevelDecimalPipe} from './util/to-level-decimal.pipe'; import {ToBattleSpritePipe} from './util/to-battle-sprite.pipe'; import {ToTechSpritePipe} from './util/to-tech-sprite.pipe'; +import {OngekiCardGachaComponent} from './ongeki-card-gacha/ongeki-card-gacha.component'; @NgModule({ @@ -31,7 +32,8 @@ import {ToTechSpritePipe} from './util/to-tech-sprite.pipe'; OngekiRatingComponent, ToLevelDecimalPipe, ToBattleSpritePipe, - ToTechSpritePipe + ToTechSpritePipe, + OngekiCardGachaComponent ], imports: [ CommonModule, diff --git a/src/app/sega/ongeki/ongeki.routing.ts b/src/app/sega/ongeki/ongeki.routing.ts index 3c56db0..0a2687d 100644 --- a/src/app/sega/ongeki/ongeki.routing.ts +++ b/src/app/sega/ongeki/ongeki.routing.ts @@ -6,6 +6,7 @@ import {OngekiRecentComponent} from './ongeki-recent/ongeki-recent.component'; import {OngekiSongListComponent} from './ongeki-song-list/ongeki-song-list.component'; import {OngekiBattlePointComponent} from './ongeki-battle-point/ongeki-battle-point.component'; import {OngekiRatingComponent} from './ongeki-rating/ongeki-rating.component'; +import {OngekiCardGachaComponent} from './ongeki-card-gacha/ongeki-card-gacha.component'; const routes: Routes = [ @@ -16,6 +17,7 @@ const routes: Routes = [ {path: 'rating', component: OngekiRatingComponent}, {path: 'card', component: OngekiCardComponent}, {path: 'card/all', component: OngekiCardListComponent}, + {path: 'card/gacha', component: OngekiCardGachaComponent}, ]; export const OngekiRoutes = RouterModule.forChild(routes);