Skip to content

Commit 6cab6f0

Browse files
committed
add spr()
* spr() draws pixel by pixel * paint() now only accepts a callback
1 parent 520591f commit 6cab6f0

File tree

9 files changed

+173
-98
lines changed

9 files changed

+173
-98
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "litecanvas",
3-
"version": "0.96.0",
3+
"version": "0.97.0",
44
"description": "Lightweight HTML5 canvas 2D game engine suitable for small projects and creative coding. Inspired by PICO-8 and P5/Processing.",
55
"license": "MIT",
66
"author": "Luiz Bills <luizbills@pm.me>",

samples/bench/bench.js

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,28 @@ function init() {
1818
state.sprite = paint(
1919
12,
2020
12,
21-
[
22-
'....4444....',
23-
'....4aa4....',
24-
'..004aa400..',
25-
'..02444420..',
26-
'777733335555',
27-
'766731135bb5',
28-
'766731135bb5',
29-
'777733335555',
30-
'..02999920..',
31-
'..00988900..',
32-
'....9889....',
33-
'....9999....',
34-
],
21+
() => {
22+
spr(
23+
0,
24+
0,
25+
12,
26+
12,
27+
[
28+
'....4444....',
29+
'....4aa4....',
30+
'..004aa400..',
31+
'..02444420..',
32+
'777733335555',
33+
'766731135bb5',
34+
'766731135bb5',
35+
'777733335555',
36+
'..02999920..',
37+
'..00988900..',
38+
'....9889....',
39+
'....9999....',
40+
].join('')
41+
)
42+
},
3543
{
3644
scale: 3,
3745
}

samples/custom-palette/custom-palette.js

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,21 @@ function init() {
2323
'#FF77A8',
2424
'#FFCCAA',
2525
])
26-
27-
// create a PICO-8 logo image
28-
pico8logo = paint(5, 5, [
29-
// prettier-ignore
30-
'..8..',
31-
'.97f.',
32-
'a777e',
33-
'.b7d.',
34-
'..c..',
35-
])
3626
}
3727

3828
function draw() {
29+
console.log('drawing...')
3930
cls(0)
40-
image(0, 0, pico8logo)
31+
spr(
32+
0,
33+
0,
34+
5,
35+
5,
36+
`
37+
..8..
38+
.97f.
39+
a777e
40+
.b7d.
41+
..c..`
42+
)
4143
}

