Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rich text and color support #1

Merged
merged 15 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 38 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Transforming Your Canvas with Multiline Magic ✨
## Features

- [x] Multiline text
- [x] Rich text formatting (with the exception of words with different font _sizes_ not yet working well in terms of text baseline alignment)
- [x] Auto line breaks
- [x] Horizontal Align
- [x] Vertical Align
Expand All @@ -35,11 +36,9 @@ See Demo: [Here](https://canvas-txt.geongeorge.com)

## Install

```
```bash
yarn add canvas-txt

or

# or
npm i canvas-txt
```

Expand All @@ -59,17 +58,17 @@ const ctx = c.getContext('2d')

ctx.clearRect(0, 0, 500, 500)

const txt = 'Lorem ipsum dolor sit amet'
const text = 'Lorem ipsum dolor sit amet'

const { height } = drawText(ctx, txt, {
const { height } = drawText(ctx, text, {
x: 100,
y: 200,
width: 200,
height: 200,
fontSize: 24,
})

console.log(`Total height = ${height}`)
console.log(`Total height = ${height}px`)
```

## Node canvas
Expand All @@ -89,9 +88,9 @@ const fs = require('fs')
function main() {
const canvas = createCanvas(400, 400)
const ctx = canvas.getContext('2d')
const txt = 'Hello World!'
const text = 'Hello World!'

const { height } = drawText(ctx, txt, {
const { height } = drawText(ctx, text, {
x: 100,
y: 200,
width: 200,
Expand All @@ -102,7 +101,7 @@ function main() {
// Convert the canvas to a buffer in PNG format
const buffer = canvas.toBuffer('image/png')
fs.writeFileSync('output.png', buffer)
console.log(`Total height = ${height}`)
console.log(`Total height = ${height}px`)
}

main()
Expand All @@ -123,7 +122,7 @@ const { drawText, getTextHeight, splitText } = window.canvasTxt

![](./src/docs/canvas.jpg)

## Properties
## drawText config properties

| Properties | Default | Description |
| :-----------: | :----------: | :----------------------------------------------------------------------------- |
Expand All @@ -137,19 +136,38 @@ const { drawText, getTextHeight, splitText } = window.canvasTxt
| `font` | `Arial` | Font family of the text |
| `fontSize` | `14` | Font size of the text in px |
| `fontStyle` | `''` | Font style, same as css font-style. Examples: `italic`, `oblique 40deg` |
| `fontVariant` | `''` | Font variant, same as css font-variant. Examples: `small-caps`, `slashed-zero` |
| `fontWeight` | `''` | Font weight, same as css font-weight. Examples: `bold`, `100` |
| `lineHeight` | `null` | Line height of the text, if set to null it tries to auto-detect the value |
| `fontVariant` | `''` | Font variant, same as css font-variant. Examples: `small-caps` |
| `fontWeight` | `'400'` | Font weight, same as css font-weight. Examples: `bold`, `100` |
| `fontColor` | `'black'` | Font color, same as css color. Examples: `blue`, `#00ff00` |
| `justify` | `false` | Justify text if `true`, it will insert spaces between words when necessary. |
| `inferWhitespace` | `true` | If whitespace in the text should be inferred. Only applies if the text given to `drawText()` is a `Word[]`. If the text is a `string`, this config setting is ignored. |

## Methods

```js
import { drawText, splitText, getTextHeight } from 'canvas-txt'
import {
drawText,
specToJson,
wordsToJson,
splitText,
splitWords,
textToWords,
getTextHeight,
getWordHeight,
getTextStyle,
getTextFormat,
} from 'canvas-txt'
```

| Method | Description |
| :---------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `drawText(ctx,text, config)` | To draw the text to the canvas |
| `splitText({ ctx, text, justify, width }` | To split the text `{ ctx: CanvasRenderingContext2D, text: string, justify: boolean, width: number }` |
| `getTextHeight({ ctx, text, style })` | To get the height of the text `{ ctx: CanvasRenderingContext2D, text: string, style: string (font style we pass to ctx.font) }` [ctx.font docs](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/font) |
- `drawText()`: Draws text (`string` or `Word[]`) to a given Canvas.
- `specToJson()`: Converts a `RenderSpec` to a JSON string. Useful for sending it as a message through `Worker.postMessage()`.
- `wordsToJson()`: Converts a `Word[]` to a JSON string. Useful for sending it as a message to a Worker thread via `Worker.postMessage()`.
- `splitText()`: Splits a given `string` into wrapped lines.
- `splitWords()`: Splits a given `Word[]` into wrapped lines.
- `textToWords()`: Converts a `string` into a `Word[]`. Useful if you want to then apply rich formatting to certain words.
- `getTextHeight()`: Gets the measured height of a given `string` using a given text style.
- `getWordHeight()`: Gets the measured height of a given `Word` using its text style.
- `getTextStyle()`: Generates a CSS Font `string` from a given `TextFormat` for use with `canvas.getContext('2d').font`
- `getTextFormat()`: Generates a "full" `TextFormat` object (all properties specified) given one with only partial properties using prescribed defaults.

TypeScript integration should provide helpful JSDocs for every function and each of its parameters to further help with their use.
4 changes: 3 additions & 1 deletion config/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ export default defineConfig({
root: 'src',
build: {
outDir: '../dist',
sourcemap: true,
lib: {
entry: 'canvas-txt/index.ts',
name: 'canvasTxt',
fileName: 'canvas-txt',
formats: ['es', 'umd'],
fileName: (format) => `canvas-txt${format === 'es' ? '.esm.min.js' : '.umd.min.js' }`,
},
},
})
17 changes: 10 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@
"version": "4.1.1",
"description": "Render multiline textboxes in HTML5 canvas with auto line breaks and better alignment system",
"files": [
"dist"
"dist",
"LICENSE",
"README.md"
],
"scripts": {
"dev": "vite serve --config config/vite.config.docs.ts",
"dev:node": "vite-node ./src/node-test.ts",
"build": "tsc && vite build --emptyOutDir --config config/vite.config.ts && yarn build:dts",
"dev:node": "vite-node ./src/node-test.ts",
"build": "tsc && vite build --emptyOutDir --config config/vite.config.ts && yarn build:dts && cp ./dist/canvas-txt.esm.min.js ./dist/canvas-txt.mjs",
"build:dts": "tsup src/canvas-txt/index.ts --dts-only && mv dist/index.d.ts dist/canvas-txt.d.ts",
"build:docs": "tsc && vite build --config config/vite.config.docs.ts",
"prepare": "yarn build"
},
"main": "./dist/canvas-txt.umd.js",
"module": "./dist/canvas-txt.mjs",
"main": "./dist/canvas-txt.umd.min.js",
"module": "./dist/canvas-txt.esm.min.js",
"types": "./dist/canvas-txt.d.ts",
"exports": {
".": {
"import": "./dist/canvas-txt.mjs",
"require": "./dist/canvas-txt.umd.js",
"import": "./dist/canvas-txt.esm.min.js",
"require": "./dist/canvas-txt.umd.min.js",
"types": "./dist/canvas-txt.d.ts"
}
},
Expand All @@ -43,6 +45,7 @@
],
"devDependencies": {
"@types/lodash": "^4.14.182",
"@types/offscreencanvas": "^2019.7.3",
"@vitejs/plugin-vue": "^3.0.1",
"canvas": "^2.11.2",
"element-plus": "^2.2.12",
Expand Down
Loading
Loading