Blockly Menu作成(3)
前回に続けて、googleのガイドを参照して作成していこうと思います。
Google for Education > Blockly > Guides > Get Started
可変サイズ
googleのガイドを参照します。
Resizable Workspace
on resizeイベント時にblocklyAreaに合わせてサイズを再計算することで実現しているようです。
var onresize = function (e) {
// Compute the absolute coordinates and dimensions of blocklyArea.
var element = blocklyArea;
var x = 0;
var y = 0;
do {
x += element.offsetLeft;
y += element.offsetTop;
element = element.offsetParent;
} while (element);
// Position blocklyDiv over blocklyArea.
blocklyDiv.style.left = x + 'px';
blocklyDiv.style.top = y + 'px';
blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
Blockly.svgResize(workspace);
};
window.addEventListener('resize', onresize, false);
onresize();
ファイル分割
今までindex.htmlの1ファイルだけで作成してきましたが、スクリプトとXMLを分割したいと思います。
スタイルシートの準備もします。
まとめ
HTML
表示サイズの計算のためにblocklyAreaを追加しています。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Blockly Sample</title>
<script src="../blockly/blockly_compressed.js"></script>
<script src="../blockly/blocks_compressed.js"></script>
<script src="../blockly/msg/js/en.js"></script>
<link rel="stylesheet" href="./styles.css">
<script src="./workspace.js"></script>
</head>
<body>
<table>
<tr>
<td>
<p>Blockly toolbox</p>
</td>
</tr>
<tr>
<td id="blocklyArea">
Blockly will be positioned here.
</td>
</tr>
</table>
<div id="blocklyDiv"></div>
</body>
</html>
スタイルシート
スタイルシートを分割します。
styles.css
html, body {
height: 100%;
margin: 0;
}
body {
background-color: #fff;
font-family: sans-serif;
overflow: hidden;
}
h1 {
font-weight: normal;
font-size: 140%;
}
table {
height: 100%;
width: 100%;
}
#blocklyArea {
height: 99%;
background: #fc9;
text-align: center;
}
#blocklyDiv
{
position: absolute;
}
XML
前回のカスタマイズしたメニューを別ファイルに分割します。
toolbox.xml
<xml id="toolbox" style="display: none">
<category name="Control">
<block type="controls_if"></block>
<block type="controls_whileUntil"></block>
<block type="controls_repeat_ext"></block>
</category>
<category name="Logic">
<block type="logic_compare"></block>
<block type="math_number"></block>
<block type="math_arithmetic"></block>
</category>
<category name="Text">
<block type="text"></block>
<block type="text_print"></block>
</category>
<category name="Variables" custom="VARIABLE"></category>
<category name="Functions" custom="PROCEDURE"></category>
</xml>
JavaScript
Resizeするための処理を追加したスクリプトを別ファイルに準備します。
workspace.js
Promise.all(
["toolbox.xml"].map(async file => {
return fetch(file).then(
(res) => {
return res.text();
}
);
})
).then((xmls) => {
xmls.forEach((xml) => {
var parser = new DOMParser();
var doc = parser.parseFromString(xml, "application/xml");
document.body.appendChild(doc.documentElement);
});
}).then(() => {
var blocklyArea = document.getElementById('blocklyArea');
var blocklyDiv = document.getElementById('blocklyDiv');
var toolbox = document.getElementById("toolbox");
var options = {
toolbox: toolbox,
scrollbars: true,
};
var blocklyDiv = document.getElementById('blocklyDiv');
var workspace = Blockly.inject('blocklyDiv', options);
var onresize = function (e) {
// Compute the absolute coordinates and dimensions of blocklyArea.
var element = blocklyArea;
var x = 0;
var y = 0;
do {
x += element.offsetLeft;
y += element.offsetTop;
element = element.offsetParent;
} while (element);
// Position blocklyDiv over blocklyArea.
blocklyDiv.style.left = x + 'px';
blocklyDiv.style.top = y + 'px';
blocklyDiv.style.width = blocklyArea.offsetWidth + 'px';
blocklyDiv.style.height = blocklyArea.offsetHeight + 'px';
Blockly.svgResize(workspace);
};
window.addEventListener('resize', onresize, false);
onresize();
Blockly.svgResize(workspace);
});
Windowsサイズを変更すると、追従してサイズが変更するようになりました。