Initial checkin for the code for Blockly for the Web codelab (#1273)

* Add Blockly for the Web codelab code

* Adding licences and comments as per review

* Renaming a4/b4 sounds to a5/b5

* Define blocks with defineBlocksWithJsonArray istead of jsonInit
This commit is contained in:
Ewa
2017-09-21 19:22:47 +02:00
committed by RoboErikG
parent 8050ce929c
commit d45d42dad7
22 changed files with 557 additions and 0 deletions

16
demos/codelab/README.md Normal file
View File

@@ -0,0 +1,16 @@
# Blockly for the Web codelab
Code for the [Blockly for the Web codelab](https://developers.google.com/TODO).
In this codelab, you'll learn how to use Blockly JavaScript library
to add a block code editor to a web application.
## What you'll learn
* How to add Blockly to a sample web app.
* How to set up a Blockly workspace.
* How to create a new block in Blockly.
* How to generate and run JavaScript code from blocks.
Example code for each step of the codelab is available from
the [completed](completed/) directory.

View File

@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blockly for the Web Codelab</title>
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
<link rel="stylesheet" href="styles/index.css">
</head>
<body mode="maker">
<header class="mdl-color--cyan-500">
<h1 class="mode-maker">Music Maker</h1>
<h1 class="mode-edit mode-blockly">Music Maker Configuration</h1>
</header>
<main>
<button class="mode-maker mdl-button" id="edit">Edit</button>
<button class="mode-edit mdl-button mdl-js-button" id="done">Done</button>
<button class="mode-blockly mdl-button mdl-js-button" id="save">Save</button>
<p class="hint mode-edit">Tap any button to edit its code. <br/>When complete, press Done.</p>
<div class="maker">
<div>
<div class="button mdl-color--amber-500">1</div>
<div class="button mdl-color--yellow-500">2</div>
<div class="button mdl-color--lime-500">3</div>
</div>
<div>
<div class="button mdl-color--pink-500">4</div>
<div class="button mdl-color--red-500">5</div>
<div class="button mdl-color--light-green-500">6</div>
</div>
<div>
<div class="button mdl-color--cyan-500">7</div>
<div class="button mdl-color--teal-500">8</div>
<div class="button mdl-color--green-500">9</div>
</div>
</div>
<div class="blockly-editor">
<div id="blockly-div" style="height: 480px; width: 400px;"></div>
</div>
</main>
<script src="scripts/music_maker.js"></script>
<script src="scripts/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,61 @@
/**
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
let currentButton;
function handlePlay(event) {
// Add code for playing sound.
}
function save(button) {
// Add code for saving the behavior of a button.
}
function handleSave() {
document.body.setAttribute('mode', 'edit');
save(currentButton);
}
function enableEditMode() {
document.body.setAttribute('mode', 'edit');
document.querySelectorAll('.button').forEach(btn => {
btn.removeEventListener('click', handlePlay);
btn.addEventListener('click', enableBlocklyMode);
});
}
function enableMakerMode() {
document.body.setAttribute('mode', 'maker');
document.querySelectorAll('.button').forEach(btn => {
btn.addEventListener('click', handlePlay);
btn.removeEventListener('click', enableBlocklyMode);
});
}
function enableBlocklyMode(e) {
document.body.setAttribute('mode', 'blockly');
currentButton = e.target;
}
document.querySelector('#edit').addEventListener('click', enableEditMode);
document.querySelector('#done').addEventListener('click', enableMakerMode);
document.querySelector('#save').addEventListener('click', handleSave);
enableMakerMode();
})();

View File

@@ -0,0 +1,33 @@
/**
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const MusicMaker = {
queue_: [],
player_: new Audio(),
queueSound: function(soundUrl) {
this.queue_.push(soundUrl);
},
play: function() {
let next = this.queue_.shift();
if (next) {
this.player_.src = next;
this.player_.play();
}
},
};
MusicMaker.player_.addEventListener(
'ended', MusicMaker.play.bind(MusicMaker));

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,75 @@
main {
width: 400px;
position: relative;
margin: 0 auto;
overflow:hidden;
height: 600px;
}
header {
background-color: green;
width: 100%;
}
h1 {
width: 400px;
position: relative;
margin: 0 auto;
color: #fff;
font-size: 1.8em;
line-height: 2.4em;
}
.mode-edit,
.mode-maker,
.mode-blockly {
display: none;
}
[mode="maker"] .mode-maker,
[mode="edit"] .mode-edit,
[mode="blockly"] .mode-blockly {
display: block;
}
.blockly-editor {
position: absolute;
top: 64px;
left: -400px;
transition: left .4s;
height: 460px;
width: 400px;
background-color: #eee;
}
[mode="blockly"] .blockly-editor {
left: 0;
}
.maker {
display: flex;
flex-flow: column;
justify-content: space-between;
height: 460px;
width: 400px;
}
.maker > div {
display: flex;
justify-content: space-between;
}
.button {
width: 120px;
height: 140px;
color: #fff;
font-size: 3em;
text-align: center;
vertical-align: middle;
line-height: 140px;
}
.mdl-button {
margin: 1em 0;
float: right;
}

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Blockly for the Web Codelab</title>
<link rel="stylesheet" href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css">
<link rel="stylesheet" href="styles/index.css">
</head>
<body mode="maker">
<header class="mdl-color--cyan-500">
<h1 class="mode-maker">Music Maker</h1>
<h1 class="mode-edit mode-blockly">Music Maker Configuration</h1>
</header>
<main>
<button class="mode-maker mdl-button" id="edit">Edit</button>
<button class="mode-edit mdl-button mdl-js-button" id="done">Done</button>
<button class="mode-blockly mdl-button mdl-js-button" id="save">Save</button>
<p class="hint mode-edit">Tap any button to edit its code. <br/>When complete, press Done.</p>
<div class="maker">
<div>
<div class="button mdl-color--amber-500">1</div>
<div class="button mdl-color--yellow-500">2</div>
<div class="button mdl-color--lime-500">3</div>
</div>
<div>
<div class="button mdl-color--pink-500">4</div>
<div class="button mdl-color--red-500">5</div>
<div class="button mdl-color--light-green-500">6</div>
</div>
<div>
<div class="button mdl-color--cyan-500">7</div>
<div class="button mdl-color--teal-500">8</div>
<div class="button mdl-color--green-500">9</div>
</div>
</div>
<div class="blockly-editor">
<div id="blockly-div" style="height: 480px; width: 400px;"></div>
<xml id="toolbox" style="display: none">
<category name="Loops" colour="120">
<block type="controls_repeat_ext">
<value name="TIMES">
<shadow type="math_number">
<field name="NUM">5</field>
</shadow>
</value>
</block>
</category>
<category name="Sounds" colour="355">
<block type="play_sound"></block>
</category>
</xml>
</div>
</main>
<script src="/blockly_compressed.js"></script>
<script src="/blocks_compressed.js"></script>
<script src="/javascript_compressed.js"></script>
<script src="/msg/js/en.js"></script>
<script src="scripts/music_maker.js"></script>
<script src="scripts/sound_blocks.js"></script>
<script src="scripts/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,88 @@
/**
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
let currentButton;
function handlePlay(event) {
loadWorkspace(event.target);
Blockly.JavaScript.addReservedWords('code');
var code = Blockly.JavaScript.workspaceToCode(Blockly.getMainWorkspace());
code += 'MusicMaker.play();';
// Eval can be dangerous. For more controlled execution, check
// https://github.com/NeilFraser/JS-Interpreter.
try {
eval(code);
} catch (error) {
console.log(error);
}
}
function loadWorkspace(button) {
let workspace = Blockly.getMainWorkspace();
workspace.clear();
if (button.blocklyXml) {
Blockly.Xml.domToWorkspace(button.blocklyXml, workspace);
}
}
function save(button) {
let xml = Blockly.Xml.workspaceToDom(Blockly.getMainWorkspace());
button.blocklyXml = xml;
}
function handleSave() {
document.body.setAttribute('mode', 'edit');
save(currentButton);
}
function enableEditMode() {
document.body.setAttribute('mode', 'edit');
document.querySelectorAll('.button').forEach(btn => {
btn.removeEventListener('click', handlePlay);
btn.addEventListener('click', enableBlocklyMode);
});
}
function enableMakerMode() {
document.body.setAttribute('mode', 'maker');
document.querySelectorAll('.button').forEach(btn => {
btn.addEventListener('click', handlePlay);
btn.removeEventListener('click', enableBlocklyMode);
});
}
function enableBlocklyMode(e) {
document.body.setAttribute('mode', 'blockly');
currentButton = e.target;
loadWorkspace(currentButton);
}
document.querySelector('#edit').addEventListener('click', enableEditMode);
document.querySelector('#done').addEventListener('click', enableMakerMode);
document.querySelector('#save').addEventListener('click', handleSave);
enableMakerMode();
Blockly.inject('blockly-div', {
media: '/media/',
toolbox: document.getElementById('toolbox'),
toolboxPosition: 'end',
horizontalLayout: true,
scrollbars: false
});
})();

View File

@@ -0,0 +1,33 @@
/**
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const MusicMaker = {
queue_: [],
player_: new Audio(),
queueSound: function(soundUrl) {
this.queue_.push(soundUrl);
},
play: function() {
let next = this.queue_.shift();
if (next) {
this.player_.src = next;
this.player_.play();
}
},
};
MusicMaker.player_.addEventListener(
'ended', MusicMaker.play.bind(MusicMaker));

View File

@@ -0,0 +1,50 @@
/**
* Copyright 2017 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Blockly.defineBlocksWithJsonArray([
// Block for colour picker.
{
"type": "play_sound",
"message0": "Play %1",
"args0": [
{
"type": "field_dropdown",
"name": "VALUE",
"options": [
["C4", "sounds/c4.m4a"],
["D4", "sounds/d4.m4a"],
["E4", "sounds/e4.m4a"],
["F4", "sounds/f4.m4a"],
["G4", "sounds/g4.m4a"],
["A5", "sounds/a5.m4a"],
["B5", "sounds/b5.m4a"],
["C5", "sounds/c5.m4a"]
]
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 355,
"tooltip": "",
"helpUrl": ""
}
]);
Blockly.JavaScript['play_sound'] = function(block) {
var value = '\'' + block.getFieldValue('VALUE') + '\'';
return 'MusicMaker.queueSound(' + value + ');\n';
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,75 @@
main {
width: 400px;
position: relative;
margin: 0 auto;
overflow:hidden;
height: 600px;
}
header {
background-color: green;
width: 100%;
}
h1 {
width: 400px;
position: relative;
margin: 0 auto;
color: #fff;
font-size: 1.8em;
line-height: 2.4em;
}
.mode-edit,
.mode-maker,
.mode-blockly {
display: none;
}
[mode="maker"] .mode-maker,
[mode="edit"] .mode-edit,
[mode="blockly"] .mode-blockly {
display: block;
}
.blockly-editor {
position: absolute;
top: 64px;
left: -400px;
transition: left .4s;
height: 460px;
width: 400px;
background-color: #eee;
}
[mode="blockly"] .blockly-editor {
left: 0;
}
.maker {
display: flex;
flex-flow: column;
justify-content: space-between;
height: 460px;
width: 400px;
}
.maker > div {
display: flex;
justify-content: space-between;
}
.button {
width: 120px;
height: 140px;
color: #fff;
font-size: 3em;
text-align: center;
vertical-align: middle;
line-height: 140px;
}
.mdl-button {
margin: 1em 0;
float: right;
}