调整#角色卡片的样式,尚未完全稳定

This commit is contained in:
yoimiya-kokomi 2022-09-19 04:54:01 +08:00
parent 2c83c15170
commit 6f250dcf4a
19 changed files with 941 additions and 971 deletions

View File

@ -1,3 +1,7 @@
# 2.0 Alpha.3
* 调整`#角色卡片`的样式,尚未完全稳定
# 2.0 Alpha.2 # 2.0 Alpha.2
* `#深渊配队`、`#戳一戳` 适配V3 * `#深渊配队`、`#戳一戳` 适配V3

View File

@ -10,15 +10,15 @@ class User {
// 保存用户配置 // 保存用户配置
async setCfg (path, value) { async setCfg (path, value) {
let userCfg = await redis.get(`genshin:user-cfg:${this.id}`) let userCfg = await redis.get(`miao:user-cfg:${this.id}`) || await redis.get(`genshin:user-cfg:${this.id}`)
userCfg = userCfg ? JSON.parse(userCfg) : {} userCfg = userCfg ? JSON.parse(userCfg) : {}
lodash.set(userCfg, path, value) lodash.set(userCfg, path, value)
await redis.set(`genshin:user-cfg:${this.id}`, JSON.stringify(userCfg)) await redis.set(`miao:user-cfg:${this.id}`, JSON.stringify(userCfg))
} }
/* 获取用户配置 */ /* 获取用户配置 */
async getCfg (path, defaultValue) { async getCfg (path, defaultValue) {
let userCfg = await redis.get(`genshin:user-cfg:${this.id}`) let userCfg = await redis.get(`miao:user-cfg:${this.id}`) || await redis.get(`genshin:user-cfg:${this.id}`)
userCfg = userCfg ? JSON.parse(userCfg) : {} userCfg = userCfg ? JSON.parse(userCfg) : {}
return lodash.get(userCfg, path, defaultValue) return lodash.get(userCfg, path, defaultValue)
} }

View File

@ -44,7 +44,7 @@ export async function character (e) {
e.uid = uidRet[0] e.uid = uidRet[0]
msg = msg.replace(uidRet[0], '') msg = msg.replace(uidRet[0], '')
} }
let name = msg.replace(/#|老婆|老公/g, '').trim() let name = msg.replace(/#|老婆|老公|卡片/g, '').trim()
if (Common.isDisable(e, 'char.char')) { if (Common.isDisable(e, 'char.char')) {
return return

View File

@ -1,4 +1,4 @@
import { Artifact, Character, Avatars } from '../../models/index.js' import { Artifact, Character, AvatarList, Avatar } from '../../models/index.js'
import { Cfg, Data, Common, Profile } from '../../components/index.js' import { Cfg, Data, Common, Profile } from '../../components/index.js'
import lodash from 'lodash' import lodash from 'lodash'
import { segment } from 'oicq' import { segment } from 'oicq'
@ -51,88 +51,80 @@ export async function renderAvatar (e, avatar, renderType = 'card') {
} }
// 渲染角色卡片 // 渲染角色卡片
async function renderCard (e, avatar, renderType = 'card') { async function renderCard (e, ds, renderType = 'card') {
let char = Character.get(avatar) let char = Character.get(ds)
if (!char) { if (!char) {
return false return false
} }
let uid = e.uid || (e.targetUser && e.targetUser.uid)
let crownNum = 0
let talent = {}
if (!char.isCustom) {
talent = await getTalent(e, avatar)
// 计算皇冠个数
crownNum = lodash.filter(lodash.map(talent, (d) => d.original), (d) => d >= 10).length
}
let bg = char.getCardImg(Cfg.get('char.se', false)) let bg = char.getCardImg(Cfg.get('char.se', false))
if (renderType === 'photo') { if (renderType === 'photo') {
e.reply(segment.image(process.cwd() + '/plugins/miao-plugin/resources/' + bg.img)) e.reply(segment.image(process.cwd() + '/plugins/miao-plugin/resources/' + bg.img))
} else {
// 渲染图像
// let talent =
let msgRes = await Common.render('character/character-card', {
save_id: uid,
uid,
talent,
crownNum,
talentMap: { a: '普攻', e: '战技', q: '爆发' },
bg,
custom: char.isCustom,
...getCharacterData(avatar, char),
ds: char.getData('name,id,title,desc')
}, { e, scale: 1.6, retMsgId: true })
if (msgRes && msgRes.message_id) {
// 如果消息发送成功就将message_id和图片路径存起来1小时过期
await redis.set(`miao:original-picture:${msgRes.message_id}`, bg.img, { EX: 3600 })
}
return true return true
} }
return true let uid = e.uid || (e.targetUser && e.targetUser.uid)
} let data = {}
let custom = char.isCustom
// 获取角色技能数据 if (!custom) {
async function getTalent (e, avatars) { let avatar = new Avatar(ds)
let char = Character.get(avatars.id)
if (char.isCustom) {
return {}
}
let uid = e.uid
if (avatars.dataSource && avatars.talent) {
// profile模式
return avatars.talent
} else {
let MysApi = await e.getMysApi({ let MysApi = await e.getMysApi({
auth: 'all', auth: 'all',
targetType: Cfg.get('char.queryOther', true) ? 'all' : 'self', targetType: Cfg.get('char.queryOther', true) ? 'all' : 'self',
cookieType: 'all', cookieType: 'all',
actionName: '查询信息' actionName: '查询信息'
}) })
if (!MysApi && !MysApi.isSelfCookie) return {} data = avatar.getData('id,name,sName,level,fetter,cons,weapon,elem,artis,imgs,dataSourceName,updateTime')
let avatar = new Avatars(uid, [avatars]) if (MysApi && MysApi.isSelfCookie) {
return await avatar.getAvatarTalent(avatars.id, MysApi) data.talent = await avatar.getTalent(MysApi)
data.talentMap = ['a', 'e', 'q']
// 计算皇冠个数
data.crownNum = lodash.filter(lodash.map(data.talent, (d) => d.original), (d) => d >= 10).length
}
} }
let width = 600
if (bg.mode === 'left') {
width = 500 * bg.width / bg.height
}
// 渲染图像
let msgRes = await Common.render('character/character-card', {
saveId: uid,
uid,
bg,
widthStyle: `<style>html,body,#container{width:${width}px}</style>`,
mode: bg.mode,
custom,
data
}, { e, scale: 1.1, retMsgId: true })
if (msgRes && msgRes.message_id) {
// 如果消息发送成功就将message_id和图片路径存起来1小时过期
await redis.set(`miao:original-picture:${msgRes.message_id}`, bg.img, { EX: 3600 })
}
return true
} }
/* /*
* 获取角色数据 * 获取角色数据
* */ * */
function getCharacterData (avatars, char) { function getCharacterData (data, char) {
let list = [] let list = []
let set = {} let set = {}
let artiEffect = [] let artiEffect = []
let w = avatars.weapon || {}
let avatar = new Avatar(data)
if (!avatar) {
return {}
}
let ret = avatar.getData('dataType,dataSourceName,name,abbr,level,weapon')
console.log(ret)
let w = data.weapon || {}
let weapon = { let weapon = {
type: 'weapon', type: 'weapon',
name: w.name || '', name: w.name || '',
showName: abbr[w.name] || w.name || '', abbr: abbr[w.name] || w.name || '',
level: w.level || 1, level: w.level || 1,
affix: w.affix || w.affix_level || 0 affix: w.affix || w.affix_level || 0
} }
let artis = avatars?.artis?.artis || avatars.reliquaries let artis = data?.artis?.artis || data.reliquaries
if (artis) { if (artis) {
lodash.forEach(artis, (val) => { lodash.forEach(artis, (val) => {
@ -162,10 +154,10 @@ function getCharacterData (avatars, char) {
let reliquaries = list[0] let reliquaries = list[0]
return { return {
name: char.name, name: char.name,
showName: char.abbr || char.name, abbr: char.abbr,
level: Data.def(avatars.lv, avatars.level), level: Data.def(data.lv, data.level),
fetter: avatars.fetter, fetter: data.fetter,
cons: Data.def(avatars.cons, avatars.actived_constellation_num), cons: Data.def(data.cons, data.actived_constellation_num),
weapon, weapon,
artiEffect, artiEffect,
reliquaries reliquaries

View File

@ -1,6 +1,6 @@
import lodash from 'lodash' import lodash from 'lodash'
import { Common, Profile, Data } from '../../components/index.js' import { Common, Profile, Data } from '../../components/index.js'
import { Avatars } from '../../models/index.js' import { AvatarList } from '../../models/index.js'
export async function profileStat (e) { export async function profileStat (e) {
// 缓存时间,单位小时 // 缓存时间,单位小时
@ -24,11 +24,11 @@ export async function profileStat (e) {
return true return true
} }
if (!await Avatars.hasTalentCache(uid)) { if (!await AvatarList.hasTalentCache(uid)) {
e.reply('正在获取角色信息,请稍候...') e.reply('正在获取角色信息,请稍候...')
} }
let avatars = new Avatars(uid, resIndex.avatars) let avatars = new AvatarList(uid, resIndex.avatars)
let ids = avatars.getIds() let ids = avatars.getIds()
let talentData = await avatars.getTalentData(ids, MysApi) let talentData = await avatars.getTalentData(ids, MysApi)

View File

@ -5,7 +5,7 @@
import lodash from 'lodash' import lodash from 'lodash'
import fs from 'fs' import fs from 'fs'
import { Cfg, Common, App } from '../components/index.js' import { Cfg, Common, App } from '../components/index.js'
import { Abyss, Avatars, Character } from '../models/index.js' import { Abyss, AvatarList, Character } from '../models/index.js'
import HutaoApi from './stat/HutaoApi.js' import HutaoApi from './stat/HutaoApi.js'
let app = App.init({ let app = App.init({
@ -199,34 +199,6 @@ async function abyssPct (e) {
}, { e, scale: 1.5 }) }, { e, scale: 1.5 })
} }
async function getTalentData (e, isUpdate = false) {
// 技能查询缓存
let cachePath = './data/cache/'
if (!fs.existsSync(cachePath)) {
fs.mkdirSync(cachePath)
}
cachePath += 'talentList/'
if (!fs.existsSync(cachePath)) {
fs.mkdirSync(cachePath)
}
let avatarRet = []
let uid = e.selfUser.uid
let hasCache = await redis.get(`cache:uid-talent-new:${uid}`)
if (hasCache) {
// 有缓存优先使用缓存
let jsonRet = fs.readFileSync(cachePath + `${uid}.json`, 'utf8')
avatarRet = JSON.parse(jsonRet)
return avatarRet
} else if (!isUpdate) {
e.noReplyTalentList = true
await global.YunzaiApps.mysInfo.talentList(e)
return await getTalentData(e, true)
}
return false
}
async function abyssTeam (e) { async function abyssTeam (e) {
let MysApi = await e.getMysApi({ let MysApi = await e.getMysApi({
auth: 'cookie', // 所有用户均可查询 auth: 'cookie', // 所有用户均可查询
@ -247,7 +219,7 @@ async function abyssTeam (e) {
let uid = e.selfUser.uid let uid = e.selfUser.uid
let resDetail let resDetail
try { try {
if (!await Avatars.hasTalentCache(uid)) { if (!await AvatarList.hasTalentCache(uid)) {
e.reply('正在获取用户信息,请稍候...') e.reply('正在获取用户信息,请稍候...')
} }
resDetail = await MysApi.getCharacter() resDetail = await MysApi.getCharacter()
@ -258,7 +230,7 @@ async function abyssTeam (e) {
} catch (err) { } catch (err) {
// console.log(err); // console.log(err);
} }
let avatars = new Avatars(uid, resDetail.avatars) let avatars = new AvatarList(uid, resDetail.avatars)
let avatarIds = avatars.getIds() let avatarIds = avatars.getIds()
let avatarData = await avatars.getTalentData(avatarIds, MysApi) let avatarData = await avatars.getTalentData(avatarIds, MysApi)
let avatarRet = {} let avatarRet = {}
@ -455,7 +427,7 @@ async function uploadData (e) {
let resDetail, resAbyss let resDetail, resAbyss
try { try {
resAbyss = await MysApi.getSpiralAbyss(1) resAbyss = await MysApi.getSpiralAbyss(1)
if (resAbyss.floors.length > 0 && !await Avatars.hasTalentCache(uid)) { if (resAbyss.floors.length > 0 && !await AvatarList.hasTalentCache(uid)) {
e.reply('正在获取用户信息,请稍候...') e.reply('正在获取用户信息,请稍候...')
} }
resDetail = await MysApi.getCharacter() resDetail = await MysApi.getCharacter()
@ -482,7 +454,7 @@ async function uploadData (e) {
} }
let abyss = new Abyss(resAbyss) let abyss = new Abyss(resAbyss)
let abyssData = abyss.getData() let abyssData = abyss.getData()
let avatars = new Avatars(uid, resDetail.avatars) let avatars = new AvatarList(uid, resDetail.avatars)
let avatarIds = abyss.getAvatars() let avatarIds = abyss.getAvatars()
let overview = ret.info || (await HutaoApi.getOverview())?.data || {} let overview = ret.info || (await HutaoApi.getOverview())?.data || {}
let addMsg = function (title, ds) { let addMsg = function (title, ds) {

View File

@ -15,7 +15,7 @@ function getApi (api) {
let HutaoApi = { let HutaoApi = {
async req (url, param = {}, EX = 3600) { async req (url, param = {}, EX = 3600) {
let cacheData = await Data.getCacheJSON(`hutao:${url}`) let cacheData = await Data.getCacheJSON(`miao:hutao:${url}`)
if (cacheData && cacheData.data && param.method !== 'POST') { if (cacheData && cacheData.data && param.method !== 'POST') {
return cacheData return cacheData
} }
@ -27,7 +27,7 @@ let HutaoApi = {
if (retData && retData.data && param.method !== 'POST') { if (retData && retData.data && param.method !== 'POST') {
let d = new Date() let d = new Date()
retData.lastUpdate = `${d.toLocaleDateString()} ${d.toTimeString().substr(0, 5)}` retData.lastUpdate = `${d.toLocaleDateString()} ${d.toTimeString().substr(0, 5)}`
await Data.setCacheJSON(`hutao:${url}`, retData, EX) await Data.setCacheJSON(`miao:hutao:${url}`, retData, EX)
} }
return retData return retData
}, },

View File

@ -23,7 +23,7 @@ let Cal = {
let listData = await request.json() let listData = await request.json()
let timeMap let timeMap
let timeMapCache = await redis.get('cache:calendar:detail') let timeMapCache = await redis.get('miao:calendar:detail')
if (timeMapCache) { if (timeMapCache) {
timeMap = JSON.parse(timeMapCache) || {} timeMap = JSON.parse(timeMapCache) || {}
} else { } else {
@ -106,7 +106,7 @@ let Cal = {
} }
} catch (e) { } catch (e) {
} }
await Data.setCacheJSON('cache:calendar:detail', timeMap, 60 * 10) await Data.setCacheJSON('miao:calendar:detail', timeMap, 60 * 10)
} }
return { listData, timeMap } return { listData, timeMap }
}, },

View File

@ -61,14 +61,15 @@ class App {
cls.prototype[key] = async function () { cls.prototype[key] = async function () {
let e = this.e let e = this.e
if (event === 'poke') { if (event === 'poke') {
console.log(e)
if (e.notice_type === 'group') { if (e.notice_type === 'group') {
if (e.user_id !== Bot.uin) { if (e.user_id !== Bot.uin) {
return false return false
} }
// group状态下戳一戳的发起人是operator
e.user_id = e.operator_id e.user_id = e.operator_id
} }
e.isPoke = true e.isPoke = true
// 随便指定一个不太常见的msg以触发msg的正则
e.msg = '#poke#' e.msg = '#poke#'
} }
e.original_msg = e.original_msg || e.msg e.original_msg = e.original_msg || e.msg

134
models/Avatar.js Normal file
View File

@ -0,0 +1,134 @@
/*
* 用户角色
* 抹平Profile及Mys Avatar
* */
import Base from './Base.js'
import lodash from 'lodash'
import { Artifact, Character, Weapon } from './index.js'
import moment from 'moment'
const charKey = 'name,abbr,sName,star,imgs,weaponType,elem'.split(',')
export default class Avatar extends Base {
constructor (data = {}) {
super()
if (!data.name) {
return false
}
let char = Character.get(data.name)
if (!char || char.isCustom) {
return false
}
this.meta = data
this.char = char
this.dataType = data.dataSource ? 'profile' : 'avatar'
}
_get (key) {
if (charKey.includes(key)) {
return this.char[key]
}
return this.meta[key]
}
get dataSourceName () {
return this.meta.dataSourceName || 'MysApi'
}
get updateTime () {
let meta = this.meta
return this.isProfile ? meta.updateTime : moment(new Date()).format('MM-DD HH:mm')
}
get isProfile () {
return this.dataType === 'profile'
}
get isAvatar () {
return this.dataType === 'avatar'
}
get artis () {
if (this.isProfile) {
return this.meta.artis
}
if (this._artis) {
return this._artis
}
let ret = {}
const posIdx = {
生之花: 1,
死之羽: 2,
时之沙: 3,
空之杯: 4,
理之冠: 5
}
lodash.forEach(this.meta.reliquaries, (ds) => {
let idx = posIdx[ds.pos_name]
ret[idx] = {
name: ds.name,
set: Artifact.getSetByArti(ds.name),
level: ds.level
}
})
this._artis = ret
return this._artis;
}
get cons () {
let data = this.meta
return this.isProfile ? data.cons : data.actived_constellation_num
}
get weapon () {
let wd = this.meta.weapon
if (!wd || !wd.name) {
return {}
}
let weapon = Weapon.get(wd.name)
return {
name: wd.name,
abbr: weapon.abbr,
star: weapon.star,
level: wd.level || 1,
affix: wd.affix || wd.affix_level || 0,
type: weapon.type,
img: weapon.img
}
}
async getTalent (MysApi) {
if (this.isProfile) {
return this.talent
}
let char = this.char
let id = char.id
let talent = {}
let talentRes = await MysApi.getDetail(id)
let avatar = this.meta
if (!char || !avatar) {
return {}
}
if (talentRes && talentRes.skill_list) {
let talentList = lodash.orderBy(talentRes.skill_list, ['id'], ['asc'])
for (let val of talentList) {
let { max_level: maxLv, level_current: lv } = val
if (val.name.includes('普通攻击')) {
talent.a = lv
continue
}
if (maxLv >= 10 && !talent.e) {
talent.e = lv
continue
}
if (maxLv >= 10 && !talent.q) {
talent.q = lv
continue
}
}
}
let ret = char.getAvatarTalent(talent, avatar.cons, 'original')
ret.id = id
return ret
}
}

View File

@ -3,7 +3,7 @@ import lodash from 'lodash'
import { Data, Common } from '../components/index.js' import { Data, Common } from '../components/index.js'
import { Artifact, Character } from './index.js' import { Artifact, Character } from './index.js'
export default class Avatars extends Base { export default class AvatarList extends Base {
constructor (uid, datas = []) { constructor (uid, datas = []) {
super() super()
if (!uid) { if (!uid) {
@ -65,7 +65,7 @@ export default class Avatars extends Base {
} }
async getTalentData (ids, MysApi = false) { async getTalentData (ids, MysApi = false) {
let avatarTalent = await Data.getCacheJSON(`genshin:avatar-talent:${this.uid}`) let avatarTalent = await Data.getCacheJSON(`miao:avatar-talent:${this.uid}`)
let needReq = {} let needReq = {}
lodash.forEach(ids, (id) => { lodash.forEach(ids, (id) => {
if (!avatarTalent[id]) { if (!avatarTalent[id]) {
@ -89,7 +89,7 @@ export default class Avatars extends Base {
lodash.forEach(skillRet, (talent) => { lodash.forEach(skillRet, (talent) => {
avatarTalent[talent.id] = talent avatarTalent[talent.id] = talent
}) })
await Data.setCacheJSON(`genshin:avatar-talent:${this.uid}`, avatarTalent, 3600 * 2) await Data.setCacheJSON(`miao:avatar-talent:${this.uid}`, avatarTalent, 3600 * 2)
} }
let ret = this.getData(ids) let ret = this.getData(ids)
lodash.forEach(ret, (avatar, id) => { lodash.forEach(ret, (avatar, id) => {
@ -131,6 +131,6 @@ export default class Avatars extends Base {
} }
} }
Avatars.hasTalentCache = async function (uid) { AvatarList.hasTalentCache = async function (uid) {
return !!await redis.get(`genshin:avatar-talent:${uid}`) return !!await redis.get(`miao:avatar-talent:${uid}`)
} }

View File

@ -41,6 +41,12 @@ class Character extends Base {
return this.isCustom ? this._id : this._id * 1 return this.isCustom ? this._id : this._id * 1
} }
get sName () {
let name = this.name
let abbr = this.abbr
return name.length <= 4 ? name : (abbr || name)
}
// 是否是旅行者 // 是否是旅行者
get isTraveler () { get isTraveler () {
return CharId.isTraveler(this.id) return CharId.isTraveler(this.id)
@ -78,6 +84,10 @@ class Character extends Base {
return this.getImgs().side return this.getImgs().side
} }
get imgs () {
return this.getImgs()
}
// 获取详情数据 // 获取详情数据
get detail () { get detail () {
return this.getDetail() return this.getDetail()
@ -163,7 +173,7 @@ class Character extends Base {
setTraveler (uid = '') { setTraveler (uid = '') {
if (this.isTraveler && uid && uid.toString().length === 9) { if (this.isTraveler && uid && uid.toString().length === 9) {
Data.setCacheJSON(`genshin:uid-traveler:${uid}`, { Data.setCacheJSON(`miao:uid-traveler:${uid}`, {
id: CharId.getTravelerId(this.id), id: CharId.getTravelerId(this.id),
elem: this.elem elem: this.elem
}, 3600 * 24 * 120) }, 3600 * 24 * 120)
@ -172,7 +182,7 @@ class Character extends Base {
async getTraveler (uid) { async getTraveler (uid) {
if (this.isTraveler) { if (this.isTraveler) {
let tData = await Data.getCacheJSON(`genshin:uid-traveler:${uid}`) let tData = await Data.getCacheJSON(`miao:uid-traveler:${uid}`)
return Character.get({ return Character.get({
id: CharId.getTravelerId(tData.id || this.id), id: CharId.getTravelerId(tData.id || this.id),
elem: tData.elem || (this.elem !== 'multi' ? this.elem : 'anemo') elem: tData.elem || (this.elem !== 'multi' ? this.elem : 'anemo')

View File

@ -125,6 +125,14 @@ export default class ProfileData extends Base {
return '' return ''
} }
get dataSourceName () {
return {
enka: 'Enka.Network',
miao: 'MiaoApi',
input: 'Input'
}[this.dataSource] || 'Enka.NetWork'
}
// 获取当前profileData的圣遗物评分withDetail=false仅返回简略信息 // 获取当前profileData的圣遗物评分withDetail=false仅返回简略信息
getArtisMark (withDetail = true) { getArtisMark (withDetail = true) {
if (this.hasData) { if (this.hasData) {

View File

@ -1,7 +1,8 @@
import Base from './Base.js' import Base from './Base.js'
import Character from './Character.js' import Character from './Character.js'
import Artifact from './Artifact.js' import Artifact from './Artifact.js'
import Avatars from './Avatars.js' import Avatar from './Avatar.js'
import AvatarList from './AvatarList.js'
import Abyss from './Abyss.js' import Abyss from './Abyss.js'
import ProfileServ from './ProfileServ.js' import ProfileServ from './ProfileServ.js'
import ProfileReq from './ProfileReq.js' import ProfileReq from './ProfileReq.js'
@ -16,7 +17,8 @@ export {
Abyss, Abyss,
Character, Character,
Artifact, Artifact,
Avatars, Avatar,
AvatarList,
ProfileServ, ProfileServ,
ProfileReq, ProfileReq,
ProfileData, ProfileData,

View File

@ -29,37 +29,42 @@ body {
} }
.info { .info {
position: absolute; position: absolute;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.5); background: rgba(0, 0, 0, 0.5);
bottom: 0px;
left: 0px;
right: 0px;
box-shadow: 0 -5px 10px 0 #000;
padding: 5px 10px 10px 150px;
text-shadow: 0 0 1px #000, 1px 1px 3px #000;
} }
.role_box { .char-title {
padding: 5px 10px; padding: 5px 10px;
background-repeat: no-repeat; background-repeat: no-repeat;
position: absolute;
left: 0;
top: 0;
text-shadow: 0 0 3px #000, 3px 3px 5px #000;
}
.char-title .char-name {
padding-left: 10px;
display: inline-block;
white-space: nowrap;
position: relative; position: relative;
} }
.title { .char-title .char-name > * {
font-size: 36px; vertical-align: bottom;
} }
.char_name { .char-title .char-name strong {
font-family: Number, "印品南征北战NZBZ体", NZBZ, "汉仪文黑-65W", YS, PingFangSC-Medium, "PingFang SC", sans-serif; font-family: Number, "印品南征北战NZBZ体", NZBZ, "汉仪文黑-65W", YS, PingFangSC-Medium, "PingFang SC", sans-serif;
font-size: 60px; font-size: 60px;
letter-spacing: 5px; letter-spacing: 5px;
line-height: 90px; font-weight: normal;
display: inline-block;
white-space: nowrap;
position: absolute;
top: 10px;
padding-left: 20px;
left: 0;
height: 85px;
text-shadow: 0 0 3px #000, 3px 3px 5px #000;
} }
.char_name:after { .char-title .char-name .cons {
font-size: 20px;
padding: 3px 8px;
border-radius: 8px;
margin: 10px 0;
text-shadow: 0 0 1px #000;
}
.char-title .char-name:after {
content: ""; content: "";
display: block; display: block;
position: absolute; position: absolute;
@ -67,36 +72,18 @@ body {
right: -50px; right: -50px;
min-width: 360px; min-width: 360px;
height: 1px; height: 1px;
bottom: 0;
left: -50px; left: -50px;
opacity: 1; opacity: 1;
transition: width 0.3s 0.1s, opacity 0.3s 0.1s; transition: width 0.3s 0.1s, opacity 0.3s 0.1s;
box-shadow: 0 0 2px 0 #000; box-shadow: 0 0 2px 0 #000;
bottom: 1px; bottom: 1px;
} }
.char_name .uid { .char-title .char-lv {
font-size: 24px; font-size: 20px;
position: absolute;
height: 25px; height: 25px;
line-height: 25px; line-height: 25px;
top: -25px;
left: 15px;
letter-spacing: 0; letter-spacing: 0;
top: 90px; padding-left: 10px;
}
.cons {
display: inline-block;
width: 55px;
height: 35px;
line-height: 35px;
border-radius: 10px;
font-size: 20px;
vertical-align: middle;
text-align: center;
letter-spacing: 0px;
box-shadow: 0px 0px 3px 0px #000;
text-shadow: 0 0 3px #000;
margin-right: 15px;
} }
.crown { .crown {
width: 30px; width: 30px;
@ -120,307 +107,7 @@ body {
font-size: 26px; font-size: 26px;
margin: 10px 5px 2px 5px; margin: 10px 5px 2px 5px;
} }
.weapon {
text-align: center;
font-size: 20px;
width: 100px;
position: absolute;
background: rgba(0, 0, 0, 0.2);
}
.weapon_lv {
position: absolute;
bottom: 0px;
right: 0;
font-size: 18px;
border-radius: 5px;
padding: 3px 5px;
background-color: rgba(0, 0, 0, var(--bg-opacity));
--bg-opacity: 0.75;
}
.weapon_affix {
position: absolute;
top: 0;
right: 0;
width: 30px;
height: 30px;
font-size: 20px;
text-align: center;
line-height: 30px;
background: #000;
border-radius: 5px;
padding: 1px 3px;
}
.weapon_cont {
position: relative;
}
.weapon_cont img {
width: 100%;
height: 100%;
}
.weapon_name {
height: 30px;
line-height: 30px;
font-size: 15px;
}
.equiv .img_box {
width: 46px;
height: 46px;
border: 1px solid #d3bc8d;
border-radius: 5px;
overflow: hidden;
}
.equiv img {
width: 100%;
transform: scale(1.2, 1.2);
}
.detail {
margin-left: 5px;
width: 300px;
margin-top: 3px;
padding: 5px 0;
display: flex;
position: relative;
}
.talent {
margin-left: 5px;
width: 300px;
padding: 5px 5px 8px;
display: flex;
position: relative;
font-size: 20px;
}
.text_box::before {
content: "";
display: block;
position: absolute;
background-image: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.5) 20%, rgba(255, 255, 255, 0.5) 80%, rgba(255, 255, 255, 0) 100%);
width: 0%;
height: 1px;
top: 0;
left: -15px;
width: 300px;
opacity: 1;
transition: width 0.3s 0.1s, opacity 0.3s 0.1s;
}
.text_box::after {
content: "";
display: block;
position: absolute;
background-image: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.5) 20%, rgba(255, 255, 255, 0.5) 80%, rgba(255, 255, 255, 0) 100%);
width: 0%;
height: 1px;
bottom: 0;
left: -15px;
width: 300px;
opacity: 1;
transition: width 0.3s 0.1s, opacity 0.3s 0.1s;
}
.detail p,
.talent div {
margin-right: 4px;
line-height: 16px;
width: 90px;
white-space: nowrap;
}
.no_skill {
padding: 10px 0;
}
.star {
width: 16px;
vertical-align: -2px;
margin-right: 1px;
}
.equiv {
margin-top: 12px;
}
.row {
display: flex;
flex-wrap: wrap;
/*margin-bottom: 5px;*/
}
.equiv {
margin: 0 10px 8px 10px;
text-align: center;
font-size: 20px;
padding: 3px;
background: rgba(0, 0, 0, 0.6);
border-radius: 5px;
height: 52px;
width: 52px;
position: relative;
display: flex;
}
.equiv .num {
position: absolute;
bottom: 0px;
font-size: 12px;
/*background: rgba(0,0,0,.6);*/
border-radius: 5px;
padding: 1px 5px;
background-color: rgba(0, 0, 0, var(--bg-opacity));
--bg-opacity: 0.75;
border-radius: 9999px;
}
.equiv .img_box {
width: 46px;
height: 46px;
border: 1px solid #d3bc8d;
border-radius: 5px;
overflow: hidden;
}
.equiv img {
width: 100%;
transform: scale(1.2, 1.2);
}
.equiv_info {
display: inline-block;
font-size: 15px;
padding: 5px 5px 1px 7px;
border-radius: 10px;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), rgba(114, 102, 104, 0.3);
margin-left: 5px;
margin-top: 0px;
}
.equiv_info .text {
margin-bottom: 5px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
body.bottom_mode {
width: 500px;
}
.bottom_mode .info {
height: 158px;
}
.bottom_mode .weapon {
left: 0;
bottom: 0;
top: 0px;
padding-top: 120px;
width: 140px;
}
.bottom_mode .weapon_affix {
display: none;
}
.bottom_mode .weapon_cont {
position: absolute;
top: 0;
width: 100%;
}
.bottom_mode .weapon_lv {
border-radius: 8px 0 0 0;
padding-left: 8px;
background: rgba(0, 0, 0, 0.5);
bottom: -8px;
font-size: 15px;
}
.bottom_mode .weapon_cont img {
width: 110px;
height: 110px;
}
.bottom_mode .weapon_name {
background: rgba(0, 0, 0, 0.5);
height: 35px;
line-height: 35px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.equiv_info {
width: calc(100% - 20px);
}
.bottom_mode .detail {
font-family: Number, "印品南征北战NZBZ体", NZBZ, "汉仪文黑-65W", YS, PingFangSC-Medium, "PingFang SC", sans-serif;
margin-top: 0px;
}
.bottom_mode .for_left {
display: none;
}
/******** left mode **********/ /******** left mode **********/
.left_mode {
width: 800px;
transform: scale(1);
}
.left_mode .info {
right: initial;
padding: 10px 10px 5px 10px;
border-radius: 8px;
left: 10px;
bottom: 10px;
}
.left_mode .weapon {
top: -110px;
width: 270px;
height: 100px;
padding: 0 0 3px 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
border-radius: 8px;
}
.left_mode .weapon_cont {
width: 100px;
padding: 3px 10px 0 0;
border-radius: 0 10px 0 0;
border-right: 0.5px solid rgba(0, 0, 0, 0.3);
position: absolute;
top: 0;
}
.left_mode .for_bottom,
.left_mode .weapon_lv,
.left_mode .weapon_affix {
display: none;
}
.left_mode .for_left {
display: block;
}
.left_mode .weapon_name {
height: 50px;
font-size: 20px;
text-align: left;
line-height: 30px;
padding: 20px 0 0 110px;
}
.left_mode .detail {
width: auto;
margin-top: -5px;
}
.left_mode .talent {
padding-left: 0;
margin-right: -5px;
width: 250px;
}
.left_mode .info,
.left_mode .weapon {
background: rgba(0, 0, 0, 0.5);
box-shadow: 0 0 5px 1px #000;
}
.left_mode .equiv_info {
padding: 0;
background: none;
margin-top: 5px;
}
.copyright {
position: absolute;
margin-bottom: 0;
}
.left_mode .copyright {
bottom: 5px;
right: 9px;
text-shadow: 1px 1px 1px #000;
line-height: 20px;
}
.bottom_mode .copyright {
bottom: 1px;
right: 7px;
text-shadow: 1px 1px 1px #000;
line-height: 20px;
font-size: 10px;
}
.no-info { .no-info {
position: absolute; position: absolute;
padding: 5px 10px; padding: 5px 10px;
@ -431,7 +118,249 @@ body.bottom_mode {
text-shadow: 1px 1px 1px #000; text-shadow: 1px 1px 1px #000;
border-radius: 5px; border-radius: 5px;
} }
.notice-cont {
color: #ccc;
font-size: 14px;
text-align: center;
}
.bottom_mode .no-info { .bottom_mode .no-info {
bottom: 25px; bottom: 25px;
} }
.char-talents {
display: flex;
}
.char-detail {
display: flex;
margin: 0;
border-radius: 0;
padding: 4px;
}
.char-detail > .cont {
position: relative;
width: 200px;
height: 90px;
margin: 4px;
}
.weapon-cont {
width: 180px;
display: flex;
text-shadow: 1px 1px 1px #000;
}
.weapon-cont .img {
width: 80px;
height: 80px;
}
.weapon-cont .star {
height: 20px;
width: 100px;
background: url("../common/item/star.png") no-repeat;
background-size: 100px 100px;
transform: scale(0.8);
transform-origin: -5px center;
display: inline-block;
margin: 1px 0;
}
.weapon-cont .star.star-2 {
background-position: 0 -20px;
}
.weapon-cont .star.star-3 {
background-position: 0 -40px;
}
.weapon-cont .star.star-4 {
background-position: 0 -60px;
}
.weapon-cont .star.star-5 {
background-position: 0 -80px;
}
.weapon-cont .weapon-info {
padding: 13px 0 0 13px;
}
.weapon-cont .weapon-info strong {
font-size: 17px;
}
.talent-cont {
display: flex;
padding: 0 5px;
}
.talent-cont .talent-item,
.talent-cont .talent-icon {
width: 100px;
height: 100px;
}
.talent-cont .talent-item {
position: relative;
}
.talent-cont .talent-icon {
width: 60px;
height: 60px;
display: table;
position: relative;
margin: 7px -5px 13x;
border-radius: 50%;
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
z-index: 90;
}
.talent-cont .talent-icon img,
.talent-cont .talent-icon .talent-icon-img {
width: 46%;
height: 46%;
position: absolute;
top: 50%;
left: 50%;
margin: -22% 0 0 -23%;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.talent-cont .talent-icon span {
background: #fff;
width: 34px;
height: 25px;
line-height: 25px;
font-size: 16px;
text-align: center;
border-radius: 5px;
position: absolute;
bottom: -15px;
left: 50%;
margin-left: -15px;
color: #000;
box-shadow: 0 0 5px 0 #000;
}
.talent-cont .talent-icon.talent-plus span {
background: #2e353e;
color: #ffdfa0;
font-weight: bold;
box-shadow: 0 0 1px 0 #d3bc8e, 1px 1px 2px 0 rgba(0, 0, 0, 0.5);
}
.talent-cont .talent-icon.talent-crown:after {
content: "";
display: none;
width: 24px;
height: 24px;
background: url("../character/imgs/crown.png") no-repeat;
background-size: contain;
position: absolute;
left: 50%;
top: -5px;
margin-left: -12px;
}
.artis-cont .artis-list {
display: flex;
height: 50px;
padding: 5px;
}
.artis-cont .artis-list .item {
height: 50px;
width: 20%;
}
.artis-cont .artis-list .item .item-icon {
width: 110%;
height: 110%;
margin: -5% -5% 0;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.artis-cont .artis-list .item .lv {
display: block;
font-size: 14px;
text-align: center;
}
.bottom-mode {
width: 600px;
}
.bottom-mode .copyright {
font-size: 12px;
position: absolute;
bottom: 0;
margin: 0;
right: 0;
height: 25px;
line-height: 25px;
padding: 0 10px;
}
.bottom-mode .copyright.data-source {
border-top: 1px solid rgba(255, 255, 255, 0.3);
left: 0;
text-align: left;
background: rgba(0, 0, 0, 0.5);
}
.bottom-mode .char-detail {
position: absolute;
bottom: 25px;
left: 0;
right: 0;
padding: 4px 0;
}
.bottom-mode .char-detail > .cont {
background: none;
box-shadow: none;
margin: 8px 0 0;
}
.bottom-mode .char-detail > .cont.left-line:after,
.bottom-mode .char-detail > .cont.right-line:after {
content: "";
display: block;
width: 1px;
height: 50px;
background: rgba(255, 255, 255, 0.5);
position: absolute;
top: 20px;
right: 0;
}
.bottom-mode .char-detail > .cont.right-line:after {
right: initial;
left: 0;
}
.bottom-mode .char-detail .notice-cont {
padding-top: 40px;
}
.left-mode {
height: 500px;
width: auto;
}
.left-mode .container {
width: auto;
}
.left-mode img.bg {
width: auto;
height: 500px;
}
.left-mode .copyright {
font-size: 12px;
position: absolute;
bottom: 0;
margin: 0;
right: 0;
height: 25px;
line-height: 25px;
padding: 0 10px;
}
.left-mode .copyright.data-source {
border-top: 1px solid rgba(255, 255, 255, 0.3);
left: 0;
text-align: left;
background: rgba(0, 0, 0, 0.5);
}
.left-mode .char-detail {
position: absolute;
bottom: 25px;
left: 0;
padding: 4px 0;
background: none;
box-shadow: none;
display: block;
}
.left-mode .char-detail > .cont {
padding-top: 8px;
margin-top: 8px;
}
.left-mode .char-detail .notice-cont {
height: 30px;
line-height: 16px;
background-size: 100% 200%;
}
/*# sourceMappingURL=character-card.css.map */ /*# sourceMappingURL=character-card.css.map */

View File

@ -1,71 +1,95 @@
<!DOCTYPE html> {{extend defaultLayout}}
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8"/>
<link rel="shortcut icon" href="#"/>
<link rel="stylesheet" type="text/css" href="{{_res_path}}/common/common.css?v=1.0"/>
<link rel="stylesheet" type="text/css" href="{{_res_path}}/character/character-card.css?v=1.0"/>
</head>
<body class="{{bg.mode}}_mode" {{sys.scale}}>
<div class="container" id="container"> {{block 'css'}}
{{if level}} <link rel="stylesheet" type="text/css" href="{{_res_path}}/common/common.css"/>
<div class="char_name"> <link rel="stylesheet" type="text/css" href="{{_res_path}}/character/character-card.css"/>
<div class="uid">ID:{{uid}}</div> {{@widthStyle}}
<span>{{ds.name}}</span> {{/block}}
<span
class="cons cons-{{cons}}">{{cons}}命</span> {{block 'main'}}
</div> <div>
<div class="info"> <div class="char-title">
<div class="detail"> Lv.{{level}} ❤{{fetter}} <div class="char-name">
<span class="crown crown_{{crownNum}}"></span> <strong>{{data.sName}}</strong>
{{if data.fetter}} <span class="fetter fetter{{data.fetter}}"></span> {{/if}}
{{if data.cons}} <span class="cons cons-{{data.cons}}">{{data.cons}}命</span> {{/if}}
</div>
<div class="char-lv">
<span>Uid:{{uid}}</span>
{{if data.level}}<span>Lv.{{data.level}}</span>{{/if}}
</div>
</div>
{{if data.level}}
{{set weapon = data.weapon }}
<div class="char-detail cont">
<div class="cont weapon-cont left-line">
<img class="img" src="{{_res_path}}{{weapon.img}}"/>
<div class="weapon-info">
<strong>{{weapon.name}}</strong>
<div class="star star-{{weapon.star}}"></div>
<span>Lv.{{weapon.leve || weapon.level}} <span
class="affix affix-{{weapon.affix}}">精{{weapon.affix}}</span></span>
</div>
</div> </div>
<div class="weapon">
<div class="weapon_cont">
<img title="{{weapon.name}}" src="{{_res_path}}/meta/weapons/icon/{{weapon.name}}.png"/>
<p class="weapon_lv">Lv.{{weapon.level}}</p> {{set talent = data.talent }}
<p class="weapon_affix">{{weapon.affix}}</p> {{set keys = ['a','e','q'] }}
</div> {{ if talent.a && talent.a.level }}
<p class="weapon_name"> <div class="cont talent-cont elem-{{data.elem}}">
<span class="for_left">Lv.{{weapon.level}} 精{{weapon.affix}}</span> {{each keys key}}
<span class="for_bottom">精{{weapon.affix}} </span> <div class="talent-item">
{{weapon.name}} <div class="talent-icon
</p> {{talent[key].level > talent[key].original ? `talent-plus`:``}}
</div> {{talent[key].original >= 10 ? `talent-crown`:``}}">
<div class="talent-icon-img"
style="background-image:url({{_res_path}}{{data.imgs[key]}})"></div>
<span>{{talent[key].level}}</span>
</div>
{{ if talent.a }} </div>
<div class="talent"> {{/each}}
{{each talentMap name key}}
<div class="talent_{{key}}">{{name}}: <span>{{ talent[key].level}}</span></div>
{{/each}}
</div> </div>
{{else}} {{else}}
<div class="talent"> <div class="cont notice-cont">
<div class="talent_{{key}}">请绑定Cookie以查询天赋信息</div> 请绑定CK以获取天赋信息
</div> </div>
{{/if}} {{/if}}
<div class="equiv_info">
<div class="text">{{artiEffect[0]|| "-"}}</div>
<div class="text">{{artiEffect[1] || "-"}}</div> <div class="cont artis-cont right-line">
{{if data.artis}}
<div class="artis-list">
{{each data.artis arti}}
<div class="item">
<div class="item-icon"
style="background-image:url({{_res_path}}meta/reliquaries/icon/{{arti.name}}.png)"></div>
<span></span>
<span class="lv">{{arti.level}}</span>
</div>
{{/each}}
</div>
{{/if}}
</div> </div>
</div>
{{else}}
<div class="char_name">
<div class="uid">ID:{{uid}}</div>
<span>{{ds.name}}</span>
</div>
{{if custom}}
<div class="no-info">自定义角色暂无角色信息</div>
{{else}}
<div class="no-info">未能获取到角色信息,请将角色放置在米游社角色展柜中</div>
{{/if}}
{{/if}}
<div class="copyright">{{@sys.copyright}}</div>
<div>
<img src="{{_res_path}}{{bg.img}}" title="{{name}}" class="bg"></div>
</div> </div>
</body> <div class="copyright data-source">
<script type="text/javascript"></script> 数据源:{{data.dataSourceName}} {{data.updateTime}}
</html> </div>
{{else}}
{{if custom}}
<div class="no-info">自定义角色暂无角色信息</div>
{{else}}
<div class="no-info">未能获取到角色信息,请将角色放置在米游社角色展柜中</div>
{{/if}}
{{/if}}
<div><img src="{{_res_path}}{{bg.img}}" title="{{name}}" class="bg"></div>
</div>
{{/block}}

View File

@ -30,81 +30,70 @@ body {
.info { .info {
position: absolute; position: absolute;
background: rgba(0, 0, 0, .5); bottom: 0;
bottom: 0px; left: 0;
left: 0px; right: 0;
right: 0px; background: rgba(0, 0, 0, 0.5)
box-shadow: 0 -5px 10px 0 #000;
padding: 5px 10px 10px 150px;
text-shadow: 0 0 1px #000, 1px 1px 3px #000;
} }
.role_box { .char-title {
padding: 5px 10px; padding: 5px 10px;
background-repeat: no-repeat; background-repeat: no-repeat;
position: relative;
}
.title {
font-size: 36px;
}
.char_name {
.font-NZBZ;
font-size: 60px;
letter-spacing: 5px;
line-height: 90px;
display: inline-block;
white-space: nowrap;
position: absolute; position: absolute;
top: 10px;
padding-left: 20px;
left: 0; left: 0;
height: 85px; top: 0;
text-shadow: 0 0 3px #000, 3px 3px 5px #000; text-shadow: 0 0 3px #000, 3px 3px 5px #000;
}
.char_name:after {
content: "";
display: block;
position: absolute;
background-image: linear-gradient(to right, rgba(255, 255, 255, 0.5) 20%, rgba(255, 255, 255, 0.5) 80%, rgba(255, 255, 255, 0) 100%);
right: -50px;
min-width: 360px;
height: 1px;
bottom: 0;
left: -50px;
opacity: 1;
transition: width 0.3s 0.1s, opacity 0.3s 0.1s;
box-shadow: 0 0 2px 0 #000;
bottom: 1px;
}
.char_name .uid { .char-name {
font-size: 24px; padding-left: 10px;
position: absolute; display: inline-block;
height: 25px; white-space: nowrap;
line-height: 25px; position: relative;
top: -25px;
left: 15px;
letter-spacing: 0;
top: 90px;
}
.cons { & > * {
display: inline-block; vertical-align: bottom;
width: 55px; }
height: 35px;
line-height: 35px; strong {
border-radius: 10px; .font-NZBZ;
font-size: 20px; font-size: 60px;
vertical-align: middle; letter-spacing: 5px;
text-align: center; font-weight: normal;
letter-spacing: 0px; }
box-shadow: 0px 0px 3px 0px #000;
text-shadow: 0 0 3px #000; .cons {
margin-right: 15px; font-size: 20px;
padding: 3px 8px;
border-radius: 8px;
margin: 10px 0;
text-shadow: 0 0 1px #000;
}
&:after {
content: "";
display: block;
position: absolute;
background-image: linear-gradient(to right, rgba(255, 255, 255, 0.5) 20%, rgba(255, 255, 255, 0.5) 80%, rgba(255, 255, 255, 0) 100%);
right: -50px;
min-width: 360px;
height: 1px;
left: -50px;
opacity: 1;
transition: width 0.3s 0.1s, opacity 0.3s 0.1s;
box-shadow: 0 0 2px 0 #000;
bottom: 1px;
}
}
.char-lv {
font-size: 20px;
height: 25px;
line-height: 25px;
letter-spacing: 0;
padding-left: 10px;
}
} }
.crown { .crown {
@ -115,22 +104,18 @@ body {
background-size: contain; background-size: contain;
vertical-align: bottom; vertical-align: bottom;
background-image: url("./imgs/crown.png"); background-image: url("./imgs/crown.png");
}
.crown.crown_0 { &.crown_0 {
background-image: none; background-image: none;
} }
.crown.crown_1 { &.crown_2 {
width: 60px;
}
} &.crown_3 {
width: 90px;
.crown.crown_2 { }
width: 60px;
}
.crown.crown_3 {
width: 90px;
} }
.detail { .detail {
@ -139,372 +124,7 @@ body {
} }
.weapon {
text-align: center;
font-size: 20px;
width: 100px;
position: absolute;
background: rgba(0, 0, 0, 0.2);
}
.weapon_lv {
position: absolute;
bottom: 0px;
right: 0;
font-size: 18px;
border-radius: 5px;
padding: 3px 5px;
background-color: rgba(0, 0, 0, var(--bg-opacity));
--bg-opacity: 0.75;
}
.weapon_affix {
position: absolute;
top: 0;
right: 0;
width: 30px;
height: 30px;
font-size: 20px;
text-align: center;
line-height: 30px;
background: #000;
border-radius: 5px;
padding: 1px 3px;
}
.weapon_cont {
position: relative;
}
.weapon_cont img {
width: 100%;
height: 100%;
}
.weapon_name {
height: 30px;
line-height: 30px;
font-size: 15px;
}
.equiv .img_box {
width: 46px;
height: 46px;
border: 1px solid #d3bc8d;
border-radius: 5px;
overflow: hidden;
}
.equiv img {
width: 100%;
transform: scale(1.2, 1.2);
}
.detail {
margin-left: 5px;
width: 300px;
margin-top: 3px;
padding: 5px 0;
display: flex;
position: relative;
}
.talent {
margin-left: 5px;
width: 300px;
padding: 5px 5px 8px;
display: flex;
position: relative;
font-size: 20px;
}
.text_box::before {
content: "";
display: block;
position: absolute;
background-image: linear-gradient(to right,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.5) 20%,
rgba(255, 255, 255, 0.5) 80%,
rgba(255, 255, 255, 0) 100%);
width: 0%;
height: 1px;
top: 0;
left: -15px;
width: 300px;
opacity: 1;
transition: width 0.3s 0.1s, opacity 0.3s 0.1s;
}
.text_box::after {
content: "";
display: block;
position: absolute;
background-image: linear-gradient(to right,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.5) 20%,
rgba(255, 255, 255, 0.5) 80%,
rgba(255, 255, 255, 0) 100%);
width: 0%;
height: 1px;
bottom: 0;
left: -15px;
width: 300px;
opacity: 1;
transition: width 0.3s 0.1s, opacity 0.3s 0.1s;
}
.detail p,
.talent div {
margin-right: 4px;
line-height: 16px;
width: 90px;
white-space: nowrap;
}
.no_skill {
padding: 10px 0;
}
.star {
width: 16px;
vertical-align: -2px;
margin-right: 1px;
}
.equiv {
margin-top: 12px;
}
.row {
display: flex;
flex-wrap: wrap;
/*margin-bottom: 5px;*/
}
.equiv {
margin: 0 10px 8px 10px;
text-align: center;
font-size: 20px;
padding: 3px;
background: rgba(0, 0, 0, 0.6);
border-radius: 5px;
height: 52px;
width: 52px;
position: relative;
display: flex;
}
.equiv .num {
position: absolute;
bottom: 0px;
font-size: 12px;
/*background: rgba(0,0,0,.6);*/
border-radius: 5px;
padding: 1px 5px;
background-color: rgba(0, 0, 0, var(--bg-opacity));
--bg-opacity: 0.75;
border-radius: 9999px;
}
.equiv .img_box {
width: 46px;
height: 46px;
border: 1px solid #d3bc8d;
border-radius: 5px;
overflow: hidden;
}
.equiv img {
width: 100%;
transform: scale(1.2, 1.2);
}
.equiv_info {
display: inline-block;
font-size: 15px;
padding: 5px 5px 1px 7px;
border-radius: 10px;
background: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.2)), rgba(114, 102, 104, 0.3);
margin-left: 5px;
margin-top: 0px;
}
.equiv_info .text {
margin-bottom: 5px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
body.bottom_mode {
width: 500px;
}
.bottom_mode .info {
height: 158px;
}
.bottom_mode .weapon {
left: 0;
bottom: 0;
top: 0px;
padding-top: 120px;
width: 140px;
}
.bottom_mode .weapon_affix {
display: none;
}
.bottom_mode .weapon_cont {
position: absolute;
top: 0;
width: 100%;
}
.bottom_mode .weapon_lv {
border-radius: 8px 0 0 0;
padding-left: 8px;
background: rgba(0, 0, 0, .5);
bottom: -8px;
font-size: 15px;
}
.bottom_mode .weapon_cont img {
width: 110px;
height: 110px;
}
.bottom_mode .weapon_name {
background: rgba(0, 0, 0, .5);
height: 35px;
line-height: 35px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
.equiv_info {
width: calc(100% - 20px);
}
.bottom_mode .detail {
.font-NZBZ;
margin-top: 0px;
}
.bottom_mode .for_left {
display: none;
}
/******** left mode **********/ /******** left mode **********/
.left_mode {
width: 800px;
transform: scale(1);
}
.left_mode .info {
right: initial;
padding: 10px 10px 5px 10px;
border-radius: 8px;
left: 10px;
bottom: 10px;
}
.left_mode .weapon {
top: -110px;
width: 270px;
height: 100px;
padding: 0 0 3px 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
border-radius: 8px;
}
.left_mode .weapon_cont {
width: 100px;
padding: 3px 10px 0 0;
border-radius: 0 10px 0 0;
border-right: 0.5px solid rgba(0, 0, 0, 0.3);
position: absolute;
top: 0;
}
.left_mode .for_bottom,
.left_mode .weapon_lv,
.left_mode .weapon_affix {
display: none;
}
.left_mode .for_left {
display: block;
}
.left_mode .weapon_name {
height: 50px;
font-size: 20px;
text-align: left;
line-height: 30px;
padding: 20px 0 0 110px;
}
.left_mode .detail {
width: auto;
margin-top: -5px;
}
.left_mode .talent {
padding-left: 0;
margin-right: -5px;
width: 250px;
}
.left_mode .info,
.left_mode .weapon {
background: rgba(0, 0, 0, 0.5);
box-shadow: 0 0 5px 1px #000;
}
.left_mode .equiv_info {
padding: 0;
background: none;
margin-top: 5px;
}
.copyright {
position: absolute;
margin-bottom: 0;
}
.left_mode .copyright {
bottom: 5px;
right: 9px;
text-shadow: 1px 1px 1px #000;
line-height: 20px;
}
.bottom_mode .copyright {
bottom: 1px;
right: 7px;
text-shadow: 1px 1px 1px #000;
line-height: 20px;
font-size: 10px;
}
.no-info { .no-info {
position: absolute; position: absolute;
padding: 5px 10px; padding: 5px 10px;
@ -516,6 +136,294 @@ body.bottom_mode {
border-radius: 5px; border-radius: 5px;
} }
.notice-cont {
color: #ccc;
font-size: 14px;
text-align: center;
}
.bottom_mode .no-info { .bottom_mode .no-info {
bottom: 25px; bottom: 25px;
} }
.char-talents {
display: flex;
}
.char-detail {
display: flex;
margin: 0;
border-radius: 0;
padding: 4px;
& > .cont {
position: relative;
width: 200px;
height: 90px;
margin: 4px;
}
}
.weapon-cont {
width: 180px;
display: flex;
text-shadow: 1px 1px 1px #000;
.img {
width: 80px;
height: 80px;
}
.star {
height: 20px;
width: 100px;
background: url("../common/item/star.png") no-repeat;
background-size: 100px 100px;
transform: scale(0.8);
transform-origin: -5px center;
display: inline-block;
margin: 1px 0;
&.star-2 {
background-position: 0 -20px;
}
&.star-3 {
background-position: 0 -40px;
}
&.star-4 {
background-position: 0 -60px;
}
&.star-5 {
background-position: 0 -80px;
}
}
.weapon-info {
padding: 13px 0 0 13px;
strong {
font-size: 17px;
}
}
}
.talent-cont {
display: flex;
padding: 0 5px;
.talent-item, .talent-icon {
width: 100px;
height: 100px;
}
.talent-item {
position: relative;
}
.talent-icon {
width: 60px;
height: 60px;
display: table;
position: relative;
margin: 7px -5px 13x;
border-radius: 50%;
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
z-index: 90;
img,
.talent-icon-img {
width: 46%;
height: 46%;
position: absolute;
top: 50%;
left: 50%;
margin: -22% 0 0 -23%;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
span {
background: #fff;
width: 34px;
height: 25px;
line-height: 25px;
font-size: 16px;
text-align: center;
border-radius: 5px;
position: absolute;
bottom: -15px;
left: 50%;
margin-left: -15px;
color: #000;
box-shadow: 0 0 5px 0 #000;
}
&.talent-plus span {
background: #2e353e;
color: #ffdfa0;
font-weight: bold;
box-shadow: 0 0 1px 0 #d3bc8e, 1px 1px 2px 0 rgba(0, 0, 0, 0.5);
}
&.talent-crown:after {
content: "";
display: none;
width: 24px;
height: 24px;
background: url("../character/imgs/crown.png") no-repeat;
background-size: contain;
position: absolute;
left: 50%;
top: -5px;
margin-left: -12px;
}
}
}
.artis-cont {
.artis-list {
display: flex;
height: 50px;
padding: 5px;
.item {
height: 50px;
width: 20%;
.item-icon {
width: 110%;
height: 110%;
margin: -5% -5% 0;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.lv {
display: block;
font-size: 14px;
text-align: center;
}
}
}
}
.bottom-mode {
width: 600px;
.copyright {
font-size: 12px;
position: absolute;
bottom: 0;
margin: 0;
right: 0;
height: 25px;
line-height: 25px;
padding: 0 10px;
&.data-source {
border-top: 1px solid rgba(255, 255, 255, .3);
left: 0;
text-align: left;
background: rgba(0, 0, 0, 0.5)
}
}
.char-detail {
position: absolute;
bottom: 25px;
left: 0;
right: 0;
padding: 4px 0;
& > .cont {
background: none;
box-shadow: none;
margin: 8px 0 0;
&.left-line,
&.right-line {
&:after {
content: "";
display: block;
width: 1px;
height: 50px;
background: rgba(255, 255, 255, .5);
position: absolute;
top: 20px;
right: 0;
}
}
&.right-line:after {
right: initial;
left: 0;
}
}
.notice-cont {
padding-top: 40px;
}
}
}
.left-mode {
height: 500px;
width: auto;
.container {
width: auto;
}
img.bg {
width: auto;
height: 500px;
}
.copyright {
font-size: 12px;
position: absolute;
bottom: 0;
margin: 0;
right: 0;
height: 25px;
line-height: 25px;
padding: 0 10px;
&.data-source {
border-top: 1px solid rgba(255, 255, 255, .3);
left: 0;
text-align: left;
background: rgba(0, 0, 0, 0.5)
}
}
.char-detail {
position: absolute;
bottom: 25px;
left: 0;
padding: 4px 0;
background: none;
box-shadow: none;
display: block;
& > .cont {
padding-top: 8px;
margin-top: 8px;
}
.notice-cont {
height: 30px;
line-height: 16px;
background-size: 100% 200%;
}
}
}

View File

@ -66,20 +66,6 @@
border-radius: 3px; border-radius: 3px;
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.5); box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.5);
/*
&.talent-crown:before {
content: "";
display: block;
width: 10px;
height: 10px;
position: absolute;
left: 0;
top: 0;
background: url("../character/imgs/crown.png") center no-repeat;
background-size: contain;
}
*/
&.talent-plus { &.talent-plus {
font-weight: bold; font-weight: bold;
color: #0284b9; color: #0284b9;

View File

@ -3,5 +3,5 @@ export default function ({ attr, artis, rule, def }) {
// 血牛钟离其余词缀权重不高于27.89,确保小生命命中副词缀最高权重 // 血牛钟离其余词缀权重不高于27.89,确保小生命命中副词缀最高权重
return rule('钟离-血牛', { hp: 100, atk: 27, cp: 27, cd: 27, recharge: 27 }) return rule('钟离-血牛', { hp: 100, atk: 27, cp: 27, cd: 27, recharge: 27 })
} }
return def({ hp: 80, atk: 75, cp: 100, cd: 100, dmg: 100, phy: 50, recharge: 55 }) return def({ hp: 80, atk: 75, cp: 100, cd: 100, dmg: 80, phy: 80, recharge: 55 })
} }