Spaces:
Build error
Build error
const BlockType = require('../../extension-support/block-type'); | |
const ArgumentType = require('../../extension-support/argument-type'); | |
const Color = require('../../util/color'); | |
const cstore = require('./canvasStorage'); | |
const Cast = require('../../util/cast'); | |
const store = new cstore(); | |
/** | |
* Class | |
* @constructor | |
*/ | |
class canvas { | |
constructor(runtime) { | |
/** | |
* The runtime instantiating this block package. | |
* @type {runtime} | |
*/ | |
this.runtime = runtime; | |
store.attachRuntime(runtime); | |
} | |
static get canvasStorageHeader() { | |
return 'canvases: '; | |
} | |
deserialize(data) { | |
store.canvases = {}; | |
for (const canvas of data) { | |
store.newCanvas(canvas.name, canvas.width, canvas.height, canvas.id); | |
} | |
} | |
serialize() { | |
return store.getAllCanvases() | |
.map(variable => ({ | |
name: variable.name, | |
width: variable.width, | |
height: variable.height, | |
id: variable.id | |
})); | |
} | |
readAsImageElement(src) { | |
return new Promise((resolve, reject) => { | |
const image = new Image(); | |
image.onload = function () { | |
resolve(image); | |
image.onload = null; | |
image.onerror = null; | |
}; | |
image.onerror = function () { | |
reject(new Error('Costume load failed. Asset could not be read.')); | |
image.onload = null; | |
image.onerror = null; | |
}; | |
image.src = src; | |
}); | |
} | |
orderCategoryBlocks(blocks) { | |
const button = blocks[0]; | |
const varBlock = blocks[1]; | |
delete blocks[0]; | |
delete blocks[1]; | |
// create the variable block xml's | |
const varBlocks = store.getAllCanvases().map(canvas => varBlock | |
.replace('{canvasId}', canvas.id)); | |
if (!varBlocks.length) { | |
return [button]; | |
} | |
// push the button to the top of the var list | |
varBlocks | |
.reverse() | |
.push(button); | |
// merge the category blocks and variable blocks into one block list | |
blocks = varBlocks | |
.reverse() | |
.concat(blocks); | |
return blocks; | |
} | |
/** | |
* @returns {object} metadata for this extension and its blocks. | |
*/ | |
getInfo() { | |
return { | |
id: 'canvas', | |
name: 'html canvas', | |
color1: '#0069c2', | |
color2: '#0060B4', | |
color3: '#0060B4', | |
isDynamic: true, | |
orderBlocks: this.orderCategoryBlocks, | |
blocks: [ | |
{ | |
opcode: 'createNewCanvas', | |
blockType: BlockType.BUTTON, | |
text: 'create new canvas' | |
}, | |
{ | |
opcode: 'canvasGetter', | |
blockType: BlockType.REPORTER, | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: '{canvasId}' | |
} | |
}, | |
text: '[canvas]' | |
}, | |
{ | |
blockType: BlockType.LABEL, | |
text: "config" | |
}, | |
{ | |
opcode: 'setGlobalCompositeOperation', | |
text: 'set composite operation of [canvas] to [CompositeOperation]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
CompositeOperation: { | |
type: ArgumentType.STRING, | |
menu: 'CompositeOperation', | |
defaultValue: "" | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
{ | |
opcode: 'setSize', | |
text: 'set width: [width] height: [height] of [canvas]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
width: { | |
type: ArgumentType.NUMBER, | |
defaultValue: this.runtime.stageWidth | |
}, | |
height: { | |
type: ArgumentType.NUMBER, | |
defaultValue: this.runtime.stageHeight | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
{ | |
opcode: 'setTransparency', | |
text: 'set transparency of [canvas] to [transparency]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
transparency: { | |
type: ArgumentType.NUMBER, | |
defaultValue: '0' | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
{ | |
opcode: 'setFill', | |
text: 'set fill color of [canvas] to [color]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
color: { | |
type: ArgumentType.COLOR | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
{ | |
opcode: 'setBorderColor', | |
text: 'set border color of [canvas] to [color]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
color: { | |
type: ArgumentType.COLOR | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
{ | |
blockType: BlockType.LABEL, | |
text: "drawing" | |
}, | |
{ | |
opcode: 'clearCanvas', | |
text: 'clear canvas [canvas]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
{ | |
opcode: 'clearAria', | |
text: 'clear area at x: [x] y: [y] with width: [width] height: [height] on [canvas]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
x: { | |
type: ArgumentType.NUMBER, | |
defaultValue: '0' | |
}, | |
y: { | |
type: ArgumentType.NUMBER, | |
defaultValue: '0' | |
}, | |
width: { | |
type: ArgumentType.NUMBER, | |
defaultValue: this.runtime.stageWidth | |
}, | |
height: { | |
type: ArgumentType.NUMBER, | |
defaultValue: this.runtime.stageHeight | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
'---', | |
{ | |
opcode: 'drawRect', | |
text: 'draw rectangle at x: [x] y: [y] with width: [width] height: [height] on [canvas]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
x: { | |
type: ArgumentType.NUMBER, | |
defaultValue: '0' | |
}, | |
y: { | |
type: ArgumentType.NUMBER, | |
defaultValue: '0' | |
}, | |
width: { | |
type: ArgumentType.NUMBER, | |
defaultValue: this.runtime.stageWidth | |
}, | |
height: { | |
type: ArgumentType.NUMBER, | |
defaultValue: this.runtime.stageHeight | |
} | |
}, | |
blockType: BlockType.COMMAND | |
}, | |
{ | |
opcode: 'drawImage', | |
text: 'draw image [src] at x: [x] y: [y] on [canvas]', | |
arguments: { | |
canvas: { | |
type: ArgumentType.STRING, | |
menu: 'canvas', | |
defaultValue: "" | |
}, | |
x: { | |
type: ArgumentType.NUMBER, | |
defaultValue: '0' | |
}, | |
y: { | |
type: ArgumentType.NUMBER, | |
defaultValue: '0' | |
}, | |
src: { | |
type: ArgumentType.STRING, | |
defaultValue: 'https://studio.penguinmod.com/favicon.ico' | |
} | |
}, | |
blockType: BlockType.COMMAND | |
} | |
], | |
menus: { | |
canvas: 'getCanvasMenuItems', | |
CompositeOperation: { | |
items: [ | |
{ | |
"text": "source-over", | |
"value": "source-over" | |
}, | |
{ | |
"text": "source-in", | |
"value": "source-in" | |
}, | |
{ | |
"text": "source-out", | |
"value": "source-out" | |
}, | |
{ | |
"text": "source-atop", | |
"value": "source-atop" | |
}, | |
{ | |
"text": "destination-over", | |
"value": "destination-over" | |
}, | |
{ | |
"text": "destination-in", | |
"value": "destination-in" | |
}, | |
{ | |
"text": "destination-out", | |
"value": "destination-out" | |
}, | |
{ | |
"text": "destination-atop", | |
"value": "destination-atop" | |
}, | |
{ | |
"text": "lighter", | |
"value": "lighter" | |
}, | |
{ | |
"text": "copy", | |
"value": "copy" | |
}, | |
{ | |
"text": "xor", | |
"value": "xor" | |
}, | |
{ | |
"text": "multiply", | |
"value": "multiply" | |
}, | |
{ | |
"text": "screen", | |
"value": "screen" | |
}, | |
{ | |
"text": "overlay", | |
"value": "overlay" | |
}, | |
{ | |
"text": "darken", | |
"value": "darken" | |
}, | |
{ | |
"text": "lighten", | |
"value": "lighten" | |
}, | |
{ | |
"text": "color-dodge", | |
"value": "color-dodge" | |
}, | |
{ | |
"text": "color-burn", | |
"value": "color-burn" | |
}, | |
{ | |
"text": "hard-light", | |
"value": "hard-light" | |
}, | |
{ | |
"text": "soft-light", | |
"value": "soft-light" | |
}, | |
{ | |
"text": "difference", | |
"value": "difference" | |
}, | |
{ | |
"text": "exclusion", | |
"value": "exclusion" | |
}, | |
{ | |
"text": "hue", | |
"value": "hue" | |
}, | |
{ | |
"text": "saturation", | |
"value": "saturation" | |
}, | |
{ | |
"text": "color", | |
"value": "color" | |
}, | |
{ | |
"text": "luminosity", | |
"value": "luminosity" | |
} | |
] | |
} | |
} | |
}; | |
} | |
createNewCanvas() { | |
const newCanvas = prompt('canvas name?', 'newCanvas'); | |
// if this camvas already exists, remove it to minimize confusion | |
if (!newCanvas) return alert('Canceled') | |
if (store.getCanvasByName(newCanvas)) return; | |
store.newCanvas(newCanvas); | |
vm.emitWorkspaceUpdate(); | |
this.serialize(); | |
} | |
getCanvasMenuItems() { | |
const canvases = store.getAllCanvases(); | |
if (canvases.length < 1) return [{ text: '', value: '' }]; | |
return canvases.map(canvas => ({ | |
text: canvas.name, | |
value: canvas.id | |
})); | |
} | |
canvasGetter(args) { | |
const canvasObj = store.getCanvas(args.canvas); | |
return canvasObj.element.toDataURL(); | |
} | |
setGlobalCompositeOperation(args) { | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.context.globalCompositeOperation = args.CompositeOperation; | |
} | |
setBorderColor(args) { | |
const color = Cast.toString(args.color); | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.context.strokeStyle = color; | |
} | |
setFill(args) { | |
const color = Cast.toString(args.color); | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.context.fillStyle = color; | |
} | |
setSize(args) { | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.element.width = args.width; | |
canvasObj.element.height = args.height; | |
canvasObj.context = canvasObj.element.getContext('2d'); | |
} | |
drawRect(args) { | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.context.fillRect(args.x, args.y, args.width, args.height); | |
} | |
drawImage(args) { | |
return new Promise(resolve => { | |
const canvasObj = store.getCanvas(args.canvas); | |
const image = new Image(); | |
image.onload = () => { | |
canvasObj.context.drawImage(image, args.x, args.y); | |
resolve(); | |
}; | |
image.src = args.src; | |
}); | |
} | |
clearAria(args) { | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.context.clearRect(args.x, args.y, args.width, args.height); | |
} | |
clearCanvas(args) { | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.context.clearRect(0, 0, canvasObj.width, canvasObj.height); | |
} | |
setTransparency(args) { | |
const canvasObj = store.getCanvas(args.canvas); | |
canvasObj.context.globalAlpha = args.transparency / 100; | |
} | |
} | |
module.exports = canvas; | |