[blockly]自定义工具栏样式

198 阅读2分钟

前言

因为在网上发现blockly相关的帖子太少,或者就是因为版本太老,无法正常使用,所有在这里把这段时间遇到的问题都给整理一下分享出来 效果: 在这里插入图片描述

版本

使用的是blockly 12.1.0版本

操作

首先要创建一个ToolboxCategory 类

我们可以在里面来定义我们的相关的操作 constructor() 构造函数,继承父类即可,一般不需要修改 init() 类别初始化后自动调用,用于设置样式、DOM 操作 addColourBorder_() Blockly 初始化颜色时调用,控制分类背景色或边框色 setSelected() 类别选中/取消选中时自动调用,控制选中样式 更多的可以参考文档

我这里是这样定义的

class CustomToolboxCategory extends Blockly.ToolboxCategory {
  constructor(categoryDef, toolbox, opt_parent) {
    super(categoryDef, toolbox, opt_parent)
  }
  // 初始化
  init() {
    super.init();

    if (this.rowDiv_) {
      this.rowDiv_.style.margin = '8px 8px';        // 上下间距
      this.rowDiv_.style.borderRadius = '6px';    // 圆角
      this.rowDiv_.style.fontSize = '14px';       // 字体大小
      this.rowDiv_.style.height = '50px'
      // 字体颜色
      var labelDom = this.rowDiv_.getElementsByClassName('blocklyToolboxCategoryLabel')[0];
      labelDom.style.color = 'white';
      labelDom.style.fontWeight = 'bold';
      this.rowDiv_.style.display = 'flex';
      this.rowDiv_.style.alignItems = 'center';
      this.rowDiv_.style.justifyContent = 'center';
    }
  }
  //Blockly 初始化颜色时调用
  addColourBorder_(colour) {
    this.rowDiv_.style.backgroundColor = colour;
  }
  /** @override */
  // 类别选中/取消选中时自动调用
  setSelected(isSelected) {
    var labelDom = this.rowDiv_.getElementsByClassName('blocklyToolboxCategoryLabel')[0];
    if (isSelected) {
      //选中状态
      // 把DIV背景设置为白色
      this.rowDiv_.style.backgroundColor = 'white';
      labelDom.style.color = this.colour_;
    } else {
      this.rowDiv_.style.backgroundColor = this.colour_;
      // 设置文本颜色为白色
      labelDom.style.color = 'white';
    }
  }
}

创建完成ToolboxCategory 类之后,我们要对这个类进行注册

// 函数介绍
Blockly.registry.register(
  type,     // 注册的类型,比如 TOOLBOX_ITEM 表示工具箱元素
  name,     // 注册的名称,用于标识,比如 'category'
  classRef, // 自定义的类,比如你要用来替代默认 Category 的类
  optOverride // 可选,是否覆盖默认注册(通常设置为 true)
)
// 我的函数
// 2. 注册到 Blockly 注册表中
Blockly.registry.register(
  Blockly.registry.Type.TOOLBOX_ITEM,
  'category', // 这里要记住
  CustomToolboxCategory,// ToolboxCategory 类名
  true
)

我们注册完成之后,就要开始引用他了 我们需要在工具箱之中使用category 要注意这一句 kind: 'category',这是我们是否可以正确加载刚刚创建的ToolboxCategory 类关键

const toolbox = {
  kind: 'categoryToolbox',
  contents: [
    {
      kind: 'category',
      name: '逻辑',
      colour: '#5CA65C',
      contents: [
        {
          kind: 'block',
          type: 'controls_if'
        },
        {
          kind: 'block',
          type: 'logic_compare'
        }
      ]
    },
    {
      kind: 'category',
      name: '数学',
      colour: '#5C81A6',
      contents: [
        {
          kind: 'block',
          type: 'math_number'
        },
        {
          kind: 'block',
          type: 'math_arithmetic'
        }
      ]
    }
  ]
}

然后初始化的时候带上这个东西,就大功告成了

  Blockly.inject(blocklyDiv.value, {
    toolbox,
    renderer: 'geras',
    theme: Blockly.Themes.Classic
  })

完整代码

<template>
  <div>
    <div ref="blocklyDiv" style="height: 600px; width: 100%; border: 1px solid #ccc;"></div>
  </div>
</template>

<script setup>
import { onMounted, ref } from 'vue'
import * as Blockly from 'blockly'

// 1. 自定义 ToolboxCategory 类
class CustomToolboxCategory extends Blockly.ToolboxCategory {
  constructor(categoryDef, toolbox, opt_parent) {
    super(categoryDef, toolbox, opt_parent)
  }

  init() {
    super.init();

    if (this.rowDiv_) {
      this.rowDiv_.style.margin = '8px 8px';        // 上下间距
      this.rowDiv_.style.borderRadius = '6px';    // 圆角
      this.rowDiv_.style.fontSize = '14px';       // 字体大小
      this.rowDiv_.style.height = '50px'
      // 字体颜色
      var labelDom = this.rowDiv_.getElementsByClassName('blocklyToolboxCategoryLabel')[0];
      labelDom.style.color = 'white';
      labelDom.style.fontWeight = 'bold';
      this.rowDiv_.style.display = 'flex';
      this.rowDiv_.style.alignItems = 'center';
      this.rowDiv_.style.justifyContent = 'center';
    }
  }
  addColourBorder_(colour) {
    this.rowDiv_.style.backgroundColor = colour;
  }
  /** @override */
  setSelected(isSelected) {
    var labelDom = this.rowDiv_.getElementsByClassName('blocklyToolboxCategoryLabel')[0];
    if (isSelected) {
      //选中状态
      // 把DIV背景设置为白色
      this.rowDiv_.style.backgroundColor = 'white';
      labelDom.style.color = this.colour_;
    } else {
      this.rowDiv_.style.backgroundColor = this.colour_;
      // 设置文本颜色为白色
      labelDom.style.color = 'white';
    }
  }
}

// 2. 注册到 Blockly 注册表中
Blockly.registry.register(
  Blockly.registry.Type.TOOLBOX_ITEM,
  'category',
  CustomToolboxCategory,// 修改工具栏的类
  true
)

const blocklyDiv = ref()
const toolbox = {
  kind: 'categoryToolbox',
  contents: [
    {
      kind: 'category',
      name: '逻辑',
      colour: '#5CA65C',
      contents: [
        {
          kind: 'block',
          type: 'controls_if'
        },
        {
          kind: 'block',
          type: 'logic_compare'
        }
      ]
    },
    {
      kind: 'category',
      name: '数学',
      colour: '#5C81A6',
      contents: [
        {
          kind: 'block',
          type: 'math_number'
        },
        {
          kind: 'block',
          type: 'math_arithmetic'
        }
      ]
    }
  ]
}

// 4. 初始化 Blockly
onMounted(() => {
  Blockly.inject(blocklyDiv.value, {
    toolbox,
    renderer: 'geras',
    theme: Blockly.Themes.Classic
  })
})
</script>