模拟Scratch的可视化脚本编辑器(二)

本次以Markdown流程图Flow为例,来说明Block扩展方法。

Created with Raphaël 2.2.0 开始 程序 条件 程序 程序 结束 程序 yes no

流程图主要有6种Block

#开始 start
st=>start: 开始

#结束 end
e=>end: 结束

#普通操作块 opration
op1=>opration: 第一个操作块
op2=>opration: 第二个操作块

#判断块 condition
cond1=>condition: 第一个判断
cond2=>condition: 第二个判断

#输入输出块 inputoutput
io1=>inputoutput: 输入输出块1
io2=>inputoutput: 输入输出块2

#子任务块
sub1=>subroutine: 子任务1
sub2=>subroutine: 子任务2

根据每个Block的格式,编写描述文件,在项目目录/client/src/scratch/blockDefs/packages目录下新建一个markdown目录,在目录中创建index.js和flow.js。
index.js文件内容

import flow from './flow'
let blocks = []
blocks = blocks.concat(flow)
export default blocks

flow.js文件中编写Block定义,输出为一个数组。以start单元为例, 先根据start语法规则** [模块名称]=start: [标题文字]:>[超链接]**,将语法中的主要数据项转变为section定义 START [index] TAG [模块文字] URL [超链接], 其中index用于Block重用,比如流程图中某个单元Block需要在多个地方中出现,使用Scratch的表现方式只能复制多个Block,使用index表示具有相同index的多个Block其实是同一个Block,只需给第一个出现的Block填写属性即可,其他Block无需重复设置属性信息。
section定义好之后,就可以编写Block定义文件来,其描述信息如下:


    {
        id: 'mk-flow-start',
        type: 'action',   // 
        shape: 'slot',
        category: 'presentation',
        draggable: true,  // 允许拖放
        state: {
          data: {
            sections: [  
              { 
                type: 'text',
                text: 'START'
              },
              {  // index
                type: 'argument',
                datatype: 'number'
              },
              {
                type: 'text',
                text: 'TAG'
              },
              { // 模块文字
                type: 'argument',
                datatype: 'string',
                data: {
                  value: '开始'
                }
              },
              {
                type: 'text',
                text: 'URL'
              },
              { // 超链接
                type: 'argument',
                datatype: 'string'
              }
            ]
          }
        }

写好定义文件后,修改一下包配置文件(文件位于项目目录/client/src/scratch/blockDefs/index.js), 在其中引入新建的markdown包即可。

import categories from './categories'
// 加载Block包
import base from './packages/base'
import chinese from './packages/chinese'
import ml from './packages/ml'
import markdown from './packages/markdown'

export default {
  categories: categories,
  packages: [base, chinese, ml, markdown]
}

进入编辑器,就可以看见start模块(见下图)。Block的颜色是根据category字段来定义,可以修改改字段来改变颜色方案。具体字段可以查看项目目录/client/src/scratch/blockDefs/categories.js文件

在这里插入图片描述

同理,将其余5个Block定义编写好(如图)

在这里插入图片描述

到目前为止,只能使用编辑器进行流程图的设计,但是并没有生产实际的flow代码,需要继续在flow.js文件中编写导出函数。另外为了方便使用,额外创建来一个流程图Block,将导出功能放在它的上下文菜单中。每次创建流程图时,始终以这个Block作为头部Block来创建

在这里插入图片描述

在Block定义中添加export属性,是一个数组,可以提供多种导出功能,并为导出功能定义上下文菜单信息,其格式如下:

    export: [
          {
            menuItem: true, // 是否添加到菜单上
            menuName: '导出为MarkDown',   // 菜单上显示文字
            fmt: 'markdown',   // 导出格式
            ext: '.md',  // 文件扩展名
            action: function() {  // 导出功能实现函数
              const fmt = 'markdown'
              start = this.nextBlock()
              if (start.protoId() !== 'mk-flow-start') {
                logger.warn('MarkDown Export: first block is not <start> Block')
              }
              ...
            }
         }
      ]

在action函数中,this就是当前Block自己,可以通过this.nextBlock()来获取下游Block,调用每个Block的export(fmt)来得到Block自身生成的代码片段,然后在根据序列结构拼接为完整的代码。例如start单元生成的代码片段为:

   st8=>start: 开始:> https://www.baidu.com

补充好export定义后,再次进入编辑器,在流程图Block上点击右键,就可以看到自定义的菜单项了。由于导出代码比较长,可自行查看flow.js文件。
在这里插入图片描述

接下来,设计一个简单的流程图,测试下导出功能。

在这里插入图片描述

点击“导出为Markdown”,显示弹出菜单,输入一个文件名,点击确定,会将生成的文件下载到本地。
在这里插入图片描述

下面为导出的代码为,其真实显示图案就是文章开头显示的流程图:

   st8=>start: 开始:> https://www.baidu.com
   op9=>operation: 程序
   c10=>condition: 条件
   op11=>operation: 程序
   e12=>end: 结束
   op13=>operation: 程序
   op14=>operation: 程序
   st8->op9(bottom)->c10
   c10(no)->op14(bottom)->op11
   c10(yes, right)->op13(bottom)->op11
   op11(bottom)->e12
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值