블록코딩 라이브러리 Blockly 사용법
Blockly는 Google에서 만든 블록코딩 라이브러리로 웹페이지에 블록코딩으로 코드를 생성하는 에디터를 제공합니다.
Blockly를 통해 Scratch와 같은 블록코딩 환경을 웹사이트에서 쉽게 구축할 수 있습니다.
과거에는 웹(자바스크립트) 이외의 안드로이드와 iOS와 같은 환경에서 라이브러리를 사용할 수 있었지만 Deprecated되어 현재는 웹 버전만 업데이트되고 있습니다.
설치
Blockly GitHub에서 코드를 다운받습니다. 다운받은 파일을 압축을 풀고 blockly_compressed.js
, blocks_compressed.js
을 복사해 다른 곳에 저장해 둡니다. 이 두 파일이 Blockly 라이브러리의 핵심 파일입니다.
그다음 블록코딩한 블록을 코드로 변환하기 위한 파일을 가져와야 합니다. javascript_compressed.js
, lua_compressed.js
, php_compressed.js
, python_compressed.js
와 같이 프로그래밍 언어 이름 파일이 있는데 이 중 javascript_compressed.js
는 코딩한 블록을 블록을 자바스크립트 코드로 변환하기 위해 필요한 파일입니다. javascript_compressed.js
역시 복사해 다른 곳에 저장해둡니다.
마지막으로 한국어 번역 파일이 필요합니다. Blockly의 블록 설명은 영어로 쓰여있는데 이를 한국어로 번역해 놓은 것을 가져오기 위해 한국어 번역 파일이 필요합니다. 한국어 파일은 msg/js/ko.js
에서 찾을 수 있습니다.
정리하자면, blockly_compressed.js
, blocks_compressed.js
, javascript_compressed.js
, msg/js/ko.js
을 찾아 프로젝트의 라이브러리 폴더에 넣으시면 됩니다.
React, Vue, Webpack과 함께 사용하는 방법은 Blockly Samples를 참고하세요.
적용
아래와 같이 웹사이트의 HTML에서 라이브러리를 불러와 줍니다.
<script src="./script/blockly/blockly_compressed.js"></script>
<script src="./script/blockly/blocks_compressed.js"></script>
<script src="./script/blockly/javascript_compressed.js"></script>
<script src="./script/blockly/ko.js"></script>
그리고 Blockly 에디터가 들어갈 빈 div
를 하나 만들어줍니다.
<div id="blockly"></div>
HTML 파일에서 블록코딩에서 사용할 수 있는 블록이 정의된 XML을 하나 정의해줍니다. 새로운 블록을 추가할 때는 이 XML을 수정하면 됩니다.
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
<category name="Logic" colour="%{BKY_LOGIC_HUE}">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="logic_operation"></block>
<block type="logic_negate"></block>
<block type="logic_boolean"></block>
<block type="logic_null"></block>
<block type="logic_ternary"></block>
</category>
</xml>
웹페이지의 자바스크립트에서 Blockly 라이브러리 사용을 위한 초기화를 해줍니다.
const blockly = document.querySelector('#blockly');
const workspace = Blockly.inject(blockly, {
toolbox: document.querySelector('#toolbox'),
theme: Blockly.Themes.Classic,
});
Blockly.svgResize(workspace);
테마
Blockly의 테마를 정의하면 에디터의 배경색 등을 바꿀 수 있습니다.
자바스크립트 파일에서 Blockly.Themes.Custom
으로 사용자 테마를 만들어줍니다.
Blockly.Themes.Custom = Blockly.Theme.defineTheme('custom', {
base: Blockly.Themes.Classic,
componentStyles: {
workspaceBackgroundColour: '#eef2f9',
toolboxBackgroundColour: '#f6f8fc',
toolboxForegroundColour: '#6e6e8e',
flyoutBackgroundColour: '#f6f8fc',
flyoutForegroundColour: '#6e6e8e',
flyoutOpacity: 1,
scrollbarColour: '#bbbccb',
scrollbarOpacity: 1,
insertionMarkerColour: '#fff',
insertionMarkerOpacity: 1,
cursorColour: '#fff',
},
});
그리고 workspace
정의 부분에서 theme
를 Blockly.Themes.Custom
으로 수정합니다.
const workspace = Blockly.inject(blockly, {
toolbox: document.querySelector('#toolbox'),
theme: Blockly.Themes.Custom,
});`
블록 추가
Blockly.Blocks
에 추가할 블록의 형태를 정의합니다.
블록의 형태는 Blockly Developer Tools에서 블록을 만들고, Block Definition을 JavaScript로 바꿔서 출력한 코드를 가져와 붙여넣으면 쉽게 제작할 수 있습니다.
Blockly.Blocks.hello = {
init() {
this.jsonInit({
message0: '%1번 인사하기',
args0: [
{
type: 'field_number',
name: 'TIME',
value: 0,
min: 0,
precision: 1,
},
],
previousStatement: null,
nextStatement: null,
colour: '#fdd835',
});
},
};
정의한 블록이 코드로 바뀔 때의 코드 형태를 작성합니다.
저희는 javascript_compressed.js
를 사용하기 때문에 Blockly.JavaScript
에 블록의 형태를 정의합니다. 이때, Blockly.Blocks
에서 정의한 블록 이름과 같아야 합니다. (아래 예제에서는 “hello” 블록)
Blockly.JavaScript.hello = (block) => {
const time = block.getFieldValue('TIME');
const code = `for(let i = 0; i < ${time}; i += 1) { alert("hello"); }\n`;
return code;
};
마지막으로 XML에 돌아와서 생성한 블록을 추가합니다.
<xml xmlns="https://developers.google.com/blockly/xml" id="toolbox" style="display: none">
<category name="New" colour="#fdd835">
<block type="hello"></block> <!-- 정의한 블록 -->
</category>
<category name="Logic" colour="%{BKY_LOGIC_HUE}">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="logic_operation"></block>
<block type="logic_negate"></block>
<block type="logic_boolean"></block>
<block type="logic_null"></block>
<block type="logic_ternary"></block>
</category>
</xml>
참고: Blockly Developer Tools Guide
유용한 함수
Blockly 라이브러리에서 자주 사용하는 코드를 함수로 정리해봤습니다.
코드 생성
Blockly.JavaScript.workspaceToCode
함수로 workspace
의 블록을 자바스크립트 코드로 변환할 수 있습니다.
const generateCode = () => {
// 무한루프 방지 설정
window.LoopTrap = 1000;
Blockly.JavaScript.INFINITE_LOOP_TRAP = 'if (--window.LoopTrap == 0) throw "Infinite loop.";';
const code = Blockly.JavaScript.workspaceToCode(workspace);
// 무한루프 방지 해제
Blockly.JavaScript.INFINITE_LOOP_TRAP = null;
return code;
};
코드 실행
eval
함수를 이용해 위에서 생성한 자바스크립트 코드를 실행합니다.
const runWorkspace = async () => {
const code = generateCode();
console.log(code);
try {
console.log('Now running...');
await eval(code);
console.log('Done.');
} catch (e) {
alert(e);
}
};
참고: Generating and Running JavaScript
workspace
의 모든 블록 제거
const clearWorkspace = () => {
Blockly.mainWorkspace.clear();
};
workspace
의 모든 블록을 XML로 변환
const printWorkspaceAsXml = () => {
const workspaceDomXml = Blockly.Xml.workspaceToDom(workspace);
const workspaceRawXml = Blockly.Xml.domToPrettyText(workspaceDomXml);
console.log(workspaceRawXml);
};
XML로 저장된 블록을 workspace
에 불러오기
const MIME_XML = 'application/xml';
const loadWorkspace = (workspaceRawXml) => {
const parser = new DOMParser();
const workspaceDomXml = parser.parseFromString(workspaceRawXml, MIME_XML).documentElement;
Blockly.Xml.clearWorkspaceAndLoadFromXml(workspaceDomXml, workspace);
};