UNPKG

obniz

Version:

obniz sdk for javascript

256 lines (233 loc) 5.73 kB
class Display { constructor(Obniz) { this.Obniz = Obniz; this.width = 128; this.height = 64; this._canvas = null; this._reset(); } _reset() { this._pos = { x: 0, y: 0 }; this.autoFlush = true; } warnCanvasAvailability() { if (this.Obniz.isNode) { throw new Error( 'obniz.js require node-canvas to draw rich contents. see more detail on docs' ); } else { throw new Error('obniz.js cant create canvas element to body'); } } _preparedCanvas() { if (this._canvas) { return this._canvas; } if (this.Obniz.isNode) { try { const { createCanvas } = require('canvas'); this._canvas = createCanvas(this.width, this.height); } catch (e) { // this.warnCanvasAvailability(); return null; } } else { const identifier = 'obnizcanvas-' + this.Obniz.id; let canvas = document.getElementById(identifier); if (!canvas) { canvas = document.createElement('canvas'); canvas.setAttribute('id', identifier); canvas.style.visibility = 'hidden'; canvas.width = this.width; canvas.height = this.height; canvas.style['-webkit-font-smoothing'] = 'none'; let body = document.getElementsByTagName('body')[0]; body.appendChild(canvas); } this._canvas = canvas; } const ctx = this._canvas.getContext('2d'); ctx.fillStyle = '#000'; ctx.fillRect(0, 0, this.width, this.height); ctx.fillStyle = '#FFF'; ctx.strokeStyle = '#FFF'; this._pos.x = 0; this._pos.y = 0; this.fontSize = 16; ctx.font = `${this.fontSize}px Arial`; return this._canvas; } _ctx() { const canvas = this._preparedCanvas(); if (canvas) { return canvas.getContext('2d'); } } font(font, size) { const ctx = this._ctx(); if (typeof size !== 'number') { size = 16; } if (typeof font !== 'string') { font = 'Arial'; } this.fontSize = size; ctx.font = '' + +' ' + size + 'px ' + font; } clear() { const ctx = this._ctx(); this._pos.x = 0; this._pos.y = 0; if (ctx) { ctx.fillStyle = '#000'; ctx.fillRect(0, 0, this.width, this.height); ctx.fillStyle = '#FFF'; ctx.strokeStyle = '#FFF'; this.draw(ctx); } else { let obj = {}; obj['display'] = { clear: true, }; this.Obniz.send(obj); } } pos(x, y) { this._ctx(); //crete first if (typeof x == 'number') { this._pos.x = x; } if (typeof y == 'number') { this._pos.y = y; } return this._pos; } print(text) { const ctx = this._ctx(); if (ctx) { ctx.fillText(text, this._pos.x, this._pos.y + this.fontSize); this.draw(ctx); this._pos.y += this.fontSize; } else { let obj = {}; obj['display'] = { text: '' + text, }; this.Obniz.send(obj); } } line(x_0, y_0, x_1, y_1) { const ctx = this._ctx(); if (ctx) { ctx.beginPath(); ctx.moveTo(x_0, y_0); ctx.lineTo(x_1, y_1); ctx.stroke(); this.draw(ctx); } else { this.warnCanvasAvailability(); } } rect(x, y, width, height, mustFill) { const ctx = this._ctx(); if (ctx) { if (mustFill) { ctx.fillRect(x, y, width, height); } else { ctx.strokeRect(x, y, width, height); } this.draw(ctx); } else { this.warnCanvasAvailability(); } } circle(x, y, r, mustFill) { const ctx = this._ctx(); if (ctx) { ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2); if (mustFill) { ctx.fill(); } else { ctx.stroke(); } this.draw(ctx); } else { this.warnCanvasAvailability(); } } qr(text, correction) { let obj = {}; obj['display'] = { qr: { text, }, }; if (correction) { obj['display'].qr.correction = correction; } this.Obniz.send(obj); } raw(data) { let obj = {}; obj['display'] = { raw: data, }; this.Obniz.send(obj); } setPinName(io, moduleName, funcName) { let obj = {}; obj['display'] = {}; obj['display']['pin_assign'] = {}; obj['display']['pin_assign'][io] = { module_name: moduleName, pin_name: funcName, }; this.Obniz.send(obj); } setPinNames(moduleName, data) { let obj = {}; obj['display'] = {}; obj['display']['pin_assign'] = {}; let noAssignee = true; for (let key in data) { noAssignee = false; obj['display']['pin_assign'][key] = { module_name: moduleName, pin_name: data[key], }; } if (!noAssignee) { this.Obniz.send(obj); } } _draw(ctx) { const stride = this.width / 8; let vram = new Array(stride * 64); const imageData = ctx.getImageData(0, 0, this.width, this.height); const data = imageData.data; for (let i = 0; i < data.length; i += 4) { let brightness = 0.34 * data[i] + 0.5 * data[i + 1] + 0.16 * data[i + 2]; let index = parseInt(i / 4); let line = parseInt(index / this.width); let col = parseInt((index - line * this.width) / 8); let bits = parseInt(index - line * this.width) % 8; if (bits == 0) vram[line * stride + col] = 0x00; if (brightness > 0x7f) vram[line * stride + col] |= 0x80 >> bits; } this.raw(vram); } draw(ctx) { if (this.autoFlush) { this._draw(ctx); } } drawing(autoFlush) { this.autoFlush = autoFlush == true; const ctx = this._ctx(); if (ctx) { this.draw(ctx); } } } module.exports = Display;