samples/logo/logo.js

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,32 @@ let scale = floor(size / minsize)
1212
logo = paint(
1313
minsize,
1414
minsize,
15-
[
16-
'................',
17-
'................',
18-
'......4444......',
19-
'......4aa4......',
20-
'....004aa400....',
21-
'....02444420....',
22-
'..777733335555..',
23-
'..766731135bb5..',
24-
'..766731135bb5..',
25-
'..777733335555..',
26-
'....02999920....',
27-
'....00988900....',
28-
'......9889......',
29-
'......9999......',
30-
'................',
31-
'................',
32-
],
15+
() => {
16+
spr(
17+
0,
18+
0,
19+
minsize,
20+
minsize,
21+
[
22+
'................',
23+
'................',
24+
'......4444......',
25+
'......4aa4......',
26+
'....004aa400....',
27+
'....02444420....',
28+
'..777733335555..',
29+
'..766731135bb5..',
30+
'..766731135bb5..',
31+
'..777733335555..',
32+
'....02999920....',
33+
'....00988900....',
34+
'......9889......',
35+
'......9999......',
36+
'................',
37+
'................',
38+
].join('')
39+
)
40+
},
3341
{
3442
scale,
3543
}

samples/pixelart/pixelart.js

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,51 @@ litecanvas({
44
autoscale: 4, // auto scale by until 4x
55
})
66

7-
const art = paint(
8-
8, // the pixel art width
9-
8, // the pixelart height
10-
[
11-
// the pixelart pixels:
12-
// each number is a pixel color
13-
// note: use space or dots to make a pixel 100% transparent
14-
' 0000 ',
15-
' 055550 ',
16-
'05505050',
17-
'05555550',
18-
'05500050',
19-
'05555550',
20-
'.055550.',
21-
'..0000..',
22-
],
23-
{
24-
scale: 2, // this pixelart is twice bigger
7+
const smile = `
8+
..0000..
9+
.055550.
10+
05505050
11+
05555550
12+
05500050
13+
05555550
14+
.055550.
15+
..0000..`
16+
17+
// https://lospec.com/palette-list/kulepu
18+
const palKulepu = [
19+
'#180c10',
20+
'#3d4249',
21+
'#798890',
22+
'#a6cbc4',
23+
'#43a6c7',
24+
'#2d488c',
25+
'#8f74e8',
26+
'#e7aac7',
27+
'#f0f5dc',
28+
'#f0b886',
29+
'#d87f5c',
30+
'#8b3e34',
31+
'#f0933b',
32+
'#f1cc46',
33+
'#89ab3e',
34+
'#306645',
35+
]
36+
37+
let usingAltPal = false
38+
39+
function tapped() {
40+
if (usingAltPal) {
41+
pal()
42+
} else {
43+
pal(palKulepu)
2544
}
26-
)
45+
usingAltPal = !usingAltPal
46+
}
2747

2848
function draw() {
2949
cls(3)
30-
image(0, 0, art)
50+
push()
51+
scale(2)
52+
spr(0, 0, 8, 8, smile)
53+
pop()
3154
}

src/index.js

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -728,19 +728,46 @@ export default function litecanvas(settings = {}) {
728728
_ctx.drawImage(source, ~~x, ~~y)
729729
},
730730

731+
/**
732+
* Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
733+
*
734+
* @param {number} x
735+
* @param {number} y
736+
* @param {number} width
737+
* @param {number} height
738+
* @param {string} pixels
739+
*/
740+
spr(x, y, width, height, pixels) {
741+
DEV: assert(isNumber(x), '[litecanvas] spr() 1st param must be a number')
742+
DEV: assert(isNumber(y), '[litecanvas] spr() 2nd param must be a number')
743+
DEV: assert(isNumber(width), '[litecanvas] spr() 3rd param must be a number')
744+
DEV: assert(isNumber(height), '[litecanvas] spr() 4th param must be a number')
745+
DEV: assert('string' === typeof pixels, '[litecanvas] spr() 5th param must be a string')
746+
747+
const chars = pixels.replace(/\s/g, '')
748+
for (let gridx = 0; gridx < width; gridx++) {
749+
for (let gridy = 0; gridy < height; gridy++) {
750+
const char = chars[height * gridy + gridx] || '.'
751+
if (char !== '.') {
752+
instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 16) || 0)
753+
}
754+
}
755+
}
756+
},
757+
731758
/**
732759
* Draw in an OffscreenCanvas and returns its image.
733760
*
734761
* @param {number} width
735762
* @param {number} height
736-
* @param {string[]|drawCallback} drawing
763+
* @param {drawCallback} callback
737764
* @param {object} [options]
738765
* @param {number} [options.scale=1]
739766
* @param {OffscreenCanvas} [options.canvas]
740767
* @returns {ImageBitmap}
741768
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
742769
*/
743-
paint(width, height, drawing, options = {}) {
770+
paint(width, height, callback, options = {}) {
744771
DEV: assert(
745772
isNumber(width) && width >= 1,
746773
'[litecanvas] paint() 1st param must be a positive number'
@@ -750,7 +777,7 @@ export default function litecanvas(settings = {}) {
750777
'[litecanvas] paint() 2nd param must be a positive number'
751778
)
752779
DEV: assert(
753-
'function' === typeof drawing || Array.isArray(drawing),
780+
'function' === typeof callback,
754781
'[litecanvas] paint() 3rd param must be a function or array'
755782
)
756783
DEV: assert(
@@ -765,37 +792,16 @@ export default function litecanvas(settings = {}) {
765792
const /** @type {OffscreenCanvas} */
766793
canvas = options.canvas || new OffscreenCanvas(1, 1),
767794
scale = options.scale || 1,
768-
contextOriginal = _ctx
795+
currentContext = _ctx // context backup
769796

770797
canvas.width = width * scale
771798
canvas.height = height * scale
772799

773800
_ctx = canvas.getContext('2d')
774801
_ctx.scale(scale, scale)
802+
callback(_ctx)
775803

776-
// draw pixel art if `draw` is a array
777-
if (Array.isArray(drawing)) {
778-
let x = 0,
779-
y = 0
780-
781-
_ctx.imageSmoothingEnabled = false
782-
783-
for (const str of drawing) {
784-
for (const color of str) {
785-
if (' ' !== color && '.' !== color) {
786-
// support for 16-color palette using hex (from 0 to f)
787-
instance.rectfill(x, y, 1, 1, parseInt(color, 16))
788-
}
789-
x++
790-
}
791-
y++
792-
x = 0
793-
}
794-
} else {
795-
drawing(_ctx)
796-
}
797-
798-
_ctx = contextOriginal // restore the context
804+
_ctx = currentContext // restore the context
799805

800806
return canvas.transferToImageBitmap()
801807
},

src/version.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

types/global.d.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ declare global {
356356
*/
357357
function textalign(align: CanvasTextAlign, baseline: CanvasTextBaseline): void
358358

359-
/** IMAGE GRAPHICS API */
359+
/** BASIC GRAPHICS API */
360360
/**
361361
* Draw an image
362362
*
@@ -365,19 +365,33 @@ declare global {
365365
* @param source
366366
*/
367367
function image(x: number, y: number, source: CanvasImageSource): void
368+
/**
369+
* Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number or a dot:
370+
*
371+
* - A base 36 number (`0-9` or `a-z`) represent a pixel color (supporting color palettes with max 36 colors).
372+
* - A dot (`.`) represent a transparent pixel.
373+
* - Spaces and lines breaks are ignored and can be used to improve the visualization.
374+
*
375+
* @param x the position X of the first pixel
376+
* @param y the position Y of the first pixel
377+
* @param width the width of the sprite
378+
* @param height the height of the sprite
379+
* @param pixels
380+
*/
381+
function spr(x: number, y: number, width: number, height: number, pixels: string): void
368382
/**
369383
* Draw in an OffscreenCanvas and returns its image.
370384
*
371385
* @param width
372386
* @param height
373-
* @param drawing
387+
* @param callback
374388
* @param [options]
375389
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
376390
*/
377391
function paint(
378392
width: number,
379393
height: number,
380-
drawing: string[] | drawCallback,
394+
callback: drawCallback,
381395
options?: {
382396
scale?: number
383397
canvas?: OffscreenCanvas

types/types.d.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ type LitecanvasInstance = {
350350
*/
351351
textalign(align: CanvasTextAlign, baseline: CanvasTextBaseline): void
352352

353-
/** IMAGE GRAPHICS API */
353+
/** BASIC GRAPHICS API */
354354
/**
355355
* Draw an image
356356
*
@@ -359,19 +359,33 @@ type LitecanvasInstance = {
359359
* @param source
360360
*/
361361
image(x: number, y: number, source: CanvasImageSource): void
362+
/**
363+
* Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number or a dot:
364+
*
365+
* - A base 36 number (`0-9` or `a-z`) represent a pixel color (supporting color palettes with max 36 colors).
366+
* - A dot (`.`) represent a transparent pixel.
367+
* - Spaces and lines breaks are ignored and can be used to improve the visualization.
368+
*
369+
* @param x the position X of the first pixel
370+
* @param y the position Y of the first pixel
371+
* @param width the width of the sprite
372+
* @param height the height of the sprite
373+
* @param pixels
374+
*/
375+
spr(x: number, y: number, width: number, height: number, pixels: string): void
362376
/**
363377
* Draw in an OffscreenCanvas and returns its image.
364378
*
365379
* @param width
366380
* @param height
367-
* @param drawing
381+
* @param callback
368382
* @param [options]
369383
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
370384
*/
371385
paint(
372386
width: number,
373387
height: number,
374-
drawing: string[] | drawCallback,
388+
callback: drawCallback,
375389
options?: {
376390
scale?: number
377391
canvas?: OffscreenCanvas

0 commit comments

Comments
 (0)