mirror of
https://github.com/Blockzilla101/citation.git
synced 2025-04-18 18:34:41 -04:00
cleanup / refactor
This commit is contained in:
parent
5d1081ba4f
commit
47a6adaafb
6 changed files with 174 additions and 256 deletions
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -5,8 +5,5 @@ node_modules/*
|
||||||
.idea/*
|
.idea/*
|
||||||
|
|
||||||
# app
|
# app
|
||||||
frames/*
|
citation*.png
|
||||||
Citation*.png
|
citation*.gif
|
||||||
Citation*.gif
|
|
||||||
|
|
||||||
src/main.js
|
|
||||||
|
|
Binary file not shown.
16
index.js
Normal file
16
index.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
const { Citation } = require('./src/citation')
|
||||||
|
const { registerFont } = require('canvas')
|
||||||
|
const path = require('path')
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const dataDir = path.join(__dirname, 'data')
|
||||||
|
const fontFile = path.join(dataDir, 'BMmini.ttf')
|
||||||
|
const logo = path.join(dataDir, 'logo.png')
|
||||||
|
|
||||||
|
if (!fs.existsSync(dataDir)) throw new Error(`${dataDir} is no where to be found`)
|
||||||
|
if (!fs.existsSync(fontFile)) throw new Error(`Font ${fontFile} is no where to be found`)
|
||||||
|
if (!fs.existsSync(logo)) throw new Error(`Logo ${logo} is no where to be found`)
|
||||||
|
|
||||||
|
registerFont(fontFile, { family: 'BMmini' });
|
||||||
|
|
||||||
|
module.exports = { Citation }
|
|
@ -6,5 +6,5 @@
|
||||||
"gif-encoder-2": "^1.0.5"
|
"gif-encoder-2": "^1.0.5"
|
||||||
},
|
},
|
||||||
"author": "Blockzilla101",
|
"author": "Blockzilla101",
|
||||||
"main": "src/citation.js"
|
"main": "index.js"
|
||||||
}
|
}
|
||||||
|
|
387
src/citation.js
387
src/citation.js
|
@ -1,31 +1,16 @@
|
||||||
const { createCanvas, Canvas, registerFont, loadImage, Image } = require('canvas');
|
const { createCanvas, Canvas, loadImage, Image } = require('canvas');
|
||||||
const { text, textWrapped, line, dottedLine, barcode, rect, textFitsHeight, textFitsWidth } = require('./util');
|
const { text, textWrapped, line, dottedLine, barcode, rect, textFitsHeight, textFitsWidth } = require('./util');
|
||||||
const Encoder = require('gif-encoder-2');
|
const Encoder = require('gif-encoder-2');
|
||||||
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
function loadAssets() {
|
|
||||||
const font = 'BMmini.ttf', altFont = 'megan_serif.ttf';
|
|
||||||
const logoFile = 'logo.png'
|
|
||||||
const dataDir = __dirname + '/../data';
|
|
||||||
|
|
||||||
if (!fs.existsSync(`${dataDir}`)) throw Error(`No "${dataDir}" folder found in the current working directory`);
|
|
||||||
if (!fs.existsSync(`${dataDir}/${font}`)) throw Error(`Font '${font}' is no where to be found`);
|
|
||||||
if (!fs.existsSync(`${dataDir}/${altFont}`)) throw Error(`Font '${altFont}' is no where to be found`);
|
|
||||||
if (!fs.existsSync(`${dataDir}/${logoFile}`)) throw Error(`Logo '${logoFile}' is no where to be found`);
|
|
||||||
|
|
||||||
registerFont(`${dataDir}/${font}`, { family: 'BMmini' });
|
|
||||||
registerFont(`${dataDir}/${altFont}`, { family: 'Megan' });
|
|
||||||
}
|
|
||||||
loadAssets();
|
|
||||||
|
|
||||||
/** @class Citation */
|
/** @class Citation */
|
||||||
module.exports.Citation = class Citation {
|
module.exports.Citation = class Citation {
|
||||||
/** @type {string} Background color of the citation */
|
/** @type {string|*} Background color of the citation */
|
||||||
moaBg = '#F3D7E6';
|
moaBg = '#F3D7E6';
|
||||||
/** @type {string} Foreground color of the citation */
|
/** @type {string|*} Foreground color of the citation */
|
||||||
moaFg = '#BFA8A8';
|
moaFg = '#BFA8A8';
|
||||||
/** @type {string} The font and separator color of the citation */
|
/** @type {string|*} The font and separator color of the citation */
|
||||||
moaFt = '#5A5559';
|
moaFt = '#5A5559';
|
||||||
|
|
||||||
/** @type {number} Width of the citation*/
|
/** @type {number} Width of the citation*/
|
||||||
|
@ -33,10 +18,10 @@ module.exports.Citation = class Citation {
|
||||||
/** @type {number} Height of the citation */
|
/** @type {number} Height of the citation */
|
||||||
#height = 160;
|
#height = 160;
|
||||||
|
|
||||||
/** @type {boolean} Should it resize automatically when text is overflowing*/
|
/** @type {boolean} Should it resize automatically when text is overflowing */
|
||||||
#autoResizeToText = false;
|
autoResizeToText = false;
|
||||||
|
|
||||||
/** @type {Image} The logo put at the bottom-mid the citation*/
|
/** @type {Image} The logo put at the mid-bottom the citation */
|
||||||
#logo = null
|
#logo = null
|
||||||
|
|
||||||
/** @type {RenderingContext} */
|
/** @type {RenderingContext} */
|
||||||
|
@ -44,9 +29,6 @@ module.exports.Citation = class Citation {
|
||||||
/** @type {Canvas} */
|
/** @type {Canvas} */
|
||||||
#canvas = null;
|
#canvas = null;
|
||||||
|
|
||||||
/** @type {string} Where to put the output*/
|
|
||||||
#outputFile = './Citation.png';
|
|
||||||
|
|
||||||
/** @type {string} Title of the citation*/
|
/** @type {string} Title of the citation*/
|
||||||
title = "M.O.A. CITATION";
|
title = "M.O.A. CITATION";
|
||||||
/** @type {string} Content/Reason for the citation*/
|
/** @type {string} Content/Reason for the citation*/
|
||||||
|
@ -54,208 +36,156 @@ module.exports.Citation = class Citation {
|
||||||
/** @type {string} Penalties of the citation*/
|
/** @type {string} Penalties of the citation*/
|
||||||
penalty = 'LAST WARNING - NO PENALTY';
|
penalty = 'LAST WARNING - NO PENALTY';
|
||||||
|
|
||||||
/** @type {number[]} The barcode at the top left*/
|
/** @type {number[]} The barcode at the top left */
|
||||||
#barcode = [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1];
|
#barcode = [1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1];
|
||||||
|
|
||||||
/** @type {number} Dot size for the dashed line at the top and bottom */
|
/** @type {number} Dot size for the dashed line at the top and bottom */
|
||||||
#topBottomDotSize = 2;
|
topBottomDotSize = 2;
|
||||||
/** @type {number} Dot size for the dots at the sides of the citation */
|
/** @type {number} Dot size for the dots at the sides of the citation */
|
||||||
#sideDotSize = 6;
|
sideDotSize = 6;
|
||||||
/** @type {number} Spacing between the dots at the sides of the citation */
|
/** @type {number} Spacing between the dots at the sides of the citation */
|
||||||
#sideDotSpacing = 4;
|
sideDotSpacing = 4;
|
||||||
/** @type {number} Separator dot size */
|
/** @type {number} Separator dot size */
|
||||||
#separatorDotSize = 2;
|
separatorDotSize = 2;
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
#barcodeWidth = 2;
|
barcodeWidth = 2;
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
#barcodeHeight = 12;
|
barcodeHeight = 12;
|
||||||
/** @type {number} */
|
/** @type {number} */
|
||||||
#fontSize = 16;
|
fontSize = 16;
|
||||||
/** @type {string} */
|
|
||||||
#font = `${this.#fontSize}px BMmini`;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
log = (...args) => { }
|
||||||
#sideDotsSpacingFromLeft = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#sideDotsSpacingFromTop = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#sideDotsSpacingFromRight = null;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
|
||||||
#separatorSpacingFromLeft = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#separatorSpacingFromRight = null;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
|
||||||
#topSeparatorSpacingFromTop = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#bottomSeparatorSpacingFromBottom = null;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
|
||||||
#barcodeSpacingFromRight = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#barcodeSpacingFromTop = null;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
|
||||||
#textSpacingFromLeft = null;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
|
||||||
#titleSpacingFromTop = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#titleMaxWidth = null;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
|
||||||
#reasonSpacingFromTop = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#reasonMaxWidth = null;
|
|
||||||
/** @type {number|null} */
|
|
||||||
#reasonMaxHeight = null;
|
|
||||||
|
|
||||||
/** @type {number|null} */
|
|
||||||
#penaltySpacingFromBottom = null;
|
|
||||||
|
|
||||||
log = msg => {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} outputFile
|
|
||||||
* @param {number} [width=366]
|
* @param {number} [width=366]
|
||||||
* @param {number} [height=160]
|
* @param {number} [height=160]
|
||||||
*/
|
*/
|
||||||
constructor(outputFile, width = 366, height = 160) {
|
constructor(width = 366, height = 160) {
|
||||||
this.#outputFile = outputFile;
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
async #createCanvas() {
|
||||||
this.#canvas = createCanvas(this.#width, this.#height);
|
this.#canvas = createCanvas(this.#width, this.#height);
|
||||||
this.#ctx = this.#canvas.getContext('2d');
|
this.#ctx = this.#canvas.getContext('2d');
|
||||||
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
|
|
||||||
this.#ctx.imageSmoothingEnabled = false;
|
this.#ctx.imageSmoothingEnabled = false;
|
||||||
this.#ctx.antialias = 'none';
|
this.#ctx.antialias = 'none';
|
||||||
|
|
||||||
|
if (!this.#logo) this.#logo = await loadImage(`${__dirname + '/../data'}/logo.png`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async generate() {
|
async render(out, gif = false, frameRate = 10, yPos = null) {
|
||||||
await this.#draw();
|
await this.#draw()
|
||||||
fs.writeFileSync(this.#outputFile, this.#canvas.toBuffer())
|
let data = gif ? await this.#animated(frameRate, yPos) : this.#canvas.toBuffer()
|
||||||
|
if (out) {
|
||||||
|
fs.writeFileSync(out, data)
|
||||||
|
}
|
||||||
|
return data
|
||||||
}
|
}
|
||||||
|
|
||||||
#draw = async () => {
|
async #draw() {
|
||||||
this.calculate();
|
await this.#createCanvas()
|
||||||
|
|
||||||
if (this.#autoResizeToText) {
|
if (this.autoResizeToText) {
|
||||||
while (!textFitsWidth(this.title, this.#font, this.#ctx, this.#titleMaxWidth)) {
|
while (!textFitsWidth(this.title, this.font, this.#ctx, this.#titleMaxWidth)) {
|
||||||
this.#canvas.width += this.#ctx.measureText(this.title).width * 0.1;
|
this.#canvas.width += this.#ctx.measureText(this.title).width * 0.1;
|
||||||
this.#width = this.#canvas.width;
|
this.#width = this.#canvas.width;
|
||||||
this.calculate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!textFitsWidth(this.penalty, this.#font, this.#ctx, this.#titleMaxWidth)) {
|
while (!textFitsWidth(this.penalty, this.font, this.#ctx, this.#titleMaxWidth)) {
|
||||||
this.#canvas.width += this.#ctx.measureText(this.penalty).width * 0.1;
|
this.#canvas.width += this.#ctx.measureText(this.penalty).width * 0.1;
|
||||||
this.#width = this.#canvas.width;
|
this.#width = this.#canvas.width;
|
||||||
this.calculate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!textFitsHeight(this.reason, this.#font, this.#ctx, this.#reasonMaxHeight)) {
|
while (!textFitsHeight(this.reason, this.font, this.#ctx, this.#reasonMaxHeight)) {
|
||||||
let metrics = this.#ctx.measureText(this.reason);
|
let metrics = this.#ctx.measureText(this.reason);
|
||||||
this.#canvas.height += (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent) * 0.03;
|
this.#canvas.height += (metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent) * 0.03;
|
||||||
this.#height = this.#canvas.height;
|
this.#height = this.#canvas.height;
|
||||||
this.calculate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// while (!textFitsWidth(this.reason, this.#font, this.#ctx, this.#reasonMaxWidth)) {
|
// while (!textFitsWidth(this.reason, this.#font, this.#ctx, this.#reasonMaxWidth)) {
|
||||||
// this.#canvas.width += this.#ctx.measureText(this.reason).width * 0.1;
|
// this.#canvas.width += this.#ctx.measureText(this.reason).width * 0.1;
|
||||||
// this.#width = this.#canvas.width;
|
// this.#width = this.#canvas.width;
|
||||||
// this.calculate();
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bg
|
// Bg
|
||||||
rect(0, 0, this.width, this.height, this.moaBg, this.#ctx);
|
rect(0, 0, this.width, this.height, this.moaBg, this.#ctx);
|
||||||
|
|
||||||
// Logo
|
// Logo
|
||||||
this.#logo = await loadImage(`${__dirname + '/../data'}/logo.png`);
|
|
||||||
this.#ctx.drawImage(this.#logo, (this.#width / 2) - (this.#logo.height / 2) - 1, this.height - (this.#bottomSeparatorSpacingFromBottom + (this.#logo.height / 2)) + 4);
|
this.#ctx.drawImage(this.#logo, (this.#width / 2) - (this.#logo.height / 2) - 1, this.height - (this.#bottomSeparatorSpacingFromBottom + (this.#logo.height / 2)) + 4);
|
||||||
|
|
||||||
// Top and bottom dots
|
// Top and bottom dots
|
||||||
dottedLine(0, this.#topBottomDotSize / 2, this.#width, this.#topBottomDotSize / 2, this.moaFg, [this.#topBottomDotSize, this.#topBottomDotSize], this.#ctx, this.#topBottomDotSize);
|
dottedLine(0, this.topBottomDotSize / 2, this.#width, this.topBottomDotSize / 2, this.moaFg, [this.topBottomDotSize, this.topBottomDotSize], this.#ctx, this.topBottomDotSize);
|
||||||
dottedLine(this.#topBottomDotSize, this.#height - this.#topBottomDotSize / 2, this.#width, this.#height - this.#topBottomDotSize / 2, this.moaFg, [this.#topBottomDotSize, this.#topBottomDotSize], this.#ctx, this.#topBottomDotSize);
|
dottedLine(this.topBottomDotSize, this.#height - this.topBottomDotSize / 2, this.#width, this.#height - this.topBottomDotSize / 2, this.moaFg, [this.topBottomDotSize, this.topBottomDotSize], this.#ctx, this.topBottomDotSize);
|
||||||
|
|
||||||
// Dots on the sides
|
// Dots on the sides
|
||||||
dottedLine(this.#sideDotsSpacingFromLeft + (this.#sideDotSize / 2), this.#sideDotsSpacingFromTop, this.#sideDotsSpacingFromLeft + (this.#sideDotSize / 2), this.#height - this.#topBottomDotSize, this.moaFg, [this.#sideDotSize, this.#sideDotSize * 2], this.#ctx, this.#sideDotSize);
|
dottedLine(this.#sideDotsSpacingFromLeft + (this.sideDotSize / 2), this.#sideDotsSpacingFromTop, this.#sideDotsSpacingFromLeft + (this.sideDotSize / 2), this.#height - this.topBottomDotSize, this.moaFg, [this.sideDotSize, this.sideDotSize * 2], this.#ctx, this.sideDotSize);
|
||||||
dottedLine(this.#width - this.#sideDotsSpacingFromRight - (this.#sideDotSize / 2), this.#sideDotsSpacingFromTop, this.#width - this.#sideDotsSpacingFromRight - (this.#sideDotSize / 2), this.#height - this.#topBottomDotSize, this.moaFg, [this.#sideDotSize, this.#sideDotSize * 2], this.#ctx, this.#sideDotSize);
|
dottedLine(this.#width - this.#sideDotsSpacingFromRight - (this.sideDotSize / 2), this.#sideDotsSpacingFromTop, this.#width - this.#sideDotsSpacingFromRight - (this.sideDotSize / 2), this.#height - this.topBottomDotSize, this.moaFg, [this.sideDotSize, this.sideDotSize * 2], this.#ctx, this.sideDotSize);
|
||||||
|
|
||||||
// Separators
|
// Separators
|
||||||
dottedLine(this.#separatorSpacingFromLeft, this.#topSeparatorSpacingFromTop + (this.#separatorDotSize / 2), this.#width - this.#separatorSpacingFromRight, this.#topSeparatorSpacingFromTop + (this.#separatorDotSize / 2), this.moaFt, [this.#separatorDotSize, this.#separatorDotSize], this.#ctx, this.#separatorDotSize);
|
dottedLine(this.#separatorSpacingFromLeft, this.#topSeparatorSpacingFromTop + (this.separatorDotSize / 2), this.#width - this.#separatorSpacingFromRight, this.#topSeparatorSpacingFromTop + (this.separatorDotSize / 2), this.moaFt, [this.separatorDotSize, this.separatorDotSize], this.#ctx, this.separatorDotSize);
|
||||||
dottedLine(this.#separatorSpacingFromLeft, this.height - (this.#bottomSeparatorSpacingFromBottom + (this.#separatorDotSize / 2)), this.#width - this.#separatorSpacingFromRight, this.height - (this.#bottomSeparatorSpacingFromBottom + (this.#separatorDotSize / 2)), this.moaFt, [this.#separatorDotSize, this.#separatorDotSize], this.#ctx, this.#separatorDotSize);
|
dottedLine(this.#separatorSpacingFromLeft, this.height - (this.#bottomSeparatorSpacingFromBottom + (this.separatorDotSize / 2)), this.#width - this.#separatorSpacingFromRight, this.height - (this.#bottomSeparatorSpacingFromBottom + (this.separatorDotSize / 2)), this.moaFt, [this.separatorDotSize, this.separatorDotSize], this.#ctx, this.separatorDotSize);
|
||||||
|
|
||||||
// Line at the side
|
// Line at the side
|
||||||
line(this.#width - (this.#topBottomDotSize / 2), 0, this.#width - (this.#topBottomDotSize / 2), this.#height, this.moaFg, this.#ctx, this.#topBottomDotSize);
|
line(this.#width - (this.topBottomDotSize / 2), 0, this.#width - (this.topBottomDotSize / 2), this.#height, this.moaFg, this.#ctx, this.topBottomDotSize);
|
||||||
|
|
||||||
// Barcode
|
// Barcode
|
||||||
barcode(this.#width - this.#barcodeSpacingFromRight - (this.#barcode.length * this.#barcodeWidth), this.#barcodeSpacingFromTop, this.#barcode, this.#barcodeHeight, this.#barcodeWidth, this.moaFt, this.moaBg, this.#ctx);
|
barcode(this.#width - this.#barcodeSpacingFromRight - (this.#barcode.length * this.barcodeWidth), this.#barcodeSpacingFromTop, this.#barcode, this.barcodeHeight, this.barcodeWidth, this.moaFt, this.moaBg, this.#ctx);
|
||||||
rect(this.#width - this.#barcodeSpacingFromRight - (this.#barcode.length * this.#barcodeWidth) - (this.#barcodeWidth * 3), this.#barcodeSpacingFromTop, this.#barcodeWidth * 2, this.#barcodeHeight / 2, this.moaFt, this.#ctx);
|
rect(this.#width - this.#barcodeSpacingFromRight - (this.#barcode.length * this.barcodeWidth) - (this.barcodeWidth * 3), this.#barcodeSpacingFromTop, this.barcodeWidth * 2, this.barcodeHeight / 2, this.moaFt, this.#ctx);
|
||||||
|
|
||||||
// Title
|
// Title
|
||||||
text(this.title, this.#textSpacingFromLeft, this.#titleSpacingFromTop, this.#font, this.moaFt, this.#ctx, 'left', this.#titleMaxWidth);
|
text(this.title, this.#textSpacingFromLeft, this.#titleSpacingFromTop, this.font, this.moaFt, this.#ctx, 'left', this.#titleMaxWidth);
|
||||||
|
|
||||||
// Reason
|
// Reason
|
||||||
textWrapped(this.reason, this.#textSpacingFromLeft, this.#reasonSpacingFromTop, this.#font, this.moaFt, this.#ctx, this.#reasonMaxWidth, this.#reasonMaxHeight)
|
textWrapped(this.reason, this.#textSpacingFromLeft, this.#reasonSpacingFromTop, this.font, this.moaFt, this.#ctx, this.#reasonMaxWidth, this.#reasonMaxHeight)
|
||||||
|
|
||||||
// Penalty
|
// Penalty
|
||||||
text(this.penalty, (this.#width / 2) - 3, this.#height - this.#penaltySpacingFromBottom, this.#font, this.moaFt, this.#ctx, 'center', this.#reasonMaxWidth);
|
text(this.penalty, (this.#width / 2) - 3, this.#height - this.#penaltySpacingFromBottom, this.font, this.moaFt, this.#ctx, 'center', this.#reasonMaxWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
async animated() {
|
async #animated(frameRate = 10, yPos = null) {
|
||||||
await this.#draw();
|
|
||||||
|
|
||||||
const encoder = new Encoder(this.#width, this.#height);
|
const encoder = new Encoder(this.#width, this.#height);
|
||||||
const canvas = createCanvas(this.#width, this.#height);
|
const canvas = createCanvas(this.#width, this.#height);
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
let ctx = canvas.getContext('2d');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} amount
|
|
||||||
* @param {Canvas} canvas
|
|
||||||
*/
|
|
||||||
function moveBy(amount, canvas) {
|
|
||||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
||||||
ctx.drawImage(canvas, 0, amount); encoder.addFrame(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
let increments = 2;
|
let increments = 2;
|
||||||
let pause = 14;
|
let pause = 14;
|
||||||
let bigPause = 100;
|
let bigPause = 100;
|
||||||
|
|
||||||
let startingPoint = this.#sideDotsSpacingFromTop;
|
// stores y values of citation position
|
||||||
let stopOne = this.#topSeparatorSpacingFromTop + increments;
|
const animation = yPos ?? [];
|
||||||
let stopTwo = this.height - this.#bottomSeparatorSpacingFromBottom + increments;
|
|
||||||
|
|
||||||
const animation = [];
|
if (!yPos) {
|
||||||
|
let startingPoint = this.#sideDotsSpacingFromTop;
|
||||||
|
let stopOne = this.#topSeparatorSpacingFromTop + increments;
|
||||||
|
let stopTwo = this.height - this.#bottomSeparatorSpacingFromBottom + increments;
|
||||||
|
|
||||||
animation.push(startingPoint)
|
animation.push(startingPoint)
|
||||||
for (let i = startingPoint + increments; i < stopOne; i += increments) {
|
for (let i = startingPoint + increments; i < stopOne; i += increments) {
|
||||||
animation.push(i);
|
animation.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < pause; i++) animation.push(stopOne);
|
||||||
|
for (let i = stopOne + increments; i < stopTwo; i += increments) {
|
||||||
|
animation.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < pause; i++) animation.push(stopTwo);
|
||||||
|
for (let i = stopTwo + increments; i < this.#height; i += increments) {
|
||||||
|
animation.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < bigPause; i++) animation.push(this.#height);
|
||||||
|
|
||||||
|
for (let i = this.#height; i >= 0; i -= increments) {
|
||||||
|
animation.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < bigPause / 2; i++) animation.push(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < pause; i++) animation.push(stopOne);
|
|
||||||
for (let i = stopOne + increments; i < stopTwo; i += increments) {
|
|
||||||
animation.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < pause; i++) animation.push(stopTwo);
|
|
||||||
for (let i = stopTwo + increments; i < this.#height; i += increments) {
|
|
||||||
animation.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < bigPause; i++) animation.push(this.#height);
|
|
||||||
|
|
||||||
for (let i = this.#height; i >= 0; i -= increments) {
|
|
||||||
animation.push(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < bigPause / 2; i++) animation.push(0);
|
|
||||||
|
|
||||||
encoder.setDelay(10);
|
encoder.setDelay(10);
|
||||||
encoder.setQuality(1);
|
encoder.setQuality(1);
|
||||||
encoder.useOptimizer = true;
|
encoder.useOptimizer = true;
|
||||||
|
@ -264,100 +194,45 @@ module.exports.Citation = class Citation {
|
||||||
|
|
||||||
encoder.start();
|
encoder.start();
|
||||||
for (let i = 0; i < animation.length; i++) {
|
for (let i = 0; i < animation.length; i++) {
|
||||||
moveBy(this.#height - animation[i], this.#canvas);
|
ctx.clearRect(0, 0, this.#width, this.#height);
|
||||||
|
ctx.drawImage(this.#canvas, 0, this.#height - animation[i]);
|
||||||
|
encoder.addFrame(ctx);
|
||||||
this.log(`\rEncoding frame ${i+1} of ${animation.length}`)
|
this.log(`\rEncoding frame ${i+1} of ${animation.length}`)
|
||||||
}
|
}
|
||||||
encoder.finish();
|
encoder.finish();
|
||||||
this.log('\nEncoding Finished\n')
|
this.log('\nEncoding Finished\n')
|
||||||
|
return encoder.out.getData()
|
||||||
fs.writeFileSync(this.#outputFile, encoder.out.getData())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recalculates the values variables that make up the citation
|
|
||||||
*/
|
|
||||||
calculate() {
|
|
||||||
this.#sideDotsSpacingFromLeft = this.#sideDotSpacing;
|
|
||||||
this.#sideDotsSpacingFromTop = this.#sideDotSpacing + this.#topBottomDotSize;
|
|
||||||
this.#sideDotsSpacingFromRight = this.#sideDotSpacing + (this.#topBottomDotSize) + 2;
|
|
||||||
|
|
||||||
this.#separatorSpacingFromLeft = this.#sideDotsSpacingFromLeft + this.#sideDotSize + 6;
|
|
||||||
this.#separatorSpacingFromRight = this.#sideDotsSpacingFromRight + this.#sideDotSize + 6;
|
|
||||||
|
|
||||||
this.#topSeparatorSpacingFromTop = this.#topBottomDotSize + (this.#fontSize * 2);
|
|
||||||
this.#bottomSeparatorSpacingFromBottom = this.#topBottomDotSize + (this.#fontSize * 2) + 10;
|
|
||||||
|
|
||||||
this.#barcodeSpacingFromRight = this.#sideDotsSpacingFromRight + this.#sideDotSize + 8;
|
|
||||||
this.#barcodeSpacingFromTop = this.#topBottomDotSize + 4;
|
|
||||||
|
|
||||||
this.#textSpacingFromLeft = this.#sideDotSpacing + this.#sideDotSize + 12;
|
|
||||||
|
|
||||||
this.#titleSpacingFromTop = this.#topBottomDotSize + this.#fontSize + 2;
|
|
||||||
this.#titleMaxWidth = this.#width - (this.#barcodeSpacingFromRight + (this.#barcode.length * this.#barcodeWidth) + (this.#barcodeWidth * 3) + this.#textSpacingFromLeft + this.#fontSize);
|
|
||||||
|
|
||||||
this.#reasonSpacingFromTop = this.#topSeparatorSpacingFromTop + this.#separatorDotSize + this.#fontSize + 4;
|
|
||||||
this.#reasonMaxWidth = this.#width - (this.#textSpacingFromLeft + this.#sideDotsSpacingFromRight + this.#sideDotSize);
|
|
||||||
this.#reasonMaxHeight = this.#height - (this.#topSeparatorSpacingFromTop + this.#bottomSeparatorSpacingFromBottom + this.#fontSize);
|
|
||||||
|
|
||||||
this.#penaltySpacingFromBottom = this.#bottomSeparatorSpacingFromBottom - this.#fontSize - 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set height(value) {
|
set height(value) {
|
||||||
if (value % 2 !== 0) value += 1;
|
if (typeof value !== 'number') throw new Error(`${value} is not a number`)
|
||||||
|
if (value % 2 !== 0) {
|
||||||
this.#canvas.height = value;
|
this.log(`width ${value} is not even | added one too it`)
|
||||||
|
value += 1
|
||||||
|
}
|
||||||
this.#height = value;
|
this.#height = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
set width(value) {
|
set width(value) {
|
||||||
if (value % 2 !== 0) value += 1;
|
if (typeof value !== 'number') throw new Error(`${value} is not a number`)
|
||||||
|
if (value % 2 !== 0) {
|
||||||
this.#canvas.width = value;
|
this.log(`width ${value} is not even | added one too it`)
|
||||||
|
value += 1
|
||||||
|
}
|
||||||
this.#width = value;
|
this.#width = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
set topBottomDotSize(value) {
|
|
||||||
if (value % 2 !== 0) value += 1;
|
|
||||||
this.#topBottomDotSize = value;
|
|
||||||
}
|
|
||||||
set sideDotSize(value) {
|
|
||||||
if (value % 2 !== 0) value += 1;
|
|
||||||
this.#sideDotSize = value;
|
|
||||||
}
|
|
||||||
set sideDotSpacing(value) {
|
|
||||||
if (value % 2 !== 0) value += 1;
|
|
||||||
this.#sideDotSpacing = value;
|
|
||||||
}
|
|
||||||
set separatorDotSize(value) {
|
|
||||||
if (value % 2 !== 0) value += 1;
|
|
||||||
this.#separatorDotSize = value;
|
|
||||||
}
|
|
||||||
set barcodeWidth(value) {
|
|
||||||
if (value % 2 !== 0) value += 1;
|
|
||||||
this.#barcodeWidth = value;
|
|
||||||
}
|
|
||||||
set barcodeHeight(value) {
|
|
||||||
if (value % 2 !== 0) value += 1;
|
|
||||||
this.#barcodeHeight = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {number[]} value */
|
/** @param {number[]} value */
|
||||||
set barcode(value) {
|
set barcode(value) {
|
||||||
for (let i = 0; i < value.length; i++) {
|
for (let i = 0; i < value.length; i++) {
|
||||||
if (value[i] !== 0 && value[i] !== 1) throw "Barcode can only contain ones and zeros"
|
if (value[i] !== 0 && value[i] !== 1) throw new Error("Barcode can only contain ones and zeros")
|
||||||
}
|
}
|
||||||
this.#barcode = value;
|
this.#barcode = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {boolean} value Note: doesn't scales well **/
|
/** @return The f*/
|
||||||
set autoResizeToText(value) {
|
get font() {
|
||||||
this.#autoResizeToText = value;
|
return `${this.fontSize}px BMmini`;
|
||||||
}
|
|
||||||
|
|
||||||
/** @param {number} value WARNING: Does not scale well**/
|
|
||||||
set fontSize(value) {
|
|
||||||
this.#fontSize = value;
|
|
||||||
this.#font = `${value}px BMmini`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return {number} */
|
/** @return {number} */
|
||||||
|
@ -365,30 +240,60 @@ module.exports.Citation = class Citation {
|
||||||
/** @return {number} */
|
/** @return {number} */
|
||||||
get width() { return this.#width; }
|
get width() { return this.#width; }
|
||||||
|
|
||||||
/** @return {number} */
|
//#region Private Getters
|
||||||
get topBottomDotSize() { return this.#topBottomDotSize; }
|
get #sideDotsSpacingFromLeft() {
|
||||||
|
return this.sideDotSpacing
|
||||||
|
}
|
||||||
|
get #sideDotsSpacingFromTop() {
|
||||||
|
return this.sideDotSpacing + this.topBottomDotSize
|
||||||
|
}
|
||||||
|
get #sideDotsSpacingFromRight() {
|
||||||
|
return this.sideDotSpacing + (this.topBottomDotSize) + 2
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {number} */
|
get #separatorSpacingFromLeft() {
|
||||||
get sideDotSize() { return this.#sideDotSize; }
|
return this.#sideDotsSpacingFromLeft + this.sideDotSize + 6
|
||||||
/** @return {number} */
|
}
|
||||||
get sideDotSpacing() { return this.#sideDotSpacing; }
|
get #separatorSpacingFromRight() {
|
||||||
|
return this.#sideDotsSpacingFromRight + this.sideDotSize + 6
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {number} */
|
get #topSeparatorSpacingFromTop() {
|
||||||
get separatorDotSize() { return this.#separatorDotSize; }
|
return this.topBottomDotSize + (this.fontSize * 2)
|
||||||
|
}
|
||||||
|
get #bottomSeparatorSpacingFromBottom() {
|
||||||
|
return this.topBottomDotSize + (this.fontSize * 2) + 10
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {number} */
|
get #barcodeSpacingFromRight() {
|
||||||
get barcodeWidth() { return this.#barcodeWidth; }
|
return this.#sideDotsSpacingFromRight + this.sideDotSize + 8
|
||||||
/** @return {number} */
|
}
|
||||||
get barcodeHeight() { return this.#barcodeHeight; }
|
get #barcodeSpacingFromTop() {
|
||||||
/** @return {number[]} */
|
return this.topBottomDotSize + 4
|
||||||
get barcode() { return this.#barcode; }
|
}
|
||||||
|
get #textSpacingFromLeft() {
|
||||||
|
return this.sideDotSpacing + this.sideDotSize + 12
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {boolean} */
|
get #titleSpacingFromTop() {
|
||||||
get autoResizeToText() { return this.#autoResizeToText; }
|
return this.topBottomDotSize + this.fontSize + 2
|
||||||
|
}
|
||||||
|
get #titleMaxWidth() {
|
||||||
|
return this.#width - (this.#barcodeSpacingFromRight + (this.#barcode.length * this.barcodeWidth) + (this.barcodeWidth * 3) + this.#textSpacingFromLeft + this.fontSize)
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {number} **/
|
get #reasonSpacingFromTop() {
|
||||||
get fontSize() { return this.#fontSize; }
|
return this.#topSeparatorSpacingFromTop + this.separatorDotSize + this.fontSize + 4
|
||||||
|
}
|
||||||
|
get #reasonMaxWidth() {
|
||||||
|
return this.#width - (this.#textSpacingFromLeft + this.#sideDotsSpacingFromRight + this.sideDotSize)
|
||||||
|
}
|
||||||
|
get #reasonMaxHeight() {
|
||||||
|
return this.#height - (this.#topSeparatorSpacingFromTop + this.#bottomSeparatorSpacingFromBottom + this.fontSize)
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {string} **/
|
get #penaltySpacingFromBottom() {
|
||||||
get outputFile() { return this.#outputFile }
|
return this.#bottomSeparatorSpacingFromBottom - this.fontSize - 10
|
||||||
|
}
|
||||||
|
//#endregion Private Getters
|
||||||
}
|
}
|
||||||
|
|
18
src/util.js
18
src/util.js
|
@ -140,7 +140,7 @@ function barcode(x, y, pattern, barHeight, barWidth, styleFilled, styleEmpty, c
|
||||||
* @param {number} y
|
* @param {number} y
|
||||||
* @param {number} w
|
* @param {number} w
|
||||||
* @param {number} h
|
* @param {number} h
|
||||||
* @param {Style} style
|
* @param {string|Style} style
|
||||||
* @param {RenderingContext} ctx
|
* @param {RenderingContext} ctx
|
||||||
*/
|
*/
|
||||||
function rect(x, y, w, h, style, ctx) {
|
function rect(x, y, w, h, style, ctx) {
|
||||||
|
@ -174,12 +174,12 @@ function textFitsHeight(text, font, ctx, maxHeight) {
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
line: line,
|
line,
|
||||||
dottedLine: dottedLine,
|
dottedLine,
|
||||||
rect: rect,
|
rect,
|
||||||
barcode: barcode,
|
barcode,
|
||||||
textWrapped: textWrapped,
|
textWrapped,
|
||||||
text: text,
|
text,
|
||||||
textFitsHeight: textFitsHeight,
|
textFitsHeight,
|
||||||
textFitsWidth: textFitsWidth
|
textFitsWidth
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue