Published
Edited
Mar 30, 2021
Insert cell
Insert cell
Insert cell
BlocklyCanvasConstants = {
return {
BeginPath: 'beginpath',
ClosePath: 'closepath',
MoveTo: 'moveto',
LineTo: 'lineto',
Stroke: 'stroke',
Fill: 'fill',
Rect: 'rect',
Arc: 'arc',
Triangle: 'triangle',
BezierCurve: 'bezierCurve',
QuadraticCurve: 'quadraticCurve',
Text: 'text'
};
}
Insert cell
Insert cell
function registerBlocklyCanvasExtensions(Blockly) {
const category = {
name: "画板",
kind: "category",
colour: 20,
contents: [
{
name: "路径",
kind: "category",
colour: 120,
contents: [
canvasBeginPath(Blockly),
canvasClosePath(Blockly),
canvasMoveTo(Blockly),
canvasLineTo(Blockly)
]
},
{
name: "形状",
kind: "category",
colour: 160,
contents: [canvasRect(Blockly), canvasBlocklyArc(Blockly), canvasTriangle(Blockly), canvasBezierCurve(Blockly), canvasQuadraticCurve(Blockly), canvasText(Blockly)]
},
{
name: "绘制",
kind: "category",
colour: 180,
contents: [canvasStroke(Blockly), canvasFill(Blockly)]
}
]
};

return category;
}
Insert cell
Insert cell
Insert cell
function canvasBeginPath(Blockly) {
const name = BlocklyCanvasConstants.BeginPath;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("beginPath");
this.appendDummyInput()
.appendField("端点样式")
.appendField(
new Blockly.FieldDropdown([
["butt", "butt"],
["round", "round"],
["square", "square"]
]),
"lineCap"
);
this.appendDummyInput()
.appendField("折点样式")
.appendField(
new Blockly.FieldDropdown([
["miter", "miter"],
["round", "round"],
["bevel", "bevel"]
]),
"lineJoin"
);
this.appendValueInput("strokeStyle")
.setCheck("Colour")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("线条颜色");
this.appendValueInput("lineWidth")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("线条宽度");
this.appendValueInput("fillStyle")
.setCheck("Colour")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("填充颜色");
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(135);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let dropdown_linecap = block.getFieldValue('lineCap');
let dropdown_linejoin = block.getFieldValue('lineJoin');
let value_strokestyle = Blockly.JavaScript.valueToCode(
block,
'strokeStyle',
Blockly.JavaScript.ORDER_NONE
);
let value_linewidth = Blockly.JavaScript.valueToCode(
block,
'lineWidth',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_fillstyle = Blockly.JavaScript.valueToCode(
block,
'fillStyle',
Blockly.JavaScript.ORDER_NONE
);

let code = `
context.lineCap = '${dropdown_linecap}';
context.lineJoin = '${dropdown_linejoin}';
context.strokeStyle = ${value_strokestyle};
context.lineWidth = ${value_linewidth};
context.fillStyle = ${value_fillstyle};
context.beginPath();
${next}`;
return code;
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="strokeStyle">
<shadow type="colour_picker">
<field name="COLOUR">#000000</field>
</shadow>
</value>
<value name="lineWidth">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="fillStyle">
<shadow type="colour_picker">
<field name="COLOUR">#000000</field>
</shadow>
</value>
</block>`
};
}
Insert cell
md`### ClosePath`
Insert cell
function canvasClosePath(Blockly) {
const name = BlocklyCanvasConstants.ClosePath;

Blockly.Blocks[name] = {
init: function() {
this.appendDummyInput().appendField("closePath");
this.setInputsInline(false);
this.setOutput(true, null);
this.setColour(200);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let code = `
context.closePath();`;

return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: ` <block type="${name}"></block>`
};
}
Insert cell
Insert cell
function canvasMoveTo(Blockly) {
const name = BlocklyCanvasConstants.MoveTo;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.appendField("moveTo");
this.appendValueInput("X")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X");
this.appendValueInput("Y")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y");
this.setInputsInline(false);
this.setOutput(true, null);
this.setColour(135);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let value_x = Blockly.JavaScript.valueToCode(
block,
'X',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y = Blockly.JavaScript.valueToCode(
block,
'Y',
Blockly.JavaScript.ORDER_ATOMIC
);
// TODO: Assemble JavaScript into code variable.
let code = `
context.moveTo(${value_x},${value_y});
${next}`;
return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="X">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
<value name="Y">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>`
};
}
Insert cell
Insert cell
function canvasLineTo(Blockly) {
const name = BlocklyCanvasConstants.LineTo;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.appendField("lineTo");
this.appendValueInput("X")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X");
this.appendValueInput("Y")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y");
this.setInputsInline(false);
this.setOutput(true, null);
this.setColour(60);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let value_x = Blockly.JavaScript.valueToCode(
block,
'X',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y = Blockly.JavaScript.valueToCode(
block,
'Y',
Blockly.JavaScript.ORDER_ATOMIC
);

let code = `
context.lineTo(${value_x},${value_y});
${next}`;
return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="X">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="Y">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
</block>`
};
}
Insert cell
Insert cell
function canvasStroke(Blockly) {
const name = BlocklyCanvasConstants.Stroke;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput('next').appendField("stroke");
this.setInputsInline(false);
this.setOutput(true, null);
this.setColour(225);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript['stroke'] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let code = `
context.stroke();
${next}
`;

return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: ` <block type="${name}"></block>`
};
}
Insert cell
md`### Fill`
Insert cell
function canvasFill(Blockly) {
const name = BlocklyCanvasConstants.Fill;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput('next').appendField("fill");
this.setInputsInline(false);
this.setOutput(true, null);
this.setColour(325);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript['fill'] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let code = `
context.fill();
${next}
`;

return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: ` <block type="${name}"></block>`
};
}
Insert cell
Insert cell
function canvasRect(Blockly) {
const name = BlocklyCanvasConstants.Rect;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.appendField("矩形");
this.appendValueInput("X1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("LeftTopX");
this.appendValueInput("Y1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("LeftTopY");
this.appendValueInput("X2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Width");
this.appendValueInput("Y2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Height");
this.setOutput(true, null);
this.setColour(330);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let value_x1 = Blockly.JavaScript.valueToCode(
block,
'X1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y1 = Blockly.JavaScript.valueToCode(
block,
'Y1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x2 = Blockly.JavaScript.valueToCode(
block,
'X2',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y2 = Blockly.JavaScript.valueToCode(
block,
'Y2',
Blockly.JavaScript.ORDER_ATOMIC
);

let code = `
context.rect(${value_x1},${value_y1},${value_x2},${value_y2});
${next}
`;

return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="X1">
<shadow type="math_number">
<field name="NUM">20</field>
</shadow>
</value>
<value name="Y1">
<shadow type="math_number">
<field name="NUM">20</field>
</shadow>
</value>
<value name="X2">
<shadow type="math_number">
<field name="NUM">160</field>
</shadow>
</value>
<value name="Y2">
<shadow type="math_number">
<field name="NUM">140</field>
</shadow>
</value>
</block>`
};
}
Insert cell
Insert cell
function canvasBlocklyArc(Blockly) {
const name = BlocklyCanvasConstants.Arc;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("圆弧");
this.appendValueInput("startX")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X");
this.appendValueInput("startY")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y");
this.appendValueInput("R")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("R");
this.appendValueInput("startAngle")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("起始角");
this.appendValueInput("endAngle")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("结束角");
this.appendValueInput("counterclockwise")
.setCheck("Boolean")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("逆时针");
this.setOutput(true, null);
this.setColour(180);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let value_startx = Blockly.JavaScript.valueToCode(
block,
'startX',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_starty = Blockly.JavaScript.valueToCode(
block,
'startY',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_r = Blockly.JavaScript.valueToCode(
block,
'R',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_startangle = Blockly.JavaScript.valueToCode(
block,
'startAngle',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_endangle = Blockly.JavaScript.valueToCode(
block,
'endAngle',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_counterclockwise = Blockly.JavaScript.valueToCode(
block,
'counterclockwise',
Blockly.JavaScript.ORDER_NONE
);

let code = ` context.arc(${value_startx},${value_starty},${value_r},${value_startangle}/180*Math.PI,${value_endangle}/180*Math.PI,${value_counterclockwise});
${next}
`;
return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="startAngle">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
<value name="endAngle">
<shadow type="math_number">
<field name="NUM">360</field>
</shadow>
</value>
<value name="startX">
<shadow type="math_number">
<field name="NUM">200</field>
</shadow>
</value>
<value name="startY">
<shadow type="math_number">
<field name="NUM">200</field>
</shadow>
</value>
<value name="R">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="counterclockwise">
<shadow type="logic_boolean">
<field name="BOOL">false</field>
</shadow>
</value>
</block>`
};
}
Insert cell
md`### Triangle`
Insert cell
function canvasTriangle(Blockly) {
const name = BlocklyCanvasConstants.Triangle;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.appendField("三角形");
this.appendValueInput("X1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X1");
this.appendValueInput("Y1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y1");
this.appendValueInput("X2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X2");
this.appendValueInput("Y2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y2");
this.appendValueInput("X3")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X3");
this.appendValueInput("Y3")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y3");
this.setOutput(true, null);
this.setColour(360);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let value_x1 = Blockly.JavaScript.valueToCode(
block,
'X1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y1 = Blockly.JavaScript.valueToCode(
block,
'Y1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x2 = Blockly.JavaScript.valueToCode(
block,
'X2',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y2 = Blockly.JavaScript.valueToCode(
block,
'Y2',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x3 = Blockly.JavaScript.valueToCode(
block,
'X3',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y3 = Blockly.JavaScript.valueToCode(
block,
'Y3',
Blockly.JavaScript.ORDER_ATOMIC
);

let code = `
context.moveTo(${value_x1}, ${value_y1});
context.lineTo(${value_x2}, ${value_y2});
context.lineTo(${value_x3}, ${value_y3});
context.lineTo(${value_x1}, ${value_y1});
${next}
`;

return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="X1">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="Y1">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="X2">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="Y2">
<shadow type="math_number">
<field name="NUM">300</field>
</shadow>
</value>
<value name="X3">
<shadow type="math_number">
<field name="NUM">300</field>
</shadow>
</value>
<value name="Y3">
<shadow type="math_number">
<field name="NUM">300</field>
</shadow>
</value>
</block>`
};
}
Insert cell
Insert cell
function canvasBezierCurve(Blockly) {
const name = BlocklyCanvasConstants.BezierCurve;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.appendField("BezierCurve");
this.appendValueInput("X1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X1");
this.appendValueInput("Y1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y1");
this.appendValueInput("X2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X2");
this.appendValueInput("Y2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y2");
this.appendValueInput("X3")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X3");
this.appendValueInput("Y3")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y3");
this.appendValueInput("X4")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X4");
this.appendValueInput("Y4")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y4");
this.setOutput(true, null);
this.setColour(190);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let value_x1 = Blockly.JavaScript.valueToCode(
block,
'X1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y1 = Blockly.JavaScript.valueToCode(
block,
'Y1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x2 = Blockly.JavaScript.valueToCode(
block,
'X2',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y2 = Blockly.JavaScript.valueToCode(
block,
'Y2',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x3 = Blockly.JavaScript.valueToCode(
block,
'X3',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y3 = Blockly.JavaScript.valueToCode(
block,
'Y3',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x4 = Blockly.JavaScript.valueToCode(
block,
'X4',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y4 = Blockly.JavaScript.valueToCode(
block,
'Y4',
Blockly.JavaScript.ORDER_ATOMIC
);

let code = `
context.moveTo(${value_x1}, ${value_y1});
context.bezierCurveTo(${value_x2}, ${value_y2}, ${value_x3}, ${value_y3}, ${value_x4}, ${value_y4});
${next}
`;

return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="X1">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="Y1">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="X2">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="Y2">
<shadow type="math_number">
<field name="NUM">300</field>
</shadow>
</value>
<value name="X3">
<shadow type="math_number">
<field name="NUM">300</field>
</shadow>
</value>
<value name="Y3">
<shadow type="math_number">
<field name="NUM">300</field>
</shadow>
</value>
<value name="X4">
<shadow type="math_number">
<field name="NUM">300</field>
</shadow>
</value>
<value name="Y4">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
</block>`
};
}
Insert cell
md`### QuadraticCurve`
Insert cell
function canvasQuadraticCurve(Blockly) {
const name = BlocklyCanvasConstants.QuadraticCurve;

Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.appendField("QuadraticCurve");
this.appendValueInput("X1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X1");
this.appendValueInput("Y1")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y1");
this.appendValueInput("X2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X2");
this.appendValueInput("Y2")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y2");
this.appendValueInput("X3")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X3");
this.appendValueInput("Y3")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("Y3");
this.setOutput(true, null);
this.setColour(280);
this.setTooltip("");
this.setHelpUrl("");
}
};

Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let value_x1 = Blockly.JavaScript.valueToCode(
block,
'X1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y1 = Blockly.JavaScript.valueToCode(
block,
'Y1',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x2 = Blockly.JavaScript.valueToCode(
block,
'X2',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y2 = Blockly.JavaScript.valueToCode(
block,
'Y2',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x3 = Blockly.JavaScript.valueToCode(
block,
'X3',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y3 = Blockly.JavaScript.valueToCode(
block,
'Y3',
Blockly.JavaScript.ORDER_ATOMIC
);
let code = `
context.moveTo(${value_x1}, ${value_y1});
context.quadraticCurveTo(${value_x2}, ${value_y2}, ${value_x3}, ${value_y3});
${next}
`;

return [code, Blockly.JavaScript.ORDER_NONE];
};

return {
kind: "block",
blockxml: `<block type="${name}">
<value name="X1">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="Y1">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="X2">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="Y2">
<shadow type="math_number">
<field name="NUM">250</field>
</shadow>
</value>
<value name="X3">
<shadow type="math_number">
<field name="NUM">400</field>
</shadow>
</value>
<value name="Y3">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
</block>`
};
}
Insert cell
md`### Text`
Insert cell
function canvasText(Blockly) {
const name = BlocklyCanvasConstants.Text;
Blockly.Blocks[name] = {
init: function() {
this.appendValueInput("next")
.setCheck(null)
.appendField("文字");
this.appendValueInput("font")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("font");
this.appendValueInput("text")
.setCheck("String")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("text");
this.appendValueInput("X")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("X");
this.appendValueInput("y")
.setCheck("Number")
.setAlign(Blockly.ALIGN_CENTRE)
.appendField("y");
this.setOutput(true, null);
this.setColour(280);
this.setTooltip("");
this.setHelpUrl("");
}
};
Blockly.JavaScript[name] = function(block) {
let next = Blockly.JavaScript.valueToCode(
block,
'next',
Blockly.JavaScript.ORDER_NONE
);
let font = Blockly.JavaScript.valueToCode(
block,
'font',
Blockly.JavaScript.ORDER_ATOMIC
);
let text = Blockly.JavaScript.valueToCode(
block,
'text',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_x = Blockly.JavaScript.valueToCode(
block,
'X',
Blockly.JavaScript.ORDER_ATOMIC
);
let value_y = Blockly.JavaScript.valueToCode(
block,
'Y',
Blockly.JavaScript.ORDER_ATOMIC
);
let code = `
context.font = "${font}px Arial";
context.fillText(${text}, ${value_x}, ${value_y});
${next}
`;

return [code, Blockly.JavaScript.ORDER_NONE];
};
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more