feat: gacha
|
|
@ -1,10 +1,9 @@
|
|||
import { ZZZPlugin } from '../lib/plugin.js';
|
||||
import _ from 'lodash';
|
||||
import render from '../lib/render.js';
|
||||
import { ZZZNoteResp } from '../model/note.js';
|
||||
import { rulePrefix } from '../lib/common.js';
|
||||
import { getAuthKey, getStoken } from '../lib/authkey.js';
|
||||
import { updateGachaLog } from '../lib/gacha.js';
|
||||
import { getAuthKey } from '../lib/authkey.js';
|
||||
import { anaylizeGachaLog, updateGachaLog } from '../lib/gacha.js';
|
||||
|
||||
export class GachaLog extends ZZZPlugin {
|
||||
constructor() {
|
||||
|
|
@ -26,6 +25,10 @@ export class GachaLog extends ZZZPlugin {
|
|||
reg: `^${rulePrefix}抽卡帮助$`,
|
||||
fnc: 'gachaHelp',
|
||||
},
|
||||
{
|
||||
reg: `^${rulePrefix}抽卡分析$`,
|
||||
fnc: 'gachaLogAnalysis',
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
@ -87,4 +90,21 @@ export class GachaLog extends ZZZPlugin {
|
|||
await this.reply(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
async gachaLogAnalysis() {
|
||||
const uid = await this.getUID();
|
||||
if (!uid) {
|
||||
return false;
|
||||
}
|
||||
await this.getPlayerInfo();
|
||||
const data = await anaylizeGachaLog(uid);
|
||||
if (!data) {
|
||||
await this.reply('未查询到抽卡记录,请先发送抽卡链接');
|
||||
return false;
|
||||
}
|
||||
const result = {
|
||||
data,
|
||||
};
|
||||
await render(this.e, 'gachalog/index.html', result);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import settings from '../settings.js';
|
||||
import PartnerId2SpriteId from '../../resources/map/PartnerId2SpriteId.json';
|
||||
import PartnerId2SpriteId from '../../resources/map/PartnerId2SpriteId.json?json';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @param {boolean} full 显示全称
|
||||
* @param {boolean} en 是否为英文
|
||||
* @returns string
|
||||
* @returns string | null
|
||||
*/
|
||||
export const IDToCharName = (id, full = true, en = false) => {
|
||||
const data = PartnerId2SpriteId?.[id];
|
||||
|
|
@ -19,7 +19,7 @@ export const IDToCharName = (id, full = true, en = false) => {
|
|||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @returns string
|
||||
* @returns string | null
|
||||
*/
|
||||
export const IDToCharSprite = id => {
|
||||
const data = PartnerId2SpriteId?.[id];
|
||||
|
|
@ -29,7 +29,7 @@ export const IDToCharSprite = id => {
|
|||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns string
|
||||
* @returns string | null
|
||||
*/
|
||||
export const charNameToID = name => {
|
||||
for (const [id, data] of Object.entries(PartnerId2SpriteId)) {
|
||||
|
|
@ -40,7 +40,7 @@ export const charNameToID = name => {
|
|||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns string
|
||||
* @returns string | null
|
||||
*/
|
||||
export const charNameToSprite = name => {
|
||||
for (const [_id, data] of Object.entries(PartnerId2SpriteId)) {
|
||||
|
|
@ -51,19 +51,20 @@ export const charNameToSprite = name => {
|
|||
|
||||
/**
|
||||
* @param {string} atlas
|
||||
* @returns string
|
||||
* @returns string | null
|
||||
*/
|
||||
export const atlasToName = atlas => {
|
||||
export const atlasToName = _atlas => {
|
||||
const atlas = settings.getConfig('atlas');
|
||||
for (const [id, data] of Object.entries(atlas)) {
|
||||
if (data.includes(atlas)) return id;
|
||||
if (id === _atlas) return id;
|
||||
if (data.includes(_atlas)) return id;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} atlas
|
||||
* @returns string
|
||||
* @returns string | null
|
||||
*/
|
||||
export const atlasToSprite = atlas => {
|
||||
const atlas = settings.getConfig('atlas');
|
||||
|
|
@ -75,7 +76,7 @@ export const atlasToSprite = atlas => {
|
|||
|
||||
/**
|
||||
* @param {string} name
|
||||
* @returns string
|
||||
* @returns string | null
|
||||
*/
|
||||
export const atlasToID = name => {
|
||||
const atlas = settings.getConfig('atlas');
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import WeaponId2Sprite from '../../resources/map/WeaponId2Sprite.json';
|
||||
import WeaponId2Sprite from '../../resources/map/WeaponId2Sprite.json?json';
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
|
|
|
|||
101
lib/gacha.js
|
|
@ -127,3 +127,104 @@ export async function updateGachaLog(authKey, uid) {
|
|||
saveGachaLog(uid, previousLog);
|
||||
return previousLog;
|
||||
}
|
||||
|
||||
const RANK_MAP = {
|
||||
4: 'S',
|
||||
3: 'A',
|
||||
2: 'B',
|
||||
};
|
||||
const HOMO_TAG = ['非到极致', '运气不好', '平稳保底', '小欧一把', '欧狗在此'];
|
||||
const NORMAL_LIST = [
|
||||
'「11号」',
|
||||
'猫又',
|
||||
'莱卡恩',
|
||||
'丽娜',
|
||||
'格莉丝',
|
||||
'珂蕾妲',
|
||||
'拘缚者',
|
||||
'燃狱齿轮',
|
||||
'嵌合编译器',
|
||||
'钢铁肉垫',
|
||||
'硫磺石',
|
||||
'啜泣摇篮',
|
||||
];
|
||||
|
||||
export async function anaylizeGachaLog(uid) {
|
||||
const savedData = getGachaLog(uid);
|
||||
if (!savedData) {
|
||||
return null;
|
||||
}
|
||||
const result = [];
|
||||
for (const name in savedData) {
|
||||
const data = savedData[name].map(
|
||||
item =>
|
||||
new SingleGachaLog(
|
||||
item.uid,
|
||||
item.gacha_id,
|
||||
item.gacha_type,
|
||||
item.item_id,
|
||||
item.count,
|
||||
item.time,
|
||||
item.name,
|
||||
item.lang,
|
||||
item.item_type,
|
||||
item.rank_type,
|
||||
item.id
|
||||
)
|
||||
);
|
||||
const earliest = data[data.length - 1];
|
||||
const latest = data[0];
|
||||
const list = [];
|
||||
let lastFive = `${data.length}`;
|
||||
let preIndex = 0;
|
||||
let luck = 0;
|
||||
data.forEach((item, i) => {
|
||||
let isUp = true;
|
||||
if (item.rank_type === '4') {
|
||||
if (NORMAL_LIST.includes(item.name)) {
|
||||
isUp = false;
|
||||
}
|
||||
if (lastFive === `${data.length}`) {
|
||||
lastFive = `${i + 1}`;
|
||||
}
|
||||
list.push({
|
||||
...item,
|
||||
rank_type_label: RANK_MAP[item.rank_type],
|
||||
isUp: isUp,
|
||||
});
|
||||
if (list.length > 0) {
|
||||
list[list.length - 1]['totalCount'] = i - preIndex;
|
||||
}
|
||||
preIndex = i;
|
||||
}
|
||||
if (i === data.length - 1 && list.length > 0) {
|
||||
list[list.length - 1]['totalCount'] = i - preIndex;
|
||||
}
|
||||
});
|
||||
const upCount = list.length;
|
||||
const totalCount = data.length;
|
||||
const fiveStars = list.length;
|
||||
logger.mark('fiveStars', fiveStars);
|
||||
logger.mark('totalCount', totalCount);
|
||||
let timeRange = '还没有抽卡';
|
||||
let avgFive = '-';
|
||||
let avgUp = '-';
|
||||
if (data.length > 0) {
|
||||
timeRange = `${latest.time} ~ ${earliest.time}`;
|
||||
if (fiveStars > 0) avgFive = (totalCount / fiveStars).toFixed(1);
|
||||
if (upCount > 0) avgUp = (totalCount / upCount).toFixed(1);
|
||||
}
|
||||
result.push({
|
||||
name,
|
||||
timeRange,
|
||||
list,
|
||||
lastFive,
|
||||
fiveStars,
|
||||
upCount,
|
||||
totalCount,
|
||||
avgFive,
|
||||
avgUp,
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ export class SingleGachaLog {
|
|||
equals(item) {
|
||||
return (
|
||||
this.uid === item.uid &&
|
||||
this.gacha_id === item.gacha_id &&
|
||||
this.id === item.id &&
|
||||
this.gacha_type === this.gacha_type
|
||||
);
|
||||
}
|
||||
|
|
|
|||
BIN
resources/gachalog/images/IconTabUP.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
resources/gachalog/images/RANK_A.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
resources/gachalog/images/RANK_B.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
resources/gachalog/images/RANK_S.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
resources/gachalog/images/bg1.png
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
resources/gachalog/images/bg2.png
Normal file
|
After Width: | Height: | Size: 221 KiB |
BIN
resources/gachalog/images/bg3.png
Normal file
|
After Width: | Height: | Size: 188 KiB |
BIN
resources/gachalog/images/bg4.png
Normal file
|
After Width: | Height: | Size: 266 KiB |
BIN
resources/gachalog/images/emoji/1.png
Normal file
|
After Width: | Height: | Size: 400 KiB |
BIN
resources/gachalog/images/emoji/10.png
Normal file
|
After Width: | Height: | Size: 314 KiB |
BIN
resources/gachalog/images/emoji/11.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
resources/gachalog/images/emoji/12.png
Normal file
|
After Width: | Height: | Size: 345 KiB |
BIN
resources/gachalog/images/emoji/13.png
Normal file
|
After Width: | Height: | Size: 248 KiB |
BIN
resources/gachalog/images/emoji/14.png
Normal file
|
After Width: | Height: | Size: 331 KiB |
BIN
resources/gachalog/images/emoji/15.png
Normal file
|
After Width: | Height: | Size: 276 KiB |
BIN
resources/gachalog/images/emoji/16.png
Normal file
|
After Width: | Height: | Size: 230 KiB |
BIN
resources/gachalog/images/emoji/2.png
Normal file
|
After Width: | Height: | Size: 234 KiB |
BIN
resources/gachalog/images/emoji/3.png
Normal file
|
After Width: | Height: | Size: 322 KiB |
BIN
resources/gachalog/images/emoji/4.png
Normal file
|
After Width: | Height: | Size: 313 KiB |
BIN
resources/gachalog/images/emoji/5.png
Normal file
|
After Width: | Height: | Size: 225 KiB |
BIN
resources/gachalog/images/emoji/6.png
Normal file
|
After Width: | Height: | Size: 269 KiB |
BIN
resources/gachalog/images/emoji/7.png
Normal file
|
After Width: | Height: | Size: 335 KiB |
BIN
resources/gachalog/images/emoji/8.png
Normal file
|
After Width: | Height: | Size: 341 KiB |
BIN
resources/gachalog/images/emoji/9.png
Normal file
|
After Width: | Height: | Size: 366 KiB |
BIN
resources/gachalog/images/role_square_avatar_1011.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
216
resources/gachalog/index.css
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
.card {
|
||||
margin: 0 1em;
|
||||
}
|
||||
.card .user-info {
|
||||
margin: 0 1em;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
.card .title {
|
||||
border-image-slice: 37 27 37 131 fill;
|
||||
border-image-width: 1em 1em 1em 4.5em;
|
||||
border-image-outset: 0em 0em 0em 0em;
|
||||
border-image-repeat: stretch stretch;
|
||||
min-height: 7em;
|
||||
padding: 0.7em 2.3em 0.7em 3.7em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.card .title.t1 {
|
||||
border-image-source: url("./images/bg1.png");
|
||||
}
|
||||
.card .title.t2 {
|
||||
border-image-source: url("./images/bg2.png");
|
||||
}
|
||||
.card .title.t3 {
|
||||
border-image-source: url("./images/bg3.png");
|
||||
}
|
||||
.card .title.t4 {
|
||||
border-image-source: url("./images/bg4.png");
|
||||
}
|
||||
.card .title .info {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
.card .title .info .type {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 0.1em;
|
||||
}
|
||||
.card .title .info .type .label {
|
||||
font-size: 1.5em;
|
||||
text-shadow: 0.05em 0.05em 0.03em rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.card .title .info .type .status {
|
||||
font-size: 0.8em;
|
||||
color: #e4e4e4;
|
||||
margin-bottom: 0.2em;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
padding: 0em 0.5em;
|
||||
border-radius: 1em;
|
||||
backdrop-filter: blur(0.3em);
|
||||
}
|
||||
.card .title .info .type .status .value {
|
||||
color: rgb(128, 237, 84);
|
||||
margin: 0 0.1em;
|
||||
}
|
||||
.card .title .info .time {
|
||||
font-size: 0.6em;
|
||||
color: #e4e4e4;
|
||||
}
|
||||
.card .title .info .analysis {
|
||||
width: 15em;
|
||||
display: flex;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
margin-left: 1em;
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.2em;
|
||||
border-radius: 2em;
|
||||
padding: 0.1em 0.5em;
|
||||
}
|
||||
.card .title .info .analysis .item {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.card .title .info .analysis .item .value {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.card .title .info .analysis .item .label {
|
||||
font-size: 0.8em;
|
||||
color: #e4e4e4;
|
||||
}
|
||||
.card .title .comment {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.card .title .comment .icon {
|
||||
width: 4.5em;
|
||||
aspect-ratio: 1;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.card .title .comment.e1 .icon {
|
||||
background-image: url("./images/emoji/1.png");
|
||||
}
|
||||
.card .title .comment.e2 .icon {
|
||||
background-image: url("./images/emoji/2.png");
|
||||
}
|
||||
.card .title .comment.e3 .icon {
|
||||
background-image: url("./images/emoji/3.png");
|
||||
}
|
||||
.card .title .comment.e4 .icon {
|
||||
background-image: url("./images/emoji/4.png");
|
||||
}
|
||||
.card .title .comment.e5 .icon {
|
||||
background-image: url("./images/emoji/5.png");
|
||||
}
|
||||
.card .title .comment.e6 .icon {
|
||||
background-image: url("./images/emoji/6.png");
|
||||
}
|
||||
.card .title .comment.e7 .icon {
|
||||
background-image: url("./images/emoji/7.png");
|
||||
}
|
||||
.card .title .comment.e8 .icon {
|
||||
background-image: url("./images/emoji/8.png");
|
||||
}
|
||||
.card .title .comment.e9 .icon {
|
||||
background-image: url("./images/emoji/9.png");
|
||||
}
|
||||
.card .title .comment.e10 .icon {
|
||||
background-image: url("./images/emoji/10.png");
|
||||
}
|
||||
.card .title .comment.e11 .icon {
|
||||
background-image: url("./images/emoji/11.png");
|
||||
}
|
||||
.card .title .comment.e12 .icon {
|
||||
background-image: url("./images/emoji/12.png");
|
||||
}
|
||||
.card .title .comment.e13 .icon {
|
||||
background-image: url("./images/emoji/13.png");
|
||||
}
|
||||
.card .title .comment.e14 .icon {
|
||||
background-image: url("./images/emoji/14.png");
|
||||
}
|
||||
.card .title .comment.e15 .icon {
|
||||
background-image: url("./images/emoji/15.png");
|
||||
}
|
||||
.card .title .comment.e16 .icon {
|
||||
background-image: url("./images/emoji/16.png");
|
||||
}
|
||||
.card .title .comment .label {
|
||||
font-size: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
.card .list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1em;
|
||||
padding: 0.5em 1.7em;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
.card .list .item {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
border-radius: 0.5em;
|
||||
overflow: hidden;
|
||||
border: 0.2em solid #000000;
|
||||
}
|
||||
.card .list .item.up::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0.1em;
|
||||
left: 0.2em;
|
||||
width: 1.7em;
|
||||
height: 1.7em;
|
||||
background: url("./images/IconTabUP.png") no-repeat center center;
|
||||
background-size: contain;
|
||||
z-index: 1;
|
||||
}
|
||||
.card .list .item .rank {
|
||||
position: absolute;
|
||||
top: 0.2em;
|
||||
right: 0.2em;
|
||||
width: 1.5em;
|
||||
aspect-ratio: 1;
|
||||
background: url("./images/RANK_A.png") no-repeat center center;
|
||||
background-size: contain;
|
||||
color: white;
|
||||
z-index: 2;
|
||||
}
|
||||
.card .list .item.rankS .rank {
|
||||
background-image: url("./images/RANK_S.png");
|
||||
}
|
||||
.card .list .item.rankB .rank {
|
||||
background-image: url("./images/RANK_B.png");
|
||||
}
|
||||
.card .list .item .image {
|
||||
width: 100%;
|
||||
aspect-ratio: 1.5;
|
||||
background-color: #e2e2e2;
|
||||
}
|
||||
.card .list .item .image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
display: block;
|
||||
}
|
||||
.card .list .item .count {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(0.3em);
|
||||
border-top-right-radius: 0.5em;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 0 0.3em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=index.css.map */
|
||||
54
resources/gachalog/index.html
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
{{extend defaultLayout}}
|
||||
|
||||
{{block 'css'}}
|
||||
<link rel="stylesheet" href="{{@sys.currentPath}}/index.css">
|
||||
{{/block}}
|
||||
|
||||
{{block 'main'}}
|
||||
<div class="card">
|
||||
{{include sys.playerInfo}}
|
||||
{{each data item i}}
|
||||
<div class="title t{{i+1}}">
|
||||
<div class="info">
|
||||
<div class="type">
|
||||
<div class="label">{{item.name}}</div>
|
||||
<div class="status">已<span class="value">{{item.lastFive}}</span>抽未出S级</div>
|
||||
</div>
|
||||
<div class="time">{{item.timeRange}}</div>
|
||||
<div class="analysis">
|
||||
<div class="item">
|
||||
<div class="value">{{item.avgFive}}</div>
|
||||
<div class="label">平均出金</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="value">{{item.avgUp}}</div>
|
||||
<div class="label">平均UP</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="value">{{item.totalCount}}</div>
|
||||
<div class="label">抽卡总数</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="comment e1">
|
||||
<div class="icon"></div>
|
||||
<div class="label">平稳保底</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="list">
|
||||
{{each item.list inv j}}
|
||||
<div class="item rankS {{inv.isUp && 'up'}}">
|
||||
<div class="rank rankS"></div>
|
||||
<div class="image">
|
||||
<img src="./images/role_square_avatar_1011.png" alt="">
|
||||
</div>
|
||||
<div class="count">{{inv?.totalCount || '-'}}抽</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
|
||||
{{/each}}
|
||||
|
||||
</div>
|
||||
{{/block}}
|
||||
172
resources/gachalog/index.scss
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
.card {
|
||||
margin: 0 1em;
|
||||
.user-info {
|
||||
margin: 0 1em;
|
||||
margin-bottom: 1.5em;
|
||||
}
|
||||
.title {
|
||||
border-image-slice: 37 27 37 131 fill;
|
||||
border-image-width: 1em 1em 1em 4.5em;
|
||||
border-image-outset: 0em 0em 0em 0em;
|
||||
border-image-repeat: stretch stretch;
|
||||
min-height: 7em;
|
||||
padding: 0.7em 2.3em 0.7em 3.7em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@for $i from 1 through 4 {
|
||||
&.t#{$i} {
|
||||
border-image-source: url('./images/bg#{$i}.png');
|
||||
}
|
||||
}
|
||||
.info {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
.type {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 0.1em;
|
||||
.label {
|
||||
font-size: 1.5em;
|
||||
text-shadow: 0.05em 0.05em 0.03em rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.status {
|
||||
font-size: 0.8em;
|
||||
color: #e4e4e4;
|
||||
margin-bottom: 0.2em;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
padding: 0em 0.5em;
|
||||
border-radius: 1em;
|
||||
backdrop-filter: blur(0.3em);
|
||||
.value {
|
||||
color: rgb(128, 237, 84);
|
||||
margin: 0 0.1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
.time {
|
||||
font-size: 0.6em;
|
||||
color: #e4e4e4;
|
||||
}
|
||||
.analysis {
|
||||
width: 15em;
|
||||
display: flex;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
margin-left: 1em;
|
||||
margin-top: 0.3em;
|
||||
margin-bottom: 0.2em;
|
||||
border-radius: 2em;
|
||||
padding: 0.1em 0.5em;
|
||||
.item {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
.value {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.label {
|
||||
font-size: 0.8em;
|
||||
color: #e4e4e4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.comment {
|
||||
flex-grow: 0;
|
||||
flex-shrink: 0;
|
||||
.icon {
|
||||
width: 4.5em;
|
||||
aspect-ratio: 1;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: contain;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
@for $i from 1 through 16 {
|
||||
&.e#{$i} {
|
||||
.icon {
|
||||
background-image: url('./images/emoji/#{$i}.png');
|
||||
}
|
||||
}
|
||||
}
|
||||
.label {
|
||||
font-size: 1em;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
.list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 1em;
|
||||
padding: 0.5em 1.7em;
|
||||
margin-bottom: 1.5em;
|
||||
.item {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
border-radius: 0.5em;
|
||||
overflow: hidden;
|
||||
border: 0.2em solid #000000;
|
||||
&.up {
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
top: 0.1em;
|
||||
left: 0.2em;
|
||||
width: 1.7em;
|
||||
height: 1.7em;
|
||||
background: url('./images/IconTabUP.png') no-repeat center center;
|
||||
background-size: contain;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
.rank {
|
||||
position: absolute;
|
||||
top: 0.2em;
|
||||
right: 0.2em;
|
||||
width: 1.5em;
|
||||
aspect-ratio: 1;
|
||||
background: url('./images/RANK_A.png') no-repeat center center;
|
||||
background-size: contain;
|
||||
color: white;
|
||||
z-index: 2;
|
||||
}
|
||||
&.rankS {
|
||||
.rank {
|
||||
background-image: url('./images/RANK_S.png');
|
||||
}
|
||||
}
|
||||
&.rankB {
|
||||
.rank {
|
||||
background-image: url('./images/RANK_B.png');
|
||||
}
|
||||
}
|
||||
.image {
|
||||
width: 100%;
|
||||
aspect-ratio: 1.5;
|
||||
background-color: #e2e2e2;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.count {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(0.3em);
|
||||
border-top-right-radius: 0.5em;
|
||||
color: white;
|
||||
text-align: center;
|
||||
padding: 0 0.3em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||