vue + blockly 自定义块、工具箱、主题

vue + blockly 自定义块、工具箱、主题

自定义块建议使用 Blockly Developer Tools 方便而且选择多样,随时生成块代码。

自定义块

  • 块由三个组件组成:
  1. 块定义对象:定义块的外观和行为,包括文本、颜色、字段和连接。
  2. 工具箱引用:对工具箱 XML 中块类型的引用,因此用户可以将其添加到工作区。
  3. 生成器函数:生成此块的代码字符串。它总是用 JavaScript 编写,即使目标语言不是 JavaScript。
<xml  style="height: 100%">
  <category name="自定义">
        <block type="custom_text_block"></block>
    </category>
</xml>

注意block type 为 custom_text_block

  • 初始化 custom_text_block 块
initCustomTectBlock () {
  Blockly.Blocks['custom_text_block'] = {
     init: function() {
       this.appendDummyInput()
           .appendField(new Blockly.FieldLabelSerializable("名称"), "TEXT_NAME")
           .appendField(new Blockly.FieldTextInput("张三丰"), "TEXT_INPUT");
       this.setOutput(true, null);
       this.setColour(105);
       this.setTooltip("");
       this.setHelpUrl("");
     }
   };
 }

代码直接复制开发工具中对应的javascript 代码即可
在这里插入图片描述

  • 效果如下
    在这里插入图片描述

  • 整体代码示例

<template>
  <div id="blocklyDiv" style="height: 800px; width: 100%;"></div>
</template>

<script>
  import Blockly from 'blockly';
  import * as Ch from 'blockly/msg/zh-hans';
  Blockly.setLocale(Ch);
  export default {
    data () {
      return {
        workspace: null,
        toolboxXml: `
          <xml  style="height: 100%">
               <category name="自定义">
                    <block type="custom_text_block"></block>
                </category>
            </xml>
         `
      }
    },
    mounted () {
      this.workspace = Blockly.inject('blocklyDiv', { toolbox:  this.toolboxXml});
      this.initCustomTectBlock();
    },
    methods: {
      initCustomTectBlock () {
        Blockly.Blocks['custom_text_block'] = {
          init: function() {
            this.appendDummyInput()
                .appendField(new Blockly.FieldLabelSerializable("名称"), "TEXT_NAME")
                .appendField(new Blockly.FieldTextInput("张三丰"), "TEXT_INPUT");
            this.setOutput(true, null);
            this.setColour(105);
            this.setTooltip("");
            this.setHelpUrl("");
          }
        };
      }
    }
  }
</script>

</script>

自定义主题

主题名称为 CUSTOM_THEME

  • 主题定义
customTheme () {
  Blockly.Themes.CUSTOM_THEME = Blockly.Theme.defineTheme('CUSTOM_THEME', {
    'base': Blockly.Themes.Classic,
    'categoryStyles': {
      'custom_category': {
        'colour': "#5ba5a5"                     // 工具箱颜色标识
      },
    },
    'blockStyles': {
      // 块样式目前由四个字段组成:colourPrimary、colourSecondary、colorTertiary 和 hat。
      'custom_text_blocks': {                   
        'colourPrimary': "#5ba5a5",             //块的背景色,可以用色调或十六进制值定义
        'colourSecondary':"#5ba5a5",            // 如果块是阴影块,则使用此颜色
        'colourTertiary':"#C5EAFF"              // 块的边框颜色
      }
    },
    'componentStyles': {
      'workspaceBackgroundColour': '#131313',   // 工作区背景色
      'toolboxBackgroundColour': '#2f2e2b',     // 工具箱背景色
      'toolboxForegroundColour': '#f5f5f5',     // 工具箱类别文字颜色
      'flyoutBackgroundColour': '#252526',      // 弹出背景颜色
      'flyoutForegroundColour': '#333',         // 弹出标签文本颜色
      'flyoutOpacity': 1,                       // 弹出不透明度
      'scrollbarColour': '#dcdcdc',             // 滚动条颜色
      'scrollbarOpacity': 0.4,                  // 滚动条不透明度
      'insertionMarkerColour': '#f5f5f5',       // 插入标记颜色(不接受颜色名称)
      'insertionMarkerOpacity': 0.3,            // 插入标记不透明度
      'cursorColour': '#f5f5f5',                // 键盘导航模式下显示的光标颜色
    }
  });
},

