cherry-box
Advanced tools
| import { textBox } from "./textBox"; | ||
| import { wrapText } from "./wrapText"; | ||
| import { TextObject } from "./textAttr"; | ||
| export { textBox, wrapText, TextObject }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.wrapText = exports.textBox = void 0; | ||
| var textBox_1 = require("./textBox"); | ||
| Object.defineProperty(exports, "textBox", { enumerable: true, get: function () { return textBox_1.textBox; } }); | ||
| var wrapText_1 = require("./wrapText"); | ||
| Object.defineProperty(exports, "wrapText", { enumerable: true, get: function () { return wrapText_1.wrapText; } }); |
| interface TextObject { | ||
| text: string; | ||
| font: string; | ||
| color: string; | ||
| modifier?: string; | ||
| shadow?: { | ||
| offset: Array<number>; | ||
| color: string; | ||
| blur: number; | ||
| }; | ||
| } | ||
| /** | ||
| * Get total width of multiple fonts at once | ||
| * @param ctx Canvas context | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Maximum font size of the text | ||
| * @param spaceWidth Width of the space between words | ||
| * @returns Width of the text | ||
| */ | ||
| declare function getTotalWidth(ctx: CanvasRenderingContext2D, text: Array<TextObject>, fontSize: number, spaceWidth?: number): number; | ||
| /** | ||
| * Paint text using all the options provided. | ||
| * @param ctx Canvas context | ||
| * @param text Text to be displayed | ||
| * @param x X coordinate of the text box | ||
| * @param y Y coordinate of the text box | ||
| * @param fontSize Font size of the font | ||
| * @param spaceWidth Width of the space between words | ||
| */ | ||
| declare function paintText(ctx: CanvasRenderingContext2D, text: Array<TextObject>, x: number, y: number, fontSize: number, spaceWidth?: number): void; | ||
| /** | ||
| * Get lines of text that fit in the box | ||
| * @param ctx Canvas context | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Font size of the text | ||
| * @param width Width of the text | ||
| * @returns | ||
| */ | ||
| declare function getLines(ctx: CanvasRenderingContext2D, text: Array<TextObject>, width: number, fontSize: number): TextObject[][]; | ||
| export { getTotalWidth, TextObject, getLines }; | ||
| export default paintText; |
| import { TextObject } from './textAttr'; | ||
| /** | ||
| * Text that adjusts to the size of the canvas | ||
| * @param ctx Canvas context | ||
| * @param x X coordinate of the text box | ||
| * @param y Y coordinate of the text box | ||
| * @param width Width of the text box | ||
| * @param height Height of the text box | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Maximum font size of the text | ||
| * @param align Alignment of the text | ||
| */ | ||
| declare function textBox(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, text: Array<TextObject>, fontSize: number, align?: number[]): { | ||
| x: number; | ||
| y: number; | ||
| width: number; | ||
| height: number; | ||
| }; | ||
| export { textBox }; |
| import { TextObject, getLines } from './textAttr'; | ||
| /** | ||
| * Text that adjusts to the size of the canvas, but it wraps | ||
| * @param ctx Canvas context | ||
| * @param x X coordinate of the text box | ||
| * @param y Y coordinate of the text box | ||
| * @param width Width of the text box | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Maximum font size of the text | ||
| * @param align Alignment of the text | ||
| */ | ||
| declare function wrapText(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, text: Array<TextObject>, fontSize: number, align?: number): void; | ||
| export { wrapText, getLines }; |
+80
-17
@@ -0,24 +1,87 @@ | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.getLines = exports.getTotalWidth = void 0; | ||
| /** | ||
| * Get total width of multiple fonts at once | ||
| * @param {ctx} ctx Canvas context | ||
| * @param {object} text Text to be displayed in the text box | ||
| * @param {int} fontSize Maximum font size of the text | ||
| * @param {int} spaceWidth Width of the space between words | ||
| * @returns {int} Width of the text | ||
| * @param ctx Canvas context | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Maximum font size of the text | ||
| * @param spaceWidth Width of the space between words | ||
| * @returns Width of the text | ||
| */ | ||
| function getTotalWidth(ctx, text, fontSize, spaceWidth=0) { | ||
| let width = 0; | ||
| for (let i = 0; i < text.length; i++) { | ||
| if (text[i].modifier == null) text[i].modifier = ''; | ||
| ctx.font = `${text[i].modifier} ${fontSize}px ${text[i].font}`; | ||
| function getTotalWidth(ctx, text, fontSize, spaceWidth) { | ||
| if (spaceWidth === void 0) { spaceWidth = 0; } | ||
| var width = 0; | ||
| for (var i = 0; i < text.length; i++) { | ||
| if (text[i].modifier == null) | ||
| text[i].modifier = ''; | ||
| ctx.font = "".concat(text[i].modifier, " ").concat(fontSize, "px ").concat(text[i].font); | ||
| width += ctx.measureText(text[i].text).width + spaceWidth; | ||
| } | ||
| return width - spaceWidth; | ||
| } | ||
| export { getTotalWidth }; | ||
| exports.getTotalWidth = getTotalWidth; | ||
| /** | ||
| * Paint text using all the options provided. | ||
| * @param ctx Canvas context | ||
| * @param text Text to be displayed | ||
| * @param x X coordinate of the text box | ||
| * @param y Y coordinate of the text box | ||
| * @param fontSize Font size of the font | ||
| * @param spaceWidth Width of the space between words | ||
| */ | ||
| function paintText(ctx, text, x, y, fontSize, spaceWidth) { | ||
| if (spaceWidth === void 0) { spaceWidth = 0; } | ||
| ctx.save(); | ||
| for (var i = 0; i < text.length; i++) { | ||
| var textPart = text[i]; | ||
| textPart.modifier = '' || textPart.modifier; | ||
| ctx.fillStyle = textPart.color; | ||
| ctx.font = "".concat(textPart.modifier, " ").concat(fontSize, "px ").concat(textPart.font); | ||
| if (textPart.shadow !== undefined) { | ||
| ctx.shadowColor = textPart.shadow.color; | ||
| ctx.shadowOffsetX = textPart.shadow.offset[0] * fontSize / 100; | ||
| ctx.shadowOffsetY = textPart.shadow.offset[1] * fontSize / 100; | ||
| ctx.shadowBlur = textPart.shadow.blur; | ||
| } | ||
| else | ||
| ctx.shadowColor = "transparent"; | ||
| ctx.fillText(textPart.text, x, y); | ||
| x += ctx.measureText(textPart.text).width + spaceWidth; | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| /** | ||
| * Get lines of text that fit in the box | ||
| * @param ctx Canvas context | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Font size of the text | ||
| * @param width Width of the text | ||
| * @returns | ||
| */ | ||
| function getLines(ctx, text, width, fontSize) { | ||
| var spaceWidth = fontSize / 4; | ||
| // Generate the lines | ||
| var lines = []; | ||
| var line = []; | ||
| for (var i = 0; i < text.length; i++) { | ||
| var splitText = text[i].text.split(' '); | ||
| for (var j = 0; j < splitText.length; j++) { | ||
| var textRich = text[i]; | ||
| textRich.text = splitText[j]; | ||
| // Remove unnecessary info in the object | ||
| textRich = JSON.parse(JSON.stringify(textRich)); | ||
| var lineWidth = getTotalWidth(ctx, line, fontSize, spaceWidth); | ||
| var textWidth = getTotalWidth(ctx, [textRich], fontSize, spaceWidth); | ||
| if (lineWidth + textWidth + spaceWidth > width) { | ||
| lines.push(line); | ||
| line = []; | ||
| } | ||
| line.push(textRich); | ||
| } | ||
| } | ||
| lines.push(line); | ||
| return lines; | ||
| } | ||
| exports.getLines = getLines; | ||
| exports.default = paintText; |
+21
-26
@@ -1,25 +0,25 @@ | ||
| import paintText from './paintText.js'; | ||
| import { getTotalWidth } from './textAttr.js'; | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.textBox = void 0; | ||
| var textAttr_1 = require("./textAttr"); | ||
| /** | ||
| * Text that adjusts to the size of the canvas | ||
| * @param {ctx} ctx Canvas context | ||
| * @param {x} x X coordinate of the text box | ||
| * @param {y} y Y coordinate of the text box | ||
| * @param {int} width Width of the text box | ||
| * @param {int} height Height of the text box | ||
| * @param {object} text Text to be displayed in the text box | ||
| * @param {int} fontSize Maximum font size of the text | ||
| * @param {array} align Alignment of the text | ||
| * @param ctx Canvas context | ||
| * @param x X coordinate of the text box | ||
| * @param y Y coordinate of the text box | ||
| * @param width Width of the text box | ||
| * @param height Height of the text box | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Maximum font size of the text | ||
| * @param align Alignment of the text | ||
| */ | ||
| function textBox(ctx, x, y, width, height, text, fontSize, align=[1, 1]) { | ||
| function textBox(ctx, x, y, width, height, text, fontSize, align) { | ||
| if (align === void 0) { align = [1, 1]; } | ||
| ctx.save(); | ||
| // Resize the textbox if the text is too long | ||
| let textWidth = getTotalWidth(ctx, text, fontSize); | ||
| if (textWidth > width) fontSize *= width / textWidth;; | ||
| textWidth = getTotalWidth(ctx, text, fontSize); | ||
| var textWidth = (0, textAttr_1.getTotalWidth)(ctx, text, fontSize); | ||
| if (textWidth > width) | ||
| fontSize *= width / textWidth; | ||
| ; | ||
| textWidth = (0, textAttr_1.getTotalWidth)(ctx, text, fontSize); | ||
| // Calculate the position of the text | ||
@@ -37,3 +37,2 @@ switch (align[0]) { | ||
| } | ||
| switch (align[1]) { | ||
@@ -47,6 +46,4 @@ case 1: | ||
| } | ||
| paintText(ctx, text, x, y, fontSize); | ||
| (0, textAttr_1.default)(ctx, text, x, y, fontSize); | ||
| ctx.restore(); | ||
| return { | ||
@@ -58,5 +55,3 @@ x: x, | ||
| }; | ||
| } | ||
| export { textBox }; | ||
| exports.textBox = textBox; |
+25
-75
@@ -1,69 +0,23 @@ | ||
| import paintText from './paintText.js'; | ||
| import { getTotalWidth } from './textAttr.js'; | ||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.getLines = exports.wrapText = void 0; | ||
| var textAttr_1 = require("./textAttr"); | ||
| Object.defineProperty(exports, "getLines", { enumerable: true, get: function () { return textAttr_1.getLines; } }); | ||
| /** | ||
| * Get lines of text that fit in the box | ||
| * @param {ctx} ctx Canvas context | ||
| * @param {object} text Text to be displayed in the text box | ||
| * @param {number} fontSize Font size of the text | ||
| * @param {number} width Width of the text | ||
| * @returns | ||
| */ | ||
| function getLines(ctx, text, width, fontSize) { | ||
| let spaceWidth = fontSize / 4; | ||
| // Generate the lines | ||
| let lines = []; | ||
| let line = []; | ||
| for (let i = 0; i < text.length; i++) { | ||
| let splitText = text[i].text.split(' '); | ||
| for (let j = 0; j < splitText.length; j++) { | ||
| let textRich = text[i]; | ||
| textRich.text = splitText[j]; | ||
| // Remove unnecessary info in the object | ||
| textRich = JSON.parse(JSON.stringify(textRich)); | ||
| let lineWidth = getTotalWidth(ctx, line, fontSize, spaceWidth); | ||
| let textWidth = getTotalWidth(ctx, [textRich], fontSize, spaceWidth); | ||
| if (lineWidth + textWidth + spaceWidth > width) { | ||
| lines.push(line); | ||
| line = []; | ||
| } | ||
| line.push(textRich); | ||
| } | ||
| } | ||
| lines.push(line); | ||
| return lines; | ||
| } | ||
| /** | ||
| * Text that adjusts to the size of the canvas, but it wraps | ||
| * @param {ctx} ctx Canvas context | ||
| * @param {int} x X coordinate of the text box | ||
| * @param {int} y Y coordinate of the text box | ||
| * @param {int} width Width of the text box | ||
| * @param {object} text Text to be displayed in the text box | ||
| * @param {int} fontSize Maximum font size of the text | ||
| * @param {string} align Alignment of the text | ||
| * @param ctx Canvas context | ||
| * @param x X coordinate of the text box | ||
| * @param y Y coordinate of the text box | ||
| * @param width Width of the text box | ||
| * @param text Text to be displayed in the text box | ||
| * @param fontSize Maximum font size of the text | ||
| * @param align Alignment of the text | ||
| */ | ||
| function wrapText(ctx, x, y, width, text, fontSize, align=1) { | ||
| function wrapText(ctx, x, y, width, text, fontSize, align) { | ||
| if (align === void 0) { align = 1; } | ||
| ctx.save(); | ||
| let lines = getLines(ctx, text, width, fontSize); | ||
| let spaceWidth = fontSize / 4; | ||
| for (let i = 0; i < lines.length; i++) { | ||
| let textWidth = getTotalWidth(ctx, lines[i], fontSize, spaceWidth); | ||
| var lines = (0, textAttr_1.getLines)(ctx, text, width, fontSize); | ||
| var spaceWidth = fontSize / 4; | ||
| for (var i = 0; i < lines.length; i++) { | ||
| var textWidth = (0, textAttr_1.getTotalWidth)(ctx, lines[i], fontSize, spaceWidth); | ||
| switch (align) { | ||
@@ -77,18 +31,14 @@ case 1: | ||
| case 3: | ||
| let rawTextWidth = getTotalWidth(ctx, lines[i], fontSize); | ||
| var rawTextWidth = (0, textAttr_1.getTotalWidth)(ctx, lines[i], fontSize); | ||
| spaceWidth = (width - rawTextWidth) / (lines[i].length - 1); | ||
| if (spaceWidth < 4) spaceWidth = 4; | ||
| if (spaceWidth > 30) spaceWidth = 10; | ||
| if (spaceWidth < 4) | ||
| spaceWidth = 4; | ||
| if (spaceWidth > 30) | ||
| spaceWidth = 10; | ||
| break; | ||
| } | ||
| paintText(ctx, lines[i], x, y+fontSize*(i+1), fontSize, spaceWidth); | ||
| (0, textAttr_1.default)(ctx, lines[i], x, y + fontSize * (i + 1), fontSize, spaceWidth); | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| export { wrapText, getLines }; | ||
| exports.wrapText = wrapText; |
+10
-6
| { | ||
| "name": "cherry-box", | ||
| "version": "1.3.0", | ||
| "version": "1.4.0", | ||
| "description": "A node-canvas package filled with utilities, manage text boxes easily and more", | ||
| "main": "index.js", | ||
| "main": "lib/index.js", | ||
| "types": "lib/index.d.ts", | ||
| "scripts": { | ||
| "test": "jest" | ||
| "test": "jest --config jestconfig.json", | ||
| "build": "tsc" | ||
| }, | ||
@@ -15,3 +17,2 @@ "keywords": [ | ||
| "license": "ISC", | ||
| "type": "module", | ||
| "repository": { | ||
@@ -22,6 +23,9 @@ "type": "git", | ||
| "devDependencies": { | ||
| "@babel/plugin-transform-modules-commonjs": "^7.17.9", | ||
| "canvas": "^2.9.1", | ||
| "jest": "^28.1.0" | ||
| "@types/jest": "^28.1.4", | ||
| "eslint": "^8.19.0", | ||
| "jest": "^28.1.2", | ||
| "ts-jest": "^28.0.5", | ||
| "typescript": "^4.7.4" | ||
| } | ||
| } |
+96
-51
@@ -8,22 +8,72 @@ # About | ||
| ```js | ||
| const cb = require("cherry-box") | ||
| const Canvas = require("canvas") | ||
| const fs = require("fs"); | ||
| let canvas = Canvas.createCanvas(1000, 200); | ||
| let ctx = canvas.getContext('2d'); | ||
| let text = [ | ||
| { | ||
| text: "I like cookies!", | ||
| color: "#ffffff", | ||
| font: "monospace", | ||
| modifier: "bold", | ||
| } | ||
| ] | ||
| cb.textBox(ctx, 0, 0, 1000, 200, text, 200, [1, 1]); | ||
| // Save canvas to file | ||
| let out = fs.createWriteStream("./out.png"); | ||
| let stream = canvas.createPNGStream(); | ||
| stream.pipe(out); | ||
| ``` | ||
| Using modules: | ||
| ```js | ||
| import { textBox } from "cherry-box"; | ||
| import Canvas from "canvas"; | ||
| import { createCanvas } from "canvas"; | ||
| import fs from "fs"; | ||
| let canvas = new Canvas.createCanvas(800, 600); | ||
| let ctx = canvas.getContext("2d"); | ||
| let canvas = Canvas.createCanvas(1000, 200); | ||
| let ctx = canvas.getContext('2d'); | ||
| let textSchema = [ | ||
| let text = [ | ||
| { | ||
| text: "I like cookies!", | ||
| color: "#ff8800", | ||
| font: "Arial", | ||
| color: "#ffffff", | ||
| font: "monospace", | ||
| modifier: "bold", | ||
| shadow: { | ||
| offset: [10, 10], blur: 5, color: "red" | ||
| }, | ||
| } | ||
| ] | ||
| textBox(800, 600, textSchema, 200, [1, 1]); | ||
| textBox(ctx, 0, 0, 1000, 200, text, 200, [1, 1]); | ||
| // Save canvas to file | ||
| let out = fs.createWriteStream("./out.png"); | ||
| let stream = canvas.createPNGStream(); | ||
| stream.pipe(out); | ||
| ``` | ||
| # Using Typescript | ||
| When using textObject you also need to import `TextObject` | ||
| ```ts | ||
| import { textObject } from "cherry-box"; | ||
| ... | ||
| let text: TextObject = [ | ||
| { | ||
| text: "I like cookies!", | ||
| color: "#ffffff", | ||
| font: "monospace", | ||
| modifier: "bold", | ||
| } | ||
| ] | ||
| ... | ||
| ``` | ||
| # Documentation | ||
@@ -35,13 +85,25 @@ | ||
| * [textSchema](#textSchema) - An easy way to specify text color, font, shadow and more into a JSON object. | ||
| ## textSchema | ||
| Text schema is made of multiple objects. These objects accepts the following values: | ||
| ## TextObject | ||
| TextObject is made of multiple objects. These objects accepts the following values: | ||
| name | description | example | type | required | ||
| --- | --- | --- | --- | --- | ||
| text | Text to be displayed | Hello world | string | true | ||
| color | Color of the text | #FFFFFF | string | true | ||
| shadow | Shadow of the text | | shadow | false | ||
| font | Font of the text | Arial | string | true | ||
| modifier | Modifier of the text | bold | string | true | ||
| text | Text to be displayed | `Hello world` | string | true | ||
| font | Font of the text | `Arial` | string | true | ||
| color | Color of the text | `#FFFFFF` | string | true | ||
| modifier | Modifier of the text | `bold` | string | false | ||
| shadow | Shadow of the text | | object| false | ||
| ### Shadow schema | ||
| Shadow is a JSON object with the following values: | ||
| > `x` and `y` offsets are relative to the text size. For example use `x: 10, y: 10` | ||
| name | description | example | type | required | ||
| --- | --- | --- | --- | --- | ||
| color | Color of the shadow | `#FFFFFF` | string | true | ||
| blur | Blur of the shadow | `5` | number | true | ||
| offset | X and Y offset of the shadow | `[10, 5]` | array | true | ||
| Example text schema: | ||
@@ -62,13 +124,2 @@ ```js | ||
| ### Shadow schema | ||
| Shadow is a JSON object with the following values: | ||
| > `x` and `y` offsets are relative to the text size. For example use `x: 10, y: 10` for minecraft font. | ||
| name | description | example | type | required | ||
| --- | --- | --- | --- | --- | ||
| color | Color of the shadow | #FFFFFF | string | true | ||
| blur | Blur of the shadow | 5 | number | true | ||
| offset | X and Y offset of the shadow | [10, 5] | array | true | ||
| ## textBox | ||
@@ -81,17 +132,11 @@ | ||
| --- | --- | --- | --- | --- | ||
| x | X position of the textbox | 0 | number | true | ||
| y | Y position of the textbox | 0 | number | true | ||
| width | Width of the textbox | 100 | number | true | ||
| height | Height of the textbox | 100 | number | true | ||
| text | Text to be displayed | | textSchema | true | ||
| maxFont | Max font size of the text | 100 | number | true | ||
| fontName | Font of the text | Arial | string | true | ||
| align | Align of the text | | array | true | ||
| ctx | Canvas context | | CanvasRenderingContext2D | true | ||
| x | X coordinate of the text box | `0` | number | true | ||
| y | Y coordinate of the text box | `0` | number | true | ||
| width | Width of the text box | `100` | number | true | ||
| height | Height of the text box | `100` | number | true | ||
| text | Text to be displayed in the text box | | TextObject | true | ||
| fontSize | Maximum font size of the text | `100` | number | true | ||
| align | Align of the text | `[1,1]` | array | true | ||
| ### textBox Errors | ||
| Code | Description | ||
| --- | --- | ||
| 601 | Text is too big to be displayed | ||
| ### Align values | ||
@@ -117,9 +162,9 @@ | ||
| --- | --- | --- | --- | --- | ||
| ctx | Canvas context | | object | true | ||
| x | X coordinate of the text box | 0 | number | true | ||
| y | Y coordinate of the text box | 0 | number | true | ||
| width | Width of the text box | 100 | number | true | ||
| text | Text to be displayed | | textSchema | true | ||
| fontSize | Font size of the text | 100 | number | true | ||
| align | Align of the text | justify | string | true | ||
| ctx | Canvas context | | CanvasRenderingContext2D | true | ||
| x | X coordinate of the text box | `0` | number | true | ||
| y | Y coordinate of the text box | `0` | number | true | ||
| width | Width of the text box | `100` | number | true | ||
| text | Text to be displayed in the text box | | TextObject | true | ||
| fontSize | Maximum font size of the text | `100` | number | true | ||
| align | Align of the text | `3` | number | true | ||
@@ -135,3 +180,3 @@ ### Align values | ||
| ```js | ||
| wrapText(ctx, 0, 0, canvas.width, wrapTextBox, 20, 3); | ||
| ``` | ||
| wrapText(ctx, 0, 0, canvas.width, text, 20, 3); | ||
| ``` |
-7
| { | ||
| "env": { | ||
| "test": { | ||
| "plugins": ["@babel/plugin-transform-modules-commonjs"] | ||
| } | ||
| } | ||
| } |
| # Auto detect text files and perform LF normalization | ||
| * text=auto |
| # For most projects, this workflow file will not need changing; you simply need | ||
| # to commit it to your repository. | ||
| # | ||
| # You may wish to alter this file to override the set of languages analyzed, | ||
| # or to provide custom queries or build logic. | ||
| # | ||
| # ******** NOTE ******** | ||
| # We have attempted to detect the languages in your repository. Please check | ||
| # the `language` matrix defined below to confirm you have the correct set of | ||
| # supported CodeQL languages. | ||
| # | ||
| name: "CodeQL" | ||
| on: | ||
| push: | ||
| branches: [ main ] | ||
| pull_request: | ||
| # The branches below must be a subset of the branches above | ||
| branches: [ main ] | ||
| schedule: | ||
| - cron: '36 5 * * 0' | ||
| jobs: | ||
| analyze: | ||
| name: Analyze | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| actions: read | ||
| contents: read | ||
| security-events: write | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| language: [ 'javascript' ] | ||
| # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] | ||
| # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v3 | ||
| # Initializes the CodeQL tools for scanning. | ||
| - name: Initialize CodeQL | ||
| uses: github/codeql-action/init@v2 | ||
| with: | ||
| languages: ${{ matrix.language }} | ||
| # If you wish to specify custom queries, you can do so here or in a config file. | ||
| # By default, queries listed here will override any specified in a config file. | ||
| # Prefix the list here with "+" to use these queries and those in the config file. | ||
| # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs | ||
| # queries: security-extended,security-and-quality | ||
| # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). | ||
| # If this step fails, then you should remove it and run the build manually (see below) | ||
| - name: Autobuild | ||
| uses: github/codeql-action/autobuild@v2 | ||
| # âšī¸ Command-line programs to run using the OS shell. | ||
| # đ See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun | ||
| # If the Autobuild fails above, remove it and uncomment the following three lines. | ||
| # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. | ||
| # - run: | | ||
| # echo "Run, Build Application using script" | ||
| # ./location_of_script_within_repo/buildscript.sh | ||
| - name: Perform CodeQL Analysis | ||
| uses: github/codeql-action/analyze@v2 |
| # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node | ||
| # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions | ||
| name: Node.js CI | ||
| on: | ||
| push: | ||
| branches: [ main ] | ||
| pull_request: | ||
| branches: [ main ] | ||
| jobs: | ||
| build: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| node-version: [17.x] | ||
| # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - name: Use Node.js ${{ matrix.node-version }} | ||
| uses: actions/setup-node@v3 | ||
| with: | ||
| node-version: ${{ matrix.node-version }} | ||
| cache: 'npm' | ||
| - run: npm ci | ||
| - run: npm run build --if-present | ||
| - run: npm run test |
| import { textBox, wrapText } from "cherry-box"; | ||
| import Canvas from "canvas"; | ||
| const canvas = new Canvas.createCanvas(800, 600); | ||
| const ctx = canvas.getContext("2d"); | ||
| let upperText = [ | ||
| { | ||
| text: "POV: Linux user", | ||
| color: "white", | ||
| modifier: "bold", | ||
| font: "ubuntu", | ||
| shadow: { | ||
| color: "red", | ||
| offset: [0, 0], | ||
| blur: 10 | ||
| } | ||
| } | ||
| ]; | ||
| textBox(ctx, 0, 0, canvas.width, canvas.height-20, upperText, 80, [2, 1]); | ||
| let wrapTextBox = [ | ||
| { | ||
| text: "I'd like to interject for a moment, what you reffered to as Linux was in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called \"Linux\", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project. The Free Software Foundation obviously intends Linux to be free software like any other free program, and whoever works for the Free Software Foundation will do whatever it takes to ensure that the GNU system remains free. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called \"Linux\" distributions are really distributions of GNU/Linux.", | ||
| color: "yellow", | ||
| font: 'Arial', | ||
| modifier: "bold", | ||
| shadow: { | ||
| color: "red", | ||
| offset: [10, 10], | ||
| blur: 10 | ||
| } | ||
| } | ||
| ] | ||
| wrapText(ctx, 25, 25, canvas.width-50, wrapTextBox, 20, 3); |
| import { textBox } from "cherry-box"; | ||
| import Canvas from "canvas"; | ||
| const canvas = new Canvas.createCanvas(800, 600); | ||
| const ctx = canvas.getContext("2d"); | ||
| let meme = [ | ||
| 'upper text', | ||
| 'lower text' | ||
| ] | ||
| let upperText = [ | ||
| { | ||
| text: meme[0], | ||
| color: "white", | ||
| font: "Impact", | ||
| shadow: { | ||
| color: "black", | ||
| offset: [0, 0], | ||
| blur: 10 | ||
| } | ||
| } | ||
| ]; | ||
| let lowerText = [ | ||
| { | ||
| text: meme[1], | ||
| color: "white", | ||
| font: "Impact", | ||
| shadow: { | ||
| color: "black", | ||
| offset: [0, 0], | ||
| blur: 10 | ||
| } | ||
| } | ||
| ]; | ||
| //Draw text | ||
| textBox(ctx, 0, 0, canvas.width, 80, upperText, 80, [1, 1]); | ||
| textBox(ctx, 0, canvas.height-80, canvas.width, 80, lowerText, 80, [1, 1]); |
-3
| import { textBox } from './lib/textBox.js'; | ||
| import { wrapText, getLines } from './lib/wrapText.js'; | ||
| export { textBox, wrapText, getLines }; |
| /** | ||
| * Paint text using all the options provided. | ||
| * @param {ctx} ctx Canvas context | ||
| * @param {string} text Text to be displayed | ||
| * @param {int} x X coordinate of the text box | ||
| * @param {int} y Y coordinate of the text box | ||
| * @param {string} font Font name of the text | ||
| * @param {number} spaceWidth Width of the space between words | ||
| */ | ||
| function paintText(ctx, text, x, y, fontSize, spaceWidth=0) { | ||
| ctx.save(); | ||
| for (let i = 0; i < text.length; i++) { | ||
| ctx.fillStyle = text[i].color; | ||
| if (text[i].modifier == undefined) text[i].modifier = ''; | ||
| ctx.font = `${text[i].modifier} ${fontSize}px ${text[i].font}`; | ||
| if (text[i].shadow) { | ||
| ctx.shadowColor = text[i].shadow.color; | ||
| ctx.shadowOffsetX = text[i].shadow.offset[0] * fontSize / 100; | ||
| ctx.shadowOffsetY = text[i].shadow.offset[1] * fontSize / 100; | ||
| ctx.shadowBlur = text[i].shadow.blur; | ||
| } else ctx.shadowColor = "transparent"; | ||
| ctx.fillText(text[i].text, x, y); | ||
| x += ctx.measureText(text[i].text).width + spaceWidth; | ||
| } | ||
| ctx.restore(); | ||
| } | ||
| export default paintText; |
-15
| ISC License | ||
| Copyright (c) 2022, CheryX | ||
| Permission to use, copy, modify, and/or distribute this software for any | ||
| purpose with or without fee is hereby granted, provided that the above | ||
| copyright notice and this permission notice appear in all copies. | ||
| THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| import { getTotalHeight, getTotalWidth } from "../lib/textAttr"; | ||
| import Canvas from "canvas"; | ||
| const canvas = Canvas.createCanvas(100, 100); | ||
| const ctx = canvas.getContext("2d"); | ||
| test("getTotalWidth", () => { | ||
| const text = [{ text: "test", font: "Arial" }]; | ||
| expect( getTotalWidth(ctx, text, 20, 0) ).toBeCloseTo(32, -0.5); | ||
| expect( getTotalWidth(ctx, text, 40, 0) ).toBeCloseTo(64, -0.5); | ||
| expect( getTotalWidth(ctx, text, 60, 0) ).toBeCloseTo(96, -1); | ||
| expect( getTotalWidth(ctx, text, 80, 0) ).toBeCloseTo(128, -1); | ||
| expect( getTotalWidth(ctx, text, 0.1, 0) ).toBeCloseTo(0, 0); | ||
| }); |
| import { getLines } from "../lib/wrapText"; | ||
| import Canvas from "canvas"; | ||
| const canvas = Canvas.createCanvas(100, 100); | ||
| const ctx = canvas.getContext("2d"); | ||
| test("getLines", () => { | ||
| let text = [{ | ||
| text: "I'd like to interject for a moment, what you reffered to as Linux was in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called \"Linux\", and many of its users are not aware that it is basically the GNU system, developed by the GNU Project. The Free Software Foundation obviously intends Linux to be free software like any other free program, and whoever works for the Free Software Foundation will do whatever it takes to ensure that the GNU system remains free. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called \"Linux\" distributions are really distributions of GNU/Linux.", | ||
| font: 'Arial', | ||
| }] | ||
| let lines = getLines(ctx, text, 1000, 20); | ||
| expect(lines.length).toBe(13); | ||
| expect(lines[0]).toStrictEqual([ | ||
| { text: "I'd", font: 'Arial' }, | ||
| { text: 'like', font: 'Arial' }, | ||
| { text: 'to', font: 'Arial' }, | ||
| { text: 'interject', font: 'Arial' }, | ||
| { text: 'for', font: 'Arial' }, | ||
| { text: 'a', font: 'Arial' }, | ||
| { text: 'moment,', font: 'Arial' }, | ||
| { text: 'what', font: 'Arial' }, | ||
| { text: 'you', font: 'Arial' }, | ||
| { text: 'reffered', font: 'Arial' }, | ||
| { text: 'to', font: 'Arial' }, | ||
| { text: 'as', font: 'Arial' }, | ||
| { text: 'Linux', font: 'Arial' }, | ||
| { text: 'was', font: 'Arial' }, | ||
| { text: 'in', font: 'Arial' }, | ||
| { text: 'fact,', font: 'Arial' }, | ||
| { text: 'GNU/Linux,', font: 'Arial' }, | ||
| { text: 'or', font: 'Arial' }, | ||
| { text: 'as', font: 'Arial' }, | ||
| { text: "I've", font: 'Arial' }, | ||
| { text: 'recently', font: 'Arial' }, | ||
| { text: 'taken', font: 'Arial' }, | ||
| { text: 'to', font: 'Arial' } | ||
| ]); | ||
| }); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
177
35.11%0
-100%15099
-28.37%6
100%10
-37.5%268
-4.63%No
NaN