finish start-code for simple js block definition
0 parents
Showing
12 changed files
with
647 additions
and
0 deletions
index.html
0 → 100644
| 1 | <!doctype html> | ||
| 2 | <html> | ||
| 3 | <head> | ||
| 4 | <meta charset="utf-8" /> | ||
| 5 | <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
| 6 | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| 7 | |||
| 8 | <title>Blockly for the Web Codelab</title> | ||
| 9 | |||
| 10 | <link | ||
| 11 | rel="stylesheet" | ||
| 12 | href="https://code.getmdl.io/1.2.1/material.indigo-pink.min.css" /> | ||
| 13 | <link rel="stylesheet" href="styles/index.css" /> | ||
| 14 | </head> | ||
| 15 | |||
| 16 | <body mode="maker"> | ||
| 17 | <header class="mdl-color--cyan-500"> | ||
| 18 | <h1 class="mode-maker">Music Maker</h1> | ||
| 19 | <h1 class="mode-edit mode-blockly">Music Maker Configuration</h1> | ||
| 20 | </header> | ||
| 21 | |||
| 22 | <main> | ||
| 23 | <button class="mode-maker mdl-button" id="edit">Edit</button> | ||
| 24 | <button class="mode-edit mdl-button mdl-js-button" id="done">Done</button> | ||
| 25 | <button class="mode-blockly mdl-button mdl-js-button" id="save"> | ||
| 26 | Save | ||
| 27 | </button> | ||
| 28 | <p class="hint mode-edit"> | ||
| 29 | Tap any button to edit its code. <br />When complete, press Done. | ||
| 30 | </p> | ||
| 31 | |||
| 32 | <div class="maker"> | ||
| 33 | <div> | ||
| 34 | <div class="button mdl-color--amber-500">1</div> | ||
| 35 | <div class="button mdl-color--yellow-500">2</div> | ||
| 36 | <div class="button mdl-color--lime-500">3</div> | ||
| 37 | </div> | ||
| 38 | <div> | ||
| 39 | <div class="button mdl-color--pink-500">4</div> | ||
| 40 | <div class="button mdl-color--red-500">5</div> | ||
| 41 | <div class="button mdl-color--light-green-500">6</div> | ||
| 42 | </div> | ||
| 43 | <div> | ||
| 44 | <div class="button mdl-color--cyan-500">7</div> | ||
| 45 | <div class="button mdl-color--teal-500">8</div> | ||
| 46 | <div class="button mdl-color--green-500">9</div> | ||
| 47 | </div> | ||
| 48 | </div> | ||
| 49 | |||
| 50 | <div class="blockly-editor"> | ||
| 51 | <div id="blocklyDiv" style="height: 480px; width: 400px"></div> | ||
| 52 | </div> | ||
| 53 | </main> | ||
| 54 | |||
| 55 | |||
| 56 | <script src="https://unpkg.com/blockly/blockly_compressed.js"></script> | ||
| 57 | <script src="https://unpkg.com/blockly/blocks_compressed.js"></script> | ||
| 58 | <script src="https://unpkg.com/blockly/javascript_compressed.js"></script> | ||
| 59 | <script src="https://unpkg.com/blockly/msg/en.js"></script> | ||
| 60 | <!-- 先加载blocky的几个核心模块 --> | ||
| 61 | <script src="scripts/sound_blocks.js"></script> | ||
| 62 | |||
| 63 | <script src="scripts/music_maker.js"></script> | ||
| 64 | <script src="scripts/main.js"></script> | ||
| 65 | </body> | ||
| 66 | </html> |
scripts/field_icon_dropdown.js
0 → 100644
| 1 | 'use strict'; | ||
| 2 | |||
| 3 | goog.provide('Blockly.FieldIconDropDown'); | ||
| 4 | goog.require('Blockly.DropDownDiv'); | ||
| 5 | |||
| 6 | |||
| 7 | /** | ||
| 8 | * 构造器 | ||
| 9 | * @param icons | ||
| 10 | * @constructor | ||
| 11 | */ | ||
| 12 | Blockly.FieldIconDropDown = function (icons) { | ||
| 13 | this.icons_ = icons; | ||
| 14 | // Example: | ||
| 15 | // [{src: '...', width: 20, height: 20, value: 'machine_value'}, ...] | ||
| 16 | // 选择第一个为默认值 | ||
| 17 | const defaultValue = icons[0].value; | ||
| 18 | Blockly.FieldIconDropDown.superClass_.constructor.call(this, defaultValue); | ||
| 19 | this.addArgType('icon_dropdown'); | ||
| 20 | }; | ||
| 21 | goog.inherits(Blockly.FieldIconDropDown, Blockly.Field); | ||
| 22 | |||
| 23 | /** | ||
| 24 | * Json配置 | ||
| 25 | */ | ||
| 26 | Blockly.FieldIconDropDown.fromJson = function (element) { | ||
| 27 | return new Blockly.FieldIconDropDown(element['options']); | ||
| 28 | }; | ||
| 29 | |||
| 30 | /** | ||
| 31 | * 下拉面板宽度(不需要修改,3个图标宽度) | ||
| 32 | * @type {number} | ||
| 33 | * @const | ||
| 34 | */ | ||
| 35 | Blockly.FieldIconDropDown.DROPDOWN_WIDTH = 168; | ||
| 36 | |||
| 37 | /** | ||
| 38 | * 颜色记录 | ||
| 39 | */ | ||
| 40 | Blockly.FieldIconDropDown.savedPrimary_ = null; | ||
| 41 | |||
| 42 | /** | ||
| 43 | * 初始化 | ||
| 44 | */ | ||
| 45 | Blockly.FieldIconDropDown.prototype.init = function (block) { | ||
| 46 | if (this.fieldGroup_) { | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | // 下拉箭头大小 | ||
| 50 | const arrowSize = 12; | ||
| 51 | |||
| 52 | // 重建dom | ||
| 53 | this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); | ||
| 54 | this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); | ||
| 55 | |||
| 56 | // 字段宽度 | ||
| 57 | this.size_.width = 44; | ||
| 58 | |||
| 59 | // 图标 | ||
| 60 | this.imageElement_ = Blockly.utils.createSvgElement('image', { | ||
| 61 | 'height': 24 + 'px', | ||
| 62 | 'width': 24 + 'px', | ||
| 63 | 'x': 4 + "px", | ||
| 64 | 'y': 4 + "px", | ||
| 65 | }, this.fieldGroup_); | ||
| 66 | this.setParentFieldImage(this.getSrcForValue(this.value_)); | ||
| 67 | |||
| 68 | // 下拉箭头位置 | ||
| 69 | this.arrowX_ = 32; | ||
| 70 | this.arrowY_ = 10; | ||
| 71 | if (block.RTL) { | ||
| 72 | this.arrowX_ = -this.arrowX_ - arrowSize; | ||
| 73 | } | ||
| 74 | |||
| 75 | // 下拉图标 | ||
| 76 | this.arrowIcon_ = Blockly.utils.createSvgElement('image', { | ||
| 77 | 'height': arrowSize + 'px', | ||
| 78 | 'width': arrowSize + 'px', | ||
| 79 | 'transform': 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')' | ||
| 80 | }, this.fieldGroup_); | ||
| 81 | this.arrowIcon_.setAttributeNS('http://www.w3.org/1999/xlink', | ||
| 82 | 'xlink:href', Blockly.mainWorkspace.options.pathToMedia + 'dropdown-arrow.svg'); | ||
| 83 | |||
| 84 | this.mouseDownWrapper_ = Blockly.bindEventWithChecks_( | ||
| 85 | this.getClickTarget_(), 'mousedown', this, this.onMouseDown_); | ||
| 86 | }; | ||
| 87 | |||
| 88 | /** | ||
| 89 | * 鼠标放置样式 | ||
| 90 | */ | ||
| 91 | Blockly.FieldIconDropDown.prototype.CURSOR = 'default'; | ||
| 92 | |||
| 93 | /** | ||
| 94 | * 设置值 | ||
| 95 | */ | ||
| 96 | Blockly.FieldIconDropDown.prototype.setValue = function (newValue) { | ||
| 97 | if (newValue === null || newValue === this.value_) { | ||
| 98 | return; // No change | ||
| 99 | } | ||
| 100 | if (this.sourceBlock_ && Blockly.Events.isEnabled()) { | ||
| 101 | Blockly.Events.fire(new Blockly.Events.Change( | ||
| 102 | this.sourceBlock_, 'field', this.name, this.value_, newValue)); | ||
| 103 | } | ||
| 104 | this.value_ = newValue; | ||
| 105 | this.setParentFieldImage(this.getSrcForValue(this.value_)); | ||
| 106 | }; | ||
| 107 | |||
| 108 | /** | ||
| 109 | * 设置当前选择图片 | ||
| 110 | */ | ||
| 111 | Blockly.FieldIconDropDown.prototype.setParentFieldImage = function (src) { | ||
| 112 | if (this.imageElement_ && src) { | ||
| 113 | this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', src || ''); | ||
| 114 | } | ||
| 115 | }; | ||
| 116 | |||
| 117 | /** | ||
| 118 | * 获取值 | ||
| 119 | */ | ||
| 120 | Blockly.FieldIconDropDown.prototype.getValue = function () { | ||
| 121 | return this.value_; | ||
| 122 | }; | ||
| 123 | |||
| 124 | /** | ||
| 125 | * 根据src获取值 | ||
| 126 | * @param value | ||
| 127 | * @returns {*} | ||
| 128 | */ | ||
| 129 | Blockly.FieldIconDropDown.prototype.getSrcForValue = function (value) { | ||
| 130 | for (var i = 0, icon; icon = this.icons_[i]; i++) { | ||
| 131 | if (icon.value === value) { | ||
| 132 | return icon.src; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | }; | ||
| 136 | |||
| 137 | /** | ||
| 138 | * 下拉选择 | ||
| 139 | */ | ||
| 140 | Blockly.FieldIconDropDown.prototype.showEditor_ = function () { | ||
| 141 | if (Blockly.DropDownDiv.hideIfOwner(this)) { | ||
| 142 | return; | ||
| 143 | } | ||
| 144 | Blockly.DropDownDiv.hideWithoutAnimation(); | ||
| 145 | Blockly.DropDownDiv.clearContent(); | ||
| 146 | // 构建下拉内容 | ||
| 147 | const contentDiv = Blockly.DropDownDiv.getContentDiv(); | ||
| 148 | // Accessibility properties | ||
| 149 | contentDiv.setAttribute('role', 'menu'); | ||
| 150 | contentDiv.setAttribute('aria-haspopup', 'true'); | ||
| 151 | for (let i = 0, icon; icon = this.icons_[i]; i++) { | ||
| 152 | |||
| 153 | // 按钮 | ||
| 154 | const button = document.createElement('button'); | ||
| 155 | button.setAttribute('id', ':' + i); | ||
| 156 | button.setAttribute('role', 'menuitem'); | ||
| 157 | button.setAttribute('class', 'blocklyDropDownButton'); | ||
| 158 | button.title = icon.alt; | ||
| 159 | button.style.width = icon.width + 'px'; | ||
| 160 | button.style.height = icon.height + 'px'; | ||
| 161 | let backgroundColor = this.sourceBlock_.getColour(); | ||
| 162 | if (icon.value === this.getValue()) { | ||
| 163 | backgroundColor = this.sourceBlock_.getColourTertiary(); | ||
| 164 | button.setAttribute('aria-selected', 'true'); | ||
| 165 | } | ||
| 166 | button.style.backgroundColor = backgroundColor; | ||
| 167 | button.style.borderColor = this.sourceBlock_.getColourTertiary(); | ||
| 168 | |||
| 169 | // 事件 | ||
| 170 | Blockly.bindEvent_(button, 'click', this, this.buttonClick_); | ||
| 171 | Blockly.bindEvent_(button, 'mouseup', this, this.buttonClick_); | ||
| 172 | Blockly.bindEvent_(button, 'mousedown', button, function (e) { | ||
| 173 | this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover'); | ||
| 174 | e.preventDefault(); | ||
| 175 | }); | ||
| 176 | Blockly.bindEvent_(button, 'mouseover', button, function () { | ||
| 177 | this.setAttribute('class', 'blocklyDropDownButton blocklyDropDownButtonHover'); | ||
| 178 | contentDiv.setAttribute('aria-activedescendant', this.id); | ||
| 179 | }); | ||
| 180 | Blockly.bindEvent_(button, 'mouseout', button, function () { | ||
| 181 | this.setAttribute('class', 'blocklyDropDownButton'); | ||
| 182 | contentDiv.removeAttribute('aria-activedescendant'); | ||
| 183 | }); | ||
| 184 | |||
| 185 | // 图标 | ||
| 186 | const buttonImg = document.createElement('img'); | ||
| 187 | buttonImg.src = icon.src; | ||
| 188 | button.setAttribute('data-value', icon.value); | ||
| 189 | buttonImg.setAttribute('data-value', icon.value); | ||
| 190 | button.appendChild(buttonImg); | ||
| 191 | contentDiv.appendChild(button); | ||
| 192 | } | ||
| 193 | contentDiv.style.width = Blockly.FieldIconDropDown.DROPDOWN_WIDTH + 'px'; | ||
| 194 | |||
| 195 | // 设置颜色 | ||
| 196 | Blockly.DropDownDiv.setColour(this.sourceBlock_.getColour(), this.sourceBlock_.getColourTertiary()); | ||
| 197 | Blockly.DropDownDiv.setCategory(this.sourceBlock_.parentBlock_.getCategory()); | ||
| 198 | this.savedPrimary_ = this.sourceBlock_.getColour(); | ||
| 199 | this.sourceBlock_.setColour(this.sourceBlock_.getColourSecondary(), | ||
| 200 | this.sourceBlock_.getColourSecondary(), | ||
| 201 | this.sourceBlock_.getColourTertiary()); | ||
| 202 | |||
| 203 | const scale = this.sourceBlock_.workspace.scale; | ||
| 204 | const secondaryYOffset = ( | ||
| 205 | -(Blockly.BlockSvg.MIN_BLOCK_Y * scale) - (Blockly.BlockSvg.FIELD_Y_OFFSET * scale) | ||
| 206 | ); | ||
| 207 | const renderedPrimary = Blockly.DropDownDiv.showPositionedByBlock(this, this.sourceBlock_, this.onHide_.bind(this), secondaryYOffset); | ||
| 208 | if (!renderedPrimary) { | ||
| 209 | const arrowX = this.arrowX_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5 + 1; | ||
| 210 | const arrowY = this.arrowY_ + Blockly.DropDownDiv.ARROW_SIZE / 1.5; | ||
| 211 | this.arrowIcon_.setAttribute('transform', 'translate(' + arrowX + ',' + arrowY + ') rotate(180)'); | ||
| 212 | } | ||
| 213 | }; | ||
| 214 | |||
| 215 | /** | ||
| 216 | * 点击按钮 | ||
| 217 | */ | ||
| 218 | Blockly.FieldIconDropDown.prototype.buttonClick_ = function (e) { | ||
| 219 | const value = e.target.getAttribute('data-value'); | ||
| 220 | this.setValue(value); | ||
| 221 | Blockly.DropDownDiv.hide(); | ||
| 222 | }; | ||
| 223 | |||
| 224 | /** | ||
| 225 | * 关闭下拉面板时回掉 | ||
| 226 | */ | ||
| 227 | Blockly.FieldIconDropDown.prototype.onHide_ = function () { | ||
| 228 | if (this.sourceBlock_) { | ||
| 229 | this.sourceBlock_.setColour(this.savedPrimary_, | ||
| 230 | this.sourceBlock_.getColourSecondary(), | ||
| 231 | this.sourceBlock_.getColourTertiary()); | ||
| 232 | } | ||
| 233 | Blockly.DropDownDiv.content_.removeAttribute('role'); | ||
| 234 | Blockly.DropDownDiv.content_.removeAttribute('aria-haspopup'); | ||
| 235 | Blockly.DropDownDiv.content_.removeAttribute('aria-activedescendant'); | ||
| 236 | this.arrowIcon_.setAttribute('transform', 'translate(' + this.arrowX_ + ',' + this.arrowY_ + ')'); | ||
| 237 | }; | ||
| 238 | |||
| 239 | Blockly.Field.register('field_icon_dropdown', Blockly.FieldIconDropDown); | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
scripts/main.js
0 → 100644
| 1 | /** | ||
| 2 | * @license | ||
| 3 | * Copyright 2017 Google LLC | ||
| 4 | * SPDX-License-Identifier: Apache-2.0 | ||
| 5 | */ | ||
| 6 | |||
| 7 | goog.require('Blockly.FieldIconDropDown'); | ||
| 8 | |||
| 9 | (function () { | ||
| 10 | let currentButton; | ||
| 11 | |||
| 12 | function handlePlay(event) { | ||
| 13 | loadWorkspace(event.target); // 加载被点击的按钮的工作区 | ||
| 14 | let code = javascript.javascriptGenerator.workspaceToCode(Blockly.getMainWorkspace()); | ||
| 15 | code += 'MusicMaker.play();';// 先加载生成音乐的代码,再添加播放音乐的代码 | ||
| 16 | try { | ||
| 17 | eval(code); // 执行生成的代码 | ||
| 18 | } catch (error) { | ||
| 19 | console.log(error); | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | function save(button) { | ||
| 24 | // Add code for saving the behavior of a button. | ||
| 25 | button.blocklySave = Blockly.serialization.workspaces.save(Blockly.getMainWorkspace());//保存特定按钮的工作区的状态 | ||
| 26 | } | ||
| 27 | |||
| 28 | function handleSave() { | ||
| 29 | document.body.setAttribute('mode', 'edit'); | ||
| 30 | save(currentButton); | ||
| 31 | } | ||
| 32 | |||
| 33 | function loadWorkspace(button) { | ||
| 34 | const workspace = Blockly.getMainWorkspace(); // 获取主工作区 | ||
| 35 | if (button.blocklySave) { | ||
| 36 | Blockly.serialization.workspaces.load(button.blocklySave, workspace); // 加载特定按钮的工作区的状态 | ||
| 37 | } else { | ||
| 38 | workspace.clear(); // 清空工作区 | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | function enableEditMode() { | ||
| 43 | document.body.setAttribute('mode', 'edit'); | ||
| 44 | document.querySelectorAll('.button').forEach((btn) => { | ||
| 45 | btn.removeEventListener('click', handlePlay); | ||
| 46 | btn.addEventListener('click', enableBlocklyMode); | ||
| 47 | }); | ||
| 48 | } | ||
| 49 | |||
| 50 | function enableMakerMode() { | ||
| 51 | document.body.setAttribute('mode', 'maker'); | ||
| 52 | document.querySelectorAll('.button').forEach((btn) => { | ||
| 53 | btn.addEventListener('click', handlePlay); | ||
| 54 | btn.removeEventListener('click', enableBlocklyMode); | ||
| 55 | }); | ||
| 56 | } | ||
| 57 | |||
| 58 | function enableBlocklyMode(e) { | ||
| 59 | document.body.setAttribute('mode', 'blockly'); | ||
| 60 | currentButton = e.target; | ||
| 61 | loadWorkspace(currentButton); | ||
| 62 | } | ||
| 63 | |||
| 64 | document.querySelector('#edit').addEventListener('click', enableEditMode); | ||
| 65 | document.querySelector('#done').addEventListener('click', enableMakerMode); | ||
| 66 | document.querySelector('#save').addEventListener('click', handleSave); | ||
| 67 | |||
| 68 | enableMakerMode(); | ||
| 69 | const toolbox = { // 工具箱 | ||
| 70 | 'kind': 'flyoutToolbox', | ||
| 71 | 'contents': [ | ||
| 72 | { | ||
| 73 | 'kind': 'block', | ||
| 74 | 'type': 'controls_repeat_ext', // 循环块 | ||
| 75 | 'inputs': { | ||
| 76 | 'TIMES': { | ||
| 77 | 'shadow': { | ||
| 78 | 'type': 'math_number', | ||
| 79 | 'fields': { | ||
| 80 | 'NUM': 5 | ||
| 81 | } | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | }, | ||
| 86 | { | ||
| 87 | 'kind': 'block', | ||
| 88 | 'type': 'play_sound' // 播放声音块 | ||
| 89 | }, | ||
| 90 | { | ||
| 91 | 'kind': 'block', | ||
| 92 | 'type': 'ZE3P_led_set_color', // 块类型 | ||
| 93 | 'inputs': { | ||
| 94 | 'COLOR': { | ||
| 95 | 'shadow': { | ||
| 96 | 'type': 'ZE3P_led', // 影子块类型 | ||
| 97 | 'fields': { | ||
| 98 | 'COLOR': 'Red' // 影子块中的字段值 | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | ] | ||
| 105 | }; | ||
| 106 | |||
| 107 | Blockly.inject('blocklyDiv', { // 注入到blocklyDiv中 | ||
| 108 | |||
| 109 | toolbox: toolbox, | ||
| 110 | scrollbars: false, | ||
| 111 | horizontalLayout: true, | ||
| 112 | toolboxPosition: "end", | ||
| 113 | }); | ||
| 114 | })(); |
scripts/music_maker.js
0 → 100644
| 1 | /** | ||
| 2 | * @license | ||
| 3 | * Copyright 2017 Google LLC | ||
| 4 | * SPDX-License-Identifier: Apache-2.0 | ||
| 5 | */ | ||
| 6 | const MusicMaker = { | ||
| 7 | queue_: [], | ||
| 8 | player_: new Audio(), | ||
| 9 | queueSound: function (soundUrl) { | ||
| 10 | this.queue_.push(soundUrl); | ||
| 11 | }, | ||
| 12 | play: function () { | ||
| 13 | const next = this.queue_.shift(); | ||
| 14 | if (next) { | ||
| 15 | this.player_.src = next; | ||
| 16 | this.player_.play(); | ||
| 17 | } | ||
| 18 | }, | ||
| 19 | }; | ||
| 20 | |||
| 21 | MusicMaker.player_.addEventListener('ended', MusicMaker.play.bind(MusicMaker)); |
scripts/sound_blocks.js
0 → 100644
| 1 | Blockly.common.defineBlocksWithJsonArray([ | ||
| 2 | { | ||
| 3 | "type": "play_sound", | ||
| 4 | "message0": "Play %1", | ||
| 5 | "args0": [ | ||
| 6 | { | ||
| 7 | "type": "field_dropdown", // 下拉框 | ||
| 8 | "name": "VALUE", | ||
| 9 | "options": [ // 声音选项 | ||
| 10 | ["C4", "sounds/c4.m4a"], | ||
| 11 | ["D4", "sounds/d4.m4a"], | ||
| 12 | ["E4", "sounds/e4.m4a"], | ||
| 13 | ["F4", "sounds/f4.m4a"], | ||
| 14 | ["G4", "sounds/g4.m4a"] | ||
| 15 | ] | ||
| 16 | } | ||
| 17 | ], | ||
| 18 | "previousStatement": null, | ||
| 19 | "nextStatement": null, | ||
| 20 | "colour": 355 | ||
| 21 | } | ||
| 22 | ]); | ||
| 23 | |||
| 24 | javascript.javascriptGenerator.forBlock['play_sound'] = function(block) { | ||
| 25 | let value = '\'' + block.getFieldValue('VALUE') + '\''; | ||
| 26 | return 'MusicMaker.queueSound(' + value + ');\n'; // 调用MusicMaker.queueSound函数 | ||
| 27 | |||
| 28 | }; | ||
| 29 | |||
| 30 | |||
| 31 | Blockly.Blocks['ZE3P_led'] = { | ||
| 32 | init: function () { | ||
| 33 | this.jsonInit({ | ||
| 34 | "message0": "%1", | ||
| 35 | "args0": [ | ||
| 36 | { | ||
| 37 | "type": "field_icon_dropdown", | ||
| 38 | "name": "COLOR", | ||
| 39 | "options": [ | ||
| 40 | { | ||
| 41 | src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_coral.svg', | ||
| 42 | width: 48, | ||
| 43 | height: 48, | ||
| 44 | value: 'Red' | ||
| 45 | }, | ||
| 46 | { | ||
| 47 | src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_green.svg', | ||
| 48 | width: 48, | ||
| 49 | height: 48, | ||
| 50 | value: 'Green' | ||
| 51 | }, | ||
| 52 | { | ||
| 53 | src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_blue.svg', | ||
| 54 | width: 48, | ||
| 55 | height: 48, | ||
| 56 | value: 'Blue' | ||
| 57 | }, | ||
| 58 | { | ||
| 59 | src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_orange.svg', | ||
| 60 | width: 48, | ||
| 61 | height: 48, | ||
| 62 | value: 'Orange' | ||
| 63 | }, | ||
| 64 | { | ||
| 65 | src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_yellow.svg', | ||
| 66 | width: 48, | ||
| 67 | height: 48, | ||
| 68 | value: 'Yellow' | ||
| 69 | }, | ||
| 70 | { | ||
| 71 | src: Blockly.mainWorkspace.options.pathToMedia + 'icons/set-led_white.svg', | ||
| 72 | width: 48, | ||
| 73 | height: 48, | ||
| 74 | value: 'White' | ||
| 75 | }, | ||
| 76 | ], | ||
| 77 | } | ||
| 78 | ], | ||
| 79 | "outputShape": Blockly.OUTPUT_SHAPE_ROUND, | ||
| 80 | "output": "String", | ||
| 81 | "extensions": ["colours_looks"] | ||
| 82 | }); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | // ZE3P LED显示颜色 | ||
| 87 | Blockly.Blocks['ZE3P_led_set_color'] = { | ||
| 88 | init: function () { | ||
| 89 | this.jsonInit({ | ||
| 90 | "message0": "%1%2", | ||
| 91 | "args0": [ | ||
| 92 | { | ||
| 93 | "type": "field_image", | ||
| 94 | "src": Blockly.mainWorkspace.options.pathToMedia + "/extensions/ZE3P.png", | ||
| 95 | "width": 24, | ||
| 96 | "height": 24 | ||
| 97 | }, | ||
| 98 | { | ||
| 99 | "type": "field_vertical_separator" | ||
| 100 | } | ||
| 101 | ], | ||
| 102 | "message1": "设置彩灯 %1 显示 %2 ", | ||
| 103 | "args1": [ | ||
| 104 | { | ||
| 105 | "type": "field_pin_dropdown", | ||
| 106 | "name": "INTERFACE", | ||
| 107 | "options": Blockly.Blocks.ZE3PInterfaceOptions, | ||
| 108 | }, | ||
| 109 | { | ||
| 110 | "type": "input_value", | ||
| 111 | "name": "COLOR", | ||
| 112 | } | ||
| 113 | ], | ||
| 114 | "category": Blockly.Categories.looks, | ||
| 115 | "extensions": ["colours_looks", "shape_statement"] | ||
| 116 | }); | ||
| 117 | } | ||
| 118 | }; | ||
| 119 | |||
| 120 | // LED颜色 | ||
| 121 | Blockly.Python['ZE3P_led'] = function (block) { | ||
| 122 | let color = block.getFieldValue('COLOR') || 0; | ||
| 123 | const code = "LedColor." + color; | ||
| 124 | return [code, Blockly.Python.ORDER_ATOMIC]; | ||
| 125 | }; | ||
| 126 | |||
| 127 | // LED显示颜色 | ||
| 128 | Blockly.Python['ZE3P_led_set_color'] = function (block) { | ||
| 129 | const pin = block.getFieldValue('INTERFACE') || ""; | ||
| 130 | const color = Blockly.Python.valueToCode(block, 'COLOR', Blockly.Python.ORDER_ATOMIC) || ""; | ||
| 131 | return `led.set_color(Interface.${pin}, ${color})\n`; | ||
| 132 | }; | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
sounds/c4.m4a
0 → 100644
No preview for this file type
sounds/c5.m4a
0 → 100644
No preview for this file type
sounds/d4.m4a
0 → 100644
No preview for this file type
sounds/e4.m4a
0 → 100644
No preview for this file type
sounds/f4.m4a
0 → 100644
No preview for this file type
sounds/g4.m4a
0 → 100644
No preview for this file type
styles/index.css
0 → 100644
| 1 | main { | ||
| 2 | width: 400px; | ||
| 3 | position: relative; | ||
| 4 | margin: 0 auto; | ||
| 5 | overflow: hidden; | ||
| 6 | height: 600px; | ||
| 7 | } | ||
| 8 | |||
| 9 | header { | ||
| 10 | background-color: green; | ||
| 11 | width: 100%; | ||
| 12 | } | ||
| 13 | |||
| 14 | h1 { | ||
| 15 | width: 400px; | ||
| 16 | position: relative; | ||
| 17 | margin: 0 auto; | ||
| 18 | color: #fff; | ||
| 19 | font-size: 1.8em; | ||
| 20 | line-height: 2.4em; | ||
| 21 | } | ||
| 22 | |||
| 23 | .mode-edit, | ||
| 24 | .mode-maker, | ||
| 25 | .mode-blockly { | ||
| 26 | display: none; | ||
| 27 | } | ||
| 28 | |||
| 29 | [mode='maker'] .mode-maker, | ||
| 30 | [mode='edit'] .mode-edit, | ||
| 31 | [mode='blockly'] .mode-blockly { | ||
| 32 | display: block; | ||
| 33 | } | ||
| 34 | |||
| 35 | .blockly-editor { | ||
| 36 | position: absolute; | ||
| 37 | top: 64px; | ||
| 38 | left: -400px; | ||
| 39 | transition: left 0.4s; | ||
| 40 | height: 460px; | ||
| 41 | width: 400px; | ||
| 42 | background-color: #eee; | ||
| 43 | } | ||
| 44 | |||
| 45 | [mode='blockly'] .blockly-editor { | ||
| 46 | left: 0; | ||
| 47 | } | ||
| 48 | |||
| 49 | .maker { | ||
| 50 | display: flex; | ||
| 51 | flex-flow: column; | ||
| 52 | justify-content: space-between; | ||
| 53 | height: 460px; | ||
| 54 | width: 400px; | ||
| 55 | } | ||
| 56 | |||
| 57 | .maker > div { | ||
| 58 | display: flex; | ||
| 59 | justify-content: space-between; | ||
| 60 | } | ||
| 61 | |||
| 62 | .button { | ||
| 63 | width: 120px; | ||
| 64 | height: 140px; | ||
| 65 | color: #fff; | ||
| 66 | font-size: 3em; | ||
| 67 | text-align: center; | ||
| 68 | vertical-align: middle; | ||
| 69 | line-height: 140px; | ||
| 70 | } | ||
| 71 | |||
| 72 | .mdl-button { | ||
| 73 | margin: 1em 0; | ||
| 74 | float: right; | ||
| 75 | } |
-
Please register or sign in to post a comment