| @@ -1081,6 +1081,11 @@ | |||
| "integrity": "sha1-K1o6s/kYzKSKjHVMCBaOPwPrphs=", | |||
| "dev": true | |||
| }, | |||
| "@popperjs/core": { | |||
| "version": "2.4.4", | |||
| "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.4.tgz", | |||
| "integrity": "sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg==" | |||
| }, | |||
| "@soda/friendly-errors-webpack-plugin": { | |||
| "version": "1.7.1", | |||
| "resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.7.1.tgz", | |||
| @@ -10722,6 +10727,14 @@ | |||
| "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", | |||
| "dev": true | |||
| }, | |||
| "tippy.js": { | |||
| "version": "6.2.5", | |||
| "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.2.5.tgz", | |||
| "integrity": "sha512-UIf8G99PMXGmdWPrr36s/DjQBdfxMPwzvPUXsxs3tDFDTZ1SgvKG+Jvt6RJ+aBqYL0oe/STxh3MNkCV3IWAKmw==", | |||
| "requires": { | |||
| "@popperjs/core": "^2.4.4" | |||
| } | |||
| }, | |||
| "tmp": { | |||
| "version": "0.0.33", | |||
| "resolved": "https://registry.npm.taobao.org/tmp/download/tmp-0.0.33.tgz", | |||
| @@ -9,6 +9,7 @@ | |||
| }, | |||
| "dependencies": { | |||
| "core-js": "^3.6.5", | |||
| "tippy.js": "^6.2.5", | |||
| "vue": "^2.6.11", | |||
| "vue-class-component": "^7.2.3", | |||
| "vue-property-decorator": "^8.4.2" | |||
| @@ -62,54 +62,18 @@ body, html { | |||
| flex-direction: column; | |||
| } | |||
| .stat-entry { | |||
| position: relative; | |||
| } | |||
| .stat-entry::after { | |||
| opacity: 0; | |||
| position: absolute; | |||
| color: #eee; | |||
| font-size: 0pt; | |||
| content: attr(data-tooltip); | |||
| transition: 0.1s; | |||
| pointer-events: none; | |||
| left: 0pt; | |||
| top: 0pt; | |||
| transform: translate(calc(-50% + 16pt), -100%); | |||
| background: #555; | |||
| padding: 8pt; | |||
| border-radius: 8pt; | |||
| z-index: 1; | |||
| .tippy-box { | |||
| text-align: center; | |||
| } | |||
| .stat-entry:hover::after { | |||
| .tippy-box .tooltip-title { | |||
| font-size: 18pt; | |||
| opacity: 1; | |||
| } | |||
| .stat-entry::before { | |||
| opacity: 0; | |||
| position: absolute; | |||
| color: #eee; | |||
| font-size: 0pt; | |||
| content: attr(data-tooltip-full); | |||
| pointer-events: none; | |||
| left: 0pt; | |||
| top: 0pt; | |||
| transform: translate(calc(-50% + 16pt), calc(-100% - 18pt - 16pt)); | |||
| white-space: nowrap; | |||
| transition: 0.1s; | |||
| background: #555; | |||
| padding: 8pt; | |||
| border-radius: 8pt; | |||
| z-index: 1; | |||
| font-family: sans-serif; | |||
| } | |||
| .stat-entry:hover::before { | |||
| .tippy-box .tooltip-body { | |||
| font-size: 12pt; | |||
| transition: all 1s cubic-bezier(1, 0, 0.75, 0); | |||
| opacity: 1; | |||
| font-family: sans-serif; | |||
| } | |||
| </style> | |||
| @@ -3,16 +3,44 @@ | |||
| <h2 v-if="subject.perspective === firstperson">You</h2> | |||
| <h2 v-if="subject.perspective !== firstperson">{{subject.name.all.capital}}</h2> | |||
| <div class="stat-line"> | |||
| <div class="stat-entry" :data-tooltip="vigor" :data-tooltip-full="vigorDescs[vigor]" v-for="vigor in Object.keys(subject.vigors)" v-bind:key="vigor"><i :class="vigorIcons[vigor]" /><div>{{subject.vigors[vigor]}}</div></div> | |||
| <div class="stat-entry" v-for="vigor in Object.keys(subject.vigors)" v-bind:key="vigor"> | |||
| <i :class="vigorIcons[vigor]" /> | |||
| <div>{{subject.vigors[vigor]}}</div> | |||
| <div class="tooltip-template"> | |||
| <div class="tooltip-title">{{ vigor }}</div> | |||
| <div class="tooltip-body">{{ vigorDescs[vigor] }}</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <br> | |||
| <div class="stat-line"> | |||
| <div class="stat-entry" :data-tooltip="stat" :data-tooltip-full="statDescs[stat]" v-for="stat in Object.keys(subject.stats)" v-bind:key="stat"><i :class="statIcons[stat]" /> {{subject.stats[stat]}}</div> | |||
| <div class="stat-entry" v-for="stat in Object.keys(subject.stats)" v-bind:key="stat"> | |||
| <i :class="statIcons[stat]" /> | |||
| <div>{{subject.stats[stat]}}</div> | |||
| <div class="tooltip-template"> | |||
| <div class="tooltip-title">{{ stat }}</div> | |||
| <div class="tooltip-body">{{ statDescs[stat] }}</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <br> | |||
| <div class="stat-line"> | |||
| <div class="stat-entry" data-tooltip="Bulk" data-tooltip-full="How much space you take up"><i class="fas fa-weight-hanging" /> {{subject.bulk}}</div> | |||
| <div class="stat-entry" data-tooltip="Prey Count" data-tooltip-full="How many people you've eaten"><i class="fas fa-utensils" /> {{ subject.containers.reduce((total, container) => total + container.contents.length, 0) }} </div> | |||
| <div class="stat-entry"> | |||
| <i class="fas fa-weight-hanging" /> | |||
| <div> {{ subject.bulk }} </div> | |||
| <div class="tooltip-template"> | |||
| <div class="tooltip-title"> Bulk </div> | |||
| <div class="tooltip-body"> How much space you take up </div> | |||
| </div> | |||
| </div> | |||
| <div class="stat-entry"> | |||
| <i class="fas fa-utensils" /> | |||
| <div> {{ subject.containers.reduce((total, container) => total + container.contents.length, 0) }} </div> | |||
| <div class="tooltip-template"> | |||
| <div class="tooltip-title"> Prey Count </div> | |||
| <div class="tooltip-body"> How many things you've eaten </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <br> | |||
| <div>Status: {{subject.status}}</div> | |||
| @@ -25,6 +53,9 @@ import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator' | |||
| import { Creature, POV } from '@/game/entity' | |||
| import { Stats, Stat, StatIcons, StatDescs, Vigor, VigorIcons, VigorDescs } from '@/game/combat' | |||
| import ContainerView from './ContainerView.vue' | |||
| import tippy from 'tippy.js' | |||
| import 'tippy.js/dist/tippy.css' | |||
| @Component({ | |||
| components: { | |||
| ContainerView | |||
| @@ -41,8 +72,15 @@ export default class Statblock extends Vue { | |||
| private vigor = Vigor | |||
| firstperson: POV = POV.First | |||
| constructor () { | |||
| super() | |||
| mounted () { | |||
| this.$el.querySelectorAll(".stat-entry").forEach(elem => { | |||
| const tooltip = elem.querySelector(".tooltip-template") as HTMLElement | |||
| tippy(elem, { | |||
| content: tooltip | |||
| }) | |||
| }) | |||
| } | |||
| } | |||
| </script> | |||
| @@ -1,4 +1,5 @@ | |||
| import { Stat, Vigor, StatDescs, VigorDescs, StatIcons, VigorIcons } from './combat' | |||
| import tippy from 'tippy.js' | |||
| export interface LogEntry { | |||
| render: () => HTMLElement[]; | |||
| @@ -124,15 +125,24 @@ export class PropElem implements LogEntry { | |||
| const span = document.createElement("span") | |||
| span.classList.add("stat-entry") | |||
| const tooltipTemplate = document.createElement("div") | |||
| const tooltipTitle = document.createElement("div") | |||
| tooltipTitle.classList.add("tooltip-title") | |||
| const tooltipBody = document.createElement("div") | |||
| tooltipBody.classList.add("tooltip-body") | |||
| tooltipTemplate.appendChild(tooltipTitle) | |||
| tooltipTemplate.appendChild(tooltipBody) | |||
| if (this.prop in Stat) { | |||
| span.dataset.tooltip = this.prop | |||
| tooltipTitle.textContent = this.prop | |||
| } else if (this.prop in Vigor) { | |||
| span.dataset.tooltip = this.prop | |||
| tooltipTitle.textContent = this.prop | |||
| } | |||
| if (this.prop in Stat) { | |||
| span.dataset.tooltipFull = StatDescs[this.prop as Stat] | |||
| tooltipBody.textContent = StatDescs[this.prop as Stat] | |||
| } else if (this.prop in Vigor) { | |||
| span.dataset.tooltipFull = VigorDescs[this.prop as Vigor] | |||
| tooltipBody.textContent = VigorDescs[this.prop as Vigor] | |||
| } | |||
| if (this.value !== null) { | |||
| @@ -140,10 +150,13 @@ export class PropElem implements LogEntry { | |||
| span.textContent = numText + ' ' | |||
| } | |||
| new FAElem(cls).render().forEach(elem => { | |||
| span.appendChild(elem) | |||
| }) | |||
| const icon = new FAElem(cls).render()[0] | |||
| span.appendChild(icon) | |||
| tippy(icon, { | |||
| content: tooltipTemplate | |||
| }) | |||
| return [span] | |||
| } | |||
| } | |||