blockStyles样式定义完成需要在 Blockly.Blocks['custom_text_block']方法中加入this.setStyle("custom_text_blocks");即可显示该样式。

  • 主题引入
Blockly.inject('blocklyDiv', { toolbox:  this.toolboxXml, theme: Blockly.Themes.CUSTOM_THEME});
  • 效果如下
    根据需求定义
  • 代码示例
<template>
    <div id="blocklyDiv" style="height: 800px; width: 100%;"></div>
</template>

<script>
  import Blockly from 'blockly';
  import * as Ch from 'blockly/msg/zh-hans';
  Blockly.setLocale(Ch);
  export default {
    data () {
      return {
        workspace: null,
        toolboxXml: `
          <xml  style="height: 100%">
               <category name="自定义" categorystyle="custom_category">
                    <block type="custom_text_block"></block>
                </category>
            </xml>
         `
      }
    },
    mounted () {
      this.customTheme();
      this.workspace = Blockly.inject('blocklyDiv', { toolbox:  this.toolboxXml, theme: Blockly.Themes.CUSTOM_THEME});
      this.initCustomTectBlock();
    },
    methods: {
      initCustomTectBlock () {
        Blockly.Blocks['custom_text_block'] = {
          init: function() {
            this.appendDummyInput()
                .appendField(new Blockly.FieldLabelSerializable("名称"), "TEXT_NAME")
                .appendField(new Blockly.FieldTextInput("张三丰"), "TEXT_INPUT");
            this.setOutput(true, null);
            this.setTooltip("");
            this.setHelpUrl("");
            this.setStyle('custom_text_blocks')
          }
        };
      },
      customTheme () {
        Blockly.Themes.CUSTOM_THEME = Blockly.Theme.defineTheme('CUSTOM_THEME', {
          'base': Blockly.Themes.Classic,
          'categoryStyles': {
            'custom_category': {
              'colour': "#5ba5a5"                     // 工具箱颜色标识
            },
          },
          'blockStyles': {
          	// 块样式目前由四个字段组成:colourPrimary、colourSecondary、colorTertiary 和 hat。
            'custom_text_blocks': {                   
              'colourPrimary': "#5ba5a5",             //块的背景色,可以用色调或十六进制值定义
              'colourSecondary':"#5ba5a5",            // 如果块是阴影块,则使用此颜色
              'colourTertiary':"#C5EAFF"              // 块的边框颜色
            }
          },
          'componentStyles': {
            'workspaceBackgroundColour': '#131313',   // 工作区背景色
            'toolboxBackgroundColour': '#2f2e2b',     // 工具箱背景色
            'toolboxForegroundColour': '#f5f5f5',     // 工具箱类别文字颜色
            'flyoutBackgroundColour': '#252526',      // 弹出背景颜色
            'flyoutForegroundColour': '#333',         // 弹出标签文本颜色
            'flyoutOpacity': 1,                       // 弹出不透明度
            'scrollbarColour': '#dcdcdc',             // 滚动条颜色
            'scrollbarOpacity': 0.4,                  // 滚动条不透明度
            'insertionMarkerColour': '#f5f5f5',       // 插入标记颜色(不接受颜色名称)
            'insertionMarkerOpacity': 0.3,            // 插入标记不透明度
            'cursorColour': '#f5f5f5',                // 键盘导航模式下显示的光标颜色
          }
        });
      }
    }
  }
</script>

自定义工具箱

  • 定义工具箱
<xml  style="height: 100%">
 	<category name="创建" custom="CREATE_TYPED_VARIABLE"></category>
</xml>

注意 custom="CREATE_TYPED_VARIABLE"这是唯一标识,注册与给定键CREATE_TYPED_VARIABLE关联的回调函数,该回调函数中创建该工具箱内按钮。

  • 注册工具箱
registerToolboxCategory () {
	this.workspace.registerToolboxCategoryCallback( 'CREATE_TYPED_VARIABLE', this.createFlyout);
  	this.registerButton();
},
// 创建变量
createFlyout (workspace) {
	  let xmlList = [];
	  const button = document.createElement('button');
	  button.setAttribute('text', '添加变量块');
	  button.setAttribute('callbackKey', 'ADD_VAR_BLOCK');
	  xmlList.push(button);
	  const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace);
	  xmlList = blockList.concat(xmlList);
	  return xmlList;
},

