likes
comments
collection
share

Scratch3.0 二次开发——支持隐藏积木选择区域

作者站长头像
站长
· 阅读数 56

概述

这次核心介绍如何修改 scratch-blocks 库 使其支持隐藏积木选择区域的功能

需求分析

Scratch3.0 二次开发——支持隐藏积木选择区域

如上图,官方 scratch 积木选择区域(flyout)是没办法伸缩或者隐藏的,这样,如果我们把整个 PC 界面移植到平板上的话,屏幕相对较小的情况下,积木编辑区域就显得很小。故,原始需求:积木选择区域(flyout)实现隐藏/显示功能,从而拓展积木编辑区域的大小。

另外,对于常规情况下,积木选择区域(flyout)默认显示会比较方便一点,只有当有需要隐藏时再通过某个按钮触发隐藏。

还有,要控制好可删除区域,如下图:

  • Scratch3.0 二次开发——支持隐藏积木选择区域
  • Scratch3.0 二次开发——支持隐藏积木选择区域

前置准备

项目构建环境依赖

启动本地服务

scratch-blocks 库中自带有测试用的页面。最好先安装 http-server,相对方便在本地启动一个 http 服务器。安装好后,在 scratch-blocks 项目的根目录下执行 http-server 就可以启动一个本地服务,直接访问 http://127.0.0.1:8080/tests/vertical_playground.html 就可以访问测试页面,如下图:

Scratch3.0 二次开发——支持隐藏积木选择区域

npm link

改好代码后,在 scratch-blocks 项目的根目录下执行 npm link 命令,然后在 demo-scratch-gui 项目根目录下执行npm link scratch-blocks 命令就可以将 demo-scratch-gui 中安装的远程 scratch-blocks 库,换成是本地的。

详细可以自行百度一下 npm link 的用法 O(∩_∩)O哈哈~

实现细节

思路

flyout 的 隐藏/显示 功能,最直接的就是去到 scratch-blocks 项目的源码文件中找线索,看有没有现成的接口:

  • flyout_base.js
    • flyout 的基础类,其它类型的 flyout 都是继承自这个类
  • flyout_vertical.js
    • 垂直布局 flyout 的类,scratch 有垂直和水平布局两种积木编辑方式(用得比较多是垂直,后续也只在垂直布局的基础上修改。对于水平布局,有需要的朋友可以摸索摸索一下)
      • 垂直布局:
        • Scratch3.0 二次开发——支持隐藏积木选择区域
      • 水平布局:
        • Scratch3.0 二次开发——支持隐藏积木选择区域

有一说一,虽然官方 scratch 几乎是 0 文档,但系统里面的接口还是有预留了挺多的,有事没事多刷刷源码,需要用到时可能会有“灵光一闪”的微妙感觉~

flyout_base.js - hide 函数,可以满足我们这次需求。但是呢,不能直接上,实现过程还是有点坑,等在下娓娓道来~

一开始非常天真的以为发现了好东西——flyout_base.js - autoClose 属性。这个属性,默认值是 false,如果设置成 true,则在把积木从 flyout 区域拖到编辑区域时,flyout 会自动隐藏起来。

打算搭配 flyout_base.js - hide 函数flyout_base.js - autoClose 属性实现这次需求,但最终做出来后会出现以下几点坑:

  1. scratch-blocks 项目报错,初步判断,下面错误是指在加载时少了一些数组元素,导致没法正确读取内容
    • Scratch3.0 二次开发——支持隐藏积木选择区域
    • 基本可以定位到是因为使用了 autoClose 属性后,隐藏了 flyout 导致的问题
  2. 角色、背景两种类型的 target 切换时,flyout 没有正确显示。本来下图这种类型的积木只会在处于背景 target 时才会出现,当切换成角色 target 时就会换成运动类型的积木。结果使用了这套方案后,没法正确切换。
    • Scratch3.0 二次开发——支持隐藏积木选择区域
  3. flyout 中,可勾选类型的积木没法勾选
    • Scratch3.0 二次开发——支持隐藏积木选择区域

个人感觉,应该是 autoClose 属性在源码里面有坑还没解决,导致了一串连环 bug,最终放弃了这套方案,改成了下一小节中的方案

源代码

上文提到,autoClose 属性 有坑,但 hide 函数 是没问题的。接下来我们会基于 hide 函数展开

修改总览

文中没有贴完所有源码,有需要的朋友麻烦上 scratch-blocks github 库 自取,有很多关键性的注释也附在源码上面,记得看看中文类型的注释(英文的注释是官方的,中文的注释都是我自己加上去的)

实现这次需求修改的地方如下:

scratch-blocks 的 core/toolbox.js 文件中:

// 相关变量:
this.isHideFlyout_ = false;
this.triggerIcon_ = null;

// 相关函数;
init
createTrigger
unfoldTrigger
foldTrigger
getIsHideFlyout
setIsHideFlyout
triggerIsHideFlyout
populate_
getClientRect
setSelectedItem
setSelectedItemForPopulate

scratch-blocks 的 core/css.js 文件中,新增了 .blocklyToolboxTrigger.blocklyToolboxTriggerIcon 两个样式 class,用来处理触发按钮

Scratch3.0 二次开发——支持隐藏积木选择区域

另外还在 scratch-blocks 的 media 目录 下增加了两份资源文件:hide.svgshow.svg

创建隐藏/显示触发器

上文总览中提及到的:

this.isHideFlyout_ = false;
this.triggerIcon_ = null;

createTrigger
unfoldTrigger
foldTrigger
getIsHideFlyout
setIsHideFlyout
triggerIsHideFlyout

这些变量和函数都是用来创建并保存隐藏/显示触发器用的

初始化

上文总览中提及到的:init 函数,是在 scratch-blocks 的 core/toolbox.js 中对隐藏/显示触发器进行初始化,包括以下内容:

  • 创建并保存对象(调用“创建隐藏/显示触发器”中的函数)
  • 创建点击事件

边边角角

上文总览中提及到的:

populate_
getClientRect
setSelectedItem
setSelectedItemForPopulate

这几个函数都是用来处理边界情况,虽然是边边角角的情况,但对于整个实现来说至关重要,最好还是看看源码里面的中文注释 O(∩_∩)O哈哈~

至此,就完成了这一次的需求实现 ✿✿ヽ(°▽°)ノ✿

转载自:https://juejin.cn/post/7129289569886961677
评论
请登录