Added basic printing functionality
This commit is contained in:
174
rpg-docs/client/compatibility/jquery.quickfit.js
Normal file
174
rpg-docs/client/compatibility/jquery.quickfit.js
Normal file
@@ -0,0 +1,174 @@
|
||||
// jscs:disable
|
||||
// https://github.com/chunksnbits/jquery-quickfit
|
||||
(function ($) {
|
||||
var Quickfit, QuickfitHelper, defaults, pluginName;
|
||||
|
||||
pluginName = 'quickfit';
|
||||
|
||||
defaults = {
|
||||
min: 8,
|
||||
max: 12,
|
||||
tolerance: 0.02,
|
||||
truncate: false,
|
||||
width: null,
|
||||
sampleNumberOfLetters: 10,
|
||||
sampleFontSize: 12
|
||||
};
|
||||
QuickfitHelper = (function () {
|
||||
|
||||
var sharedInstance = null;
|
||||
|
||||
QuickfitHelper.instance = function (options) {
|
||||
if (!sharedInstance) {
|
||||
sharedInstance = new QuickfitHelper(options);
|
||||
}
|
||||
return sharedInstance;
|
||||
};
|
||||
|
||||
function QuickfitHelper(options) {
|
||||
this.options = options;
|
||||
|
||||
this.item = $('<span id="meassure"></span>');
|
||||
this.item.css({
|
||||
position: 'absolute',
|
||||
left: '-1000px',
|
||||
top: '-1000px',
|
||||
'font-size': "" + this.options.sampleFontSize + "px"
|
||||
});
|
||||
$('body').append(this.item);
|
||||
|
||||
this.meassures = {};
|
||||
}
|
||||
|
||||
QuickfitHelper.prototype.getMeassure = function (letter) {
|
||||
var currentMeassure;
|
||||
currentMeassure = this.meassures[letter];
|
||||
if (!currentMeassure) {
|
||||
currentMeassure = this.setMeassure(letter);
|
||||
}
|
||||
return currentMeassure;
|
||||
};
|
||||
|
||||
QuickfitHelper.prototype.setMeassure = function (letter) {
|
||||
var currentMeassure, index, sampleLetter, text, _ref;
|
||||
|
||||
text = '';
|
||||
sampleLetter = letter === ' ' ? ' ' : letter;
|
||||
|
||||
for (index = 0, _ref = this.options.sampleNumberOfLetters - 1; 0 <= _ref ? index <= _ref : index >= _ref; 0 <= _ref ? index++ : index--) {
|
||||
text += sampleLetter;
|
||||
}
|
||||
|
||||
this.item.html(text);
|
||||
currentMeassure = this.item.width() / this.options.sampleNumberOfLetters / this.options.sampleFontSize;
|
||||
this.meassures[letter] = currentMeassure;
|
||||
|
||||
return currentMeassure;
|
||||
};
|
||||
|
||||
return QuickfitHelper;
|
||||
|
||||
})();
|
||||
|
||||
Quickfit = (function () {
|
||||
|
||||
function Quickfit(element, options) {
|
||||
this.$element = element;
|
||||
this.options = $.extend({}, defaults, options);
|
||||
this.$element = $(this.$element);
|
||||
this._defaults = defaults;
|
||||
this._name = pluginName;
|
||||
this.quickfitHelper = QuickfitHelper.instance(this.options);
|
||||
}
|
||||
|
||||
Quickfit.prototype.fit = function () {
|
||||
var elementWidth;
|
||||
if (!this.options.width) {
|
||||
elementWidth = this.$element.width();
|
||||
this.options.width = elementWidth - this.options.tolerance * elementWidth;
|
||||
}
|
||||
if (this.text = this.$element.attr('data-quickfit')) {
|
||||
this.previouslyTruncated = true;
|
||||
} else {
|
||||
this.text = this.$element.text();
|
||||
}
|
||||
this.calculateFontSize();
|
||||
|
||||
if (this.options.truncate) this.truncate();
|
||||
|
||||
return {
|
||||
$element: this.$element,
|
||||
size: this.fontSize
|
||||
};
|
||||
};
|
||||
|
||||
Quickfit.prototype.calculateFontSize = function () {
|
||||
var letter, textWidth, i;
|
||||
|
||||
textWidth = 0;
|
||||
for (i = 0; i < this.text.length; ++i) {
|
||||
letter = this.text.charAt(i);
|
||||
textWidth += this.quickfitHelper.getMeassure(letter);
|
||||
}
|
||||
|
||||
this.targetFontSize = parseInt(this.options.width / textWidth);
|
||||
return this.fontSize = Math.max(this.options.min, Math.min(this.options.max, this.targetFontSize));
|
||||
};
|
||||
|
||||
Quickfit.prototype.truncate = function () {
|
||||
var index, lastLetter, letter, textToAdd, textWidth;
|
||||
|
||||
if (this.fontSize > this.targetFontSize) {
|
||||
textToAdd = '';
|
||||
textWidth = 3 * this.quickfitHelper.getMeassure('.') * this.fontSize;
|
||||
|
||||
index = 0;
|
||||
while (textWidth < this.options.width && index < this.text.length) {
|
||||
letter = this.text[index++];
|
||||
if (lastLetter) textToAdd += lastLetter;
|
||||
textWidth += this.fontSize * this.quickfitHelper.getMeassure(letter);
|
||||
lastLetter = letter;
|
||||
}
|
||||
|
||||
if (textToAdd.length + 1 === this.text.length) {
|
||||
textToAdd = this.text;
|
||||
} else {
|
||||
textToAdd += '...';
|
||||
}
|
||||
this.textWasTruncated = true;
|
||||
|
||||
return this.$element.attr('data-quickfit', this.text).html(textToAdd);
|
||||
|
||||
} else {
|
||||
if (this.previouslyTruncated) {
|
||||
return this.$element.html(this.text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return Quickfit;
|
||||
|
||||
})();
|
||||
|
||||
return $.fn.quickfit = function (options) {
|
||||
var measurements = [];
|
||||
|
||||
// Separate measurements from repaints
|
||||
// First calculate all measurements...
|
||||
var $elements = this.each(function () {
|
||||
var measurement = new Quickfit(this, options).fit();
|
||||
measurements.push(measurement);
|
||||
return measurement.$element;
|
||||
});
|
||||
|
||||
// ... then apply the measurements.
|
||||
for (var i = 0; i < measurements.length; i++) {
|
||||
var measurement = measurements[i];
|
||||
|
||||
measurement.$element.css({ fontSize: measurement.size + 'px' });
|
||||
}
|
||||
|
||||
return $elements;
|
||||
};
|
||||
|
||||
})(jQuery, window);
|
||||
12
rpg-docs/client/lib/printing.js
Normal file
12
rpg-docs/client/lib/printing.js
Normal file
@@ -0,0 +1,12 @@
|
||||
Session.setDefault("isPrinting", false);
|
||||
if (window.matchMedia) {
|
||||
var mediaQueryList = window.matchMedia("print");
|
||||
mediaQueryList.addListener(function(mql) {
|
||||
if (mql.matches) {
|
||||
Session.set("isPrinting", true);
|
||||
Tracker.flush();
|
||||
} else {
|
||||
Session.set("isPrinting", false);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,4 +1,7 @@
|
||||
<template name="characterSheet">
|
||||
{{#if printing}}
|
||||
{{> printedCharacterSheet}}
|
||||
{{/if}}
|
||||
<div class="fit layout vertical character-sheet">
|
||||
<app-header fixed effects="waterfall">
|
||||
<app-toolbar class="medium-tall {{colorClass}}">
|
||||
|
||||
@@ -165,6 +165,9 @@ var getTab = function(charId){
|
||||
};
|
||||
|
||||
Template.characterSheet.helpers({
|
||||
printing: function(){
|
||||
return Session.get("isPrinting");
|
||||
},
|
||||
selectedTab: function(){
|
||||
return getTab(this._id);
|
||||
},
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<template name="printedAbility">
|
||||
<div class="printedAbility layout vertical center">
|
||||
<div class="paper-font-subhead title flex layout horizontal center">
|
||||
{{title}}
|
||||
</div>
|
||||
<div class="paper-font-display1 stat">
|
||||
{{characterCalculate "attributeValue" ../_id ability}}
|
||||
</div>
|
||||
<div class="paper-font-subhead modifier">
|
||||
{{abilityMod}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
Template.printedAbility.helpers({
|
||||
abilityMod: function() {
|
||||
return signedString(
|
||||
Characters.calculate.abilityMod(
|
||||
Template.parentData()._id, this.ability
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
.printed {
|
||||
background: #fff;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.printed > .page {
|
||||
width: 100%;
|
||||
padding: 1cm;
|
||||
page-break-inside: avoid;
|
||||
page-break-after: always;
|
||||
}
|
||||
|
||||
.printed .shrink-to-fit {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@media screen {
|
||||
.printed {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.character-sheet {
|
||||
display: none;
|
||||
}
|
||||
app-drawer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<template name="printedCharacterSheet">
|
||||
<div class="printed">
|
||||
<div class="page">
|
||||
<div class="layout vertical">
|
||||
<div class="layout horizontal">
|
||||
<div class="characterName paper-font-title">
|
||||
{{name}}
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
{{#each classes}}
|
||||
<span style="margin-right: 16px;">
|
||||
{{name}} {{level}}
|
||||
</span>
|
||||
{{/each}}
|
||||
</div>
|
||||
<div>
|
||||
{{alignment}} {{gender}} {{race}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layout horizontal">
|
||||
<div class="col1 padded flex layout vertical">
|
||||
<div class="layout horizontal">
|
||||
<div class="abilities padded layout vertical justified">
|
||||
{{> printedAbility ability="strength" title="Strength" color="red"}}
|
||||
{{> printedAbility ability="dexterity" title="Dexterity" color="indigo"}}
|
||||
{{> printedAbility ability="constitution" title="Constitution" color="green"}}
|
||||
{{> printedAbility ability="intelligence" title="Intelligence" color="deep-orange"}}
|
||||
{{> printedAbility ability="wisdom" title="Wisdom" color="purple"}}
|
||||
{{> printedAbility ability="charisma" title="Charisma" color="pink"}}
|
||||
</div>
|
||||
<div class="padded flex layout vertical">
|
||||
<div class="proficiencyBonus">
|
||||
{{> printedLongStat stat="proficiencyBonus" name="Proficiency Bonus" prefix="+"}}
|
||||
</div>
|
||||
<div class="saves">
|
||||
<div class="paper-font-subhead">
|
||||
Saving Throws
|
||||
</div>
|
||||
<div>
|
||||
{{> printedSkillRow name="Strength" skill="strengthSave"}}
|
||||
{{> printedSkillRow name="Dexterity" skill="dexteritySave"}}
|
||||
{{> printedSkillRow name="Constitution" skill="constitutionSave"}}
|
||||
{{> printedSkillRow name="Intelligence" skill="intelligenceSave"}}
|
||||
{{> printedSkillRow name="Wisdom" skill="wisdomSave"}}
|
||||
{{> printedSkillRow name="Charisma" skill="charismaSave"}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="skills">
|
||||
<div class="paper-font-subhead">
|
||||
Skills
|
||||
</div>
|
||||
<div>
|
||||
{{> printedSkillRow name="Acrobatics" skill="acrobatics"}}
|
||||
{{> printedSkillRow name="Animal Handling" skill="animalHandling"}}
|
||||
{{> printedSkillRow name="Arcana" skill="arcana"}}
|
||||
{{> printedSkillRow name="Athletics" skill="athletics"}}
|
||||
{{> printedSkillRow name="Deception" skill="deception"}}
|
||||
{{> printedSkillRow name="History" skill="history"}}
|
||||
{{> printedSkillRow name="Insight" skill="insight"}}
|
||||
{{> printedSkillRow name="Intimidation" skill="intimidation"}}
|
||||
{{> printedSkillRow name="Investigation" skill="investigation"}}
|
||||
{{> printedSkillRow name="Medicine" skill="medicine"}}
|
||||
{{> printedSkillRow name="Nature" skill="nature"}}
|
||||
{{> printedSkillRow name="Perception" skill="perception" showPassive="true"}}
|
||||
{{> printedSkillRow name="Performance" skill="performance"}}
|
||||
{{> printedSkillRow name="Persuasion" skill="persuasion"}}
|
||||
{{> printedSkillRow name="Religion" skill="religion"}}
|
||||
{{> printedSkillRow name="Sleight of Hand" skill="sleightOfHand"}}
|
||||
{{> printedSkillRow name="Stealth" skill="stealth"}}
|
||||
{{> printedSkillRow name="Survival" skill="survival"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="proficiencies">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="col2 padded flex">
|
||||
<div class="layout vertical">
|
||||
<div class="layout horizontal justified">
|
||||
<div class="armor">
|
||||
{{> printedSquareStat stat="armor" name="Armor Class" color="teal"}}
|
||||
</div>
|
||||
<div class="inititive">
|
||||
{{> printedSquareStat stat="initiative" name="Initiative" color="teal"}}
|
||||
</div>
|
||||
<div class="speed">
|
||||
{{> printedSquareStat stat="speed" name="Speed" color="teal"}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="hitpoints padded layout vertical">
|
||||
<div>Hit Points</div>
|
||||
<div style="width: 3cm; height: 2cm;">
|
||||
<!-- Space for writing-->
|
||||
</div>
|
||||
<div class="layout horizontal end-justified">
|
||||
/{{characterCalculate "attributeValue" _id "hitPoints"}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="tempHitpoints"></div>
|
||||
<div class="layout horizontal">
|
||||
<div class="hitDice"></div>
|
||||
<div class="deathSaves"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="attacks"></div>
|
||||
<div class="persona"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,17 @@
|
||||
Template.printedCharacterSheet.onRendered(function(){
|
||||
// Quickfit is only called once on rendering, text will not resize reactively
|
||||
this.$(".shrink-to-fit").quickfit({
|
||||
min: 7,
|
||||
max: 36,
|
||||
truncate: true,
|
||||
});
|
||||
});
|
||||
|
||||
Template.printedCharacterSheet.helpers({
|
||||
character(){
|
||||
return Characters.findOne(this._id);
|
||||
},
|
||||
classes: function(){
|
||||
return Classes.find({charId: this._id}, {sort: {createdAt: 1}});
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
<template name="printedLongStat">
|
||||
<div class="printedLongStat layout horizontal">
|
||||
<div class="numbers paper-font-display1">
|
||||
{{#if isSkill}}
|
||||
{{prefix}}{{skillMod}}
|
||||
{{else}}
|
||||
{{prefix}}{{characterCalculate "attributeValue" ../_id stat}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="paper-font-subhead title flex layout horizontal center">
|
||||
{{name}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
Template.printedLongStat.helpers({
|
||||
skillMod: function() {
|
||||
return signedString(
|
||||
Characters.calculate.skillMod(
|
||||
Template.parentData()._id, this.stat
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
<template name="printedSkillRow">
|
||||
<div class="printedSkillRow layout horizontal center">
|
||||
<iron-icon icon="{{profIcon}}"></iron-icon>
|
||||
{{#if failSkill}}
|
||||
<div class="fail skill-mod">fail</div>
|
||||
{{else}}
|
||||
<div class="{{advantage}} skill-mod">
|
||||
{{skillMod}}
|
||||
</div>
|
||||
{{/if}}
|
||||
<div flex>
|
||||
{{name}}
|
||||
{{#if conditionalCount}}
|
||||
*
|
||||
{{/if}}
|
||||
{{#if showPassive}}
|
||||
({{characterCalculate "passiveSkill" ../_id skill}})
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,41 @@
|
||||
Template.printedSkillRow.helpers({
|
||||
skillMod: function() {
|
||||
return signedString(
|
||||
Characters.calculate.skillMod(
|
||||
Template.parentData()._id, this.skill
|
||||
)
|
||||
);
|
||||
},
|
||||
profIcon: function(){
|
||||
var charId = Template.parentData()._id;
|
||||
var prof = Characters.calculate.proficiency(charId, this.skill);
|
||||
if (prof > 0 && prof < 1) return "image:brightness-2";
|
||||
if (prof === 1) return "image:brightness-1";
|
||||
if (prof > 1) return "av:album";
|
||||
return "radio-button-unchecked";
|
||||
},
|
||||
failSkill: function(){
|
||||
var charId = Template.parentData()._id;
|
||||
return Effects.find({
|
||||
charId: charId,
|
||||
stat: this.skill,
|
||||
enabled: true,
|
||||
operation: "fail",
|
||||
}).count();
|
||||
},
|
||||
advantage: function(){
|
||||
var charId = Template.parentData()._id;
|
||||
var advantage = Characters.calculate.advantage(charId, this.skill);
|
||||
if (advantage > 0) return "advantage";
|
||||
if (advantage < 0) return "disadvantage";
|
||||
},
|
||||
conditionalCount: function(){
|
||||
var charId = Template.parentData()._id;
|
||||
return Effects.find({
|
||||
charId: charId,
|
||||
stat: this.skill,
|
||||
enabled: true,
|
||||
operation: "conditional",
|
||||
}).count();
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
<template name="printedSquareStat">
|
||||
<div class="printedSquareStat padded layout vertical center">
|
||||
<div class="paper-font-subhead">
|
||||
{{name}}
|
||||
</div>
|
||||
<div class="numbers paper-font-display1">
|
||||
{{#if isSkill}}
|
||||
{{prefix}}{{skillMod}}
|
||||
{{else}}
|
||||
{{prefix}}{{characterCalculate "attributeValue" ../_id stat}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,9 @@
|
||||
Template.printedSquareStat.helpers({
|
||||
skillMod: function() {
|
||||
return signedString(
|
||||
Characters.calculate.skillMod(
|
||||
Template.parentData()._id, this.stat
|
||||
)
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -23,4 +23,17 @@
|
||||
<meta name="msapplication-TileColor" content="#b91d1d">
|
||||
<meta name="msapplication-TileImage" content="/mstile-144x144.png?v=lk6WXp6Pmj">
|
||||
<meta name="theme-color" content="#d12929">
|
||||
|
||||
<style type="text/css" media="print">
|
||||
@page {
|
||||
margin: 0mm;
|
||||
}
|
||||
html {
|
||||
margin: 0px;
|
||||
}
|
||||
* {
|
||||
-webkit-transition: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
Reference in New Issue
Block a user