注意 ADD_VAR_BLOCK"这是唯一标识,注册与给定键ADD_VAR_BLOCK关联的回调函数,该回调函数进一步处理需求。

  • 注册工具箱内按钮
registerButton () {
  this.workspace.registerButtonCallback( 'ADD_VAR_BLOCK', this.buttonClickCallbackEvent);
},
buttonClickCallbackEvent (e) {
  console.log(e);
},
  • 效果如下
    在这里插入图片描述

  • 示例演示

    样式请自行忽略

    通过点击工具箱内按钮并弹框且添加变量

    效果图1:
    点击左侧添加变量块显示弹框
    效果图2:输入123 点击添加生成左侧效果

  • 示例演示完整代码

<template>
  <div class="blockly-contant">
    <div id="blocklyDiv" style="height: 800px; width: 100%;"></div>
    <el-dialog
        title="添加块"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
    >
      <el-form label-position="top" label-width="80px" :model="formLabelAlign">
        <el-form-item label="变量名">
          <el-input v-model="formLabelAlign.name"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addBlockEvent">添 加</el-button>
      </span>
    </el-dialog>
  </div>

</template>

<script>
  import Blockly from 'blockly';
  import * as Ch from 'blockly/msg/zh-hans';
  Blockly.setLocale(Ch);
  export default {
    data () {
      return {
        workspace: null,
        dialogVisible: false,
        toolboxXml: `
          <xml  style="height: 100%">
             <category name="创建" custom="CREATE_TYPED_VARIABLE"></category>
          </xml>
         `,
        formLabelAlign: {
          name: ''
        }
      }
    },
    mounted () {
      this.workspace = Blockly.inject('blocklyDiv', { toolbox:  this.toolboxXml});
      this.registerToolboxCategory();

    },
    methods: {
      // 注册工具箱
      registerToolboxCategory () {
        this.workspace.registerToolboxCategoryCallback( 'CREATE_TYPED_VARIABLE', this.createFlyout);
        this.registerButton();
      },
      // 注册工具箱内按钮
      registerButton () {
        this.workspace.registerButtonCallback( 'ADD_VAR_BLOCK', this.buttonClickCallbackEvent);
      },
      // 工具箱内按钮生成
      createFlyout (workspace) {
        let xmlList = [];
        const button = document.createElement('button');
        button.setAttribute('text', '添加变量块');
        button.setAttribute('callbackKey', 'ADD_VAR_BLOCK');
        xmlList.push(button);
        const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace);
        xmlList = blockList.concat(xmlList);
        return xmlList;
      },
      // 按钮点击事件
      buttonClickCallbackEvent (e) {
        this.dialogVisible = true;
      },
      // 点击添加
      addBlockEvent () {
        let name = this.formLabelAlign.name;
        this.createVariable(name)
      },
      // 创建变量块
      createVariable (name) {
        let [text, type, msg] = [this.getValidInput(name), '', ''];
        if (text) {
          const existing = Blockly.Variables.nameUsedWithAnyType(text, this.workspace);
          if (existing) {
            if (existing.type === type) {
              msg = Blockly.Msg['VARIABLE_ALREADY_EXISTS'].replace( '%1', existing.name);
            } else {
              msg = Blockly.Msg['VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE'];
              msg = msg.replace('%1', existing.name).replace('%2',  this.getDisplayName(existing.type));
            }
            this.$message({message: msg, type: 'warning'})
          } else {
            this.workspace.createVariable(text, type);
          }
        }
        if (!msg) {
          this.workspace.createVariable(text, type);
          this.dialogVisible = false;
        }
      },
      // 类型判断
      getDisplayName(type) {
        for (let i = 0; i < this.types_.length; i++) {
          const typeNames = this.types_[i];
          if (type === typeNames[1]) {
            return typeNames[0];
          }
        }
        return '';
      },
      // 获取名称
      getValidInput(newVar) {
        if (newVar) {
          newVar = newVar.replace(/[\s\xa0]+/g, ' ').trim();
          if (newVar === Blockly.Msg['RENAME_VARIABLE'] ||
              newVar === Blockly.Msg['NEW_VARIABLE']) {
            newVar = null;
          }
        }
        return newVar;
      },

    }
  }
</script>
<style>
  .blockly-contant /deep/ .el-dialog {
    text-align: left !important;
  }
</style>
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值