0.0.16 • Published 5 years ago
@ng-blockly/custom v0.0.16
@ng-blockly/custom
为当前项目做的个性化定制,依赖于@ng-blockly/blockly包
例如:修改卡槽形状、修改toolbox样式、toolbox目录下的block为异步加载、下拉列表的背景色与sourceBlock的颜色相同、自定义支持模糊查询的单选/多选下拉列表、自定义的逻辑判断表达式、自定义主题 等等
安装
Install from npm repository:
npm install @ng-blockly/blockly --save && npm install @ng-blockly/custom --save
or you can: ng add @ng-blockly/custom, this will install @ng-blockly/custom, @ng-blockly/blockly and generate a custom blockly template.
只需要在AppModule中导入NgCustomBlocklyModule一次。 推荐使用自定义主题,或者使用内置的主题,new DarkTheme().DarkTheme
public config: NgBlocklyConfig = {
theme: new DarkTheme().DarkTheme,
scrollbars: true, // 工作区域可滚动
trashcan: true, // 显示或隐藏垃圾桶
media: '/assets/blockly/media/', // blockly媒体路径---默认路径访问不到,需要翻墙
};
样式覆盖
.blocklyToolboxDiv {
background-color: #eee;
}
.blocklyHidden {
display: none !important;
}
.blocklyTreeRow {
height: 40px;
display: flex;
align-items: center;
margin-bottom: 0;
padding-right: 16px;
}
// 目录展开
.app-blockly-expanded {
i {
transform: rotateX(180deg);
transition: all .3s;
}
}
// 目录闭合
.app-blockly-collapsed {
i {
transform: rotateX(0deg);
transition: all .3s;
}
}
.app-blockly-selected {
i {
color: #fff;
}
}
// flyout背景色
.blocklyFlyoutBackground {
fill: #4b4949!important;
}
// flyout中label的颜色
.blocklyFlyoutLabelText {
fill: #fff;
}
// mutator图标的背景色
.blocklyIconShape {
fill: #aaa;
}
.blocklyDropDownDiv {
.goog-menuitem {
color: #fff;
&:hover {
background: #4b4949;
opacity: .4;
}
}
.goog-menuitem-content {
color: unset;
}
}
// 修改浏览器滚动条默认样式
::-webkit-scrollbar {
width: 0.25rem;
height: 0.25rem;
// background-image: linear-gradient(135deg, #1DE9B6 0%, rgba(8, 196, 219, 0.5) 72%, rgba(0, 182, 234, 0.3) 100%);
}
::-webkit-scrollbar-track {
border-radius: 0;
}
::-webkit-scrollbar-thumb {
border-radius: 0;
background: #ccc;
transition: all .2s;
border-radius: 0.25rem;
}
::-webkit-scrollbar-thumb:hover {
background-color: rgba(95, 95, 95, 0.7);
}
// json格式化展示
.string { color: green; }
.number { color: darkorange; }
.boolean { color: blue; }
.null { color: magenta; }
.key { color: red; }
:focus {
outline-width: 0;
}
// blockly ul
.app-blockly-ul {
display: flex;
height: 100%;
padding-inline-start: 0;
margin-bottom: 0;
background: #fff;
overflow-x: scroll;
overflow-y: hidden;
&::-webkit-scrollbar {
width: 0;
height: 0;
}
}
.app-blockly-li {
display: flex;
height: 100%;
flex: 0 0 auto;
list-style-type:none;
background: #fafafa;
color: rgba(0,0,0,.65);
border-left: 1px solid #e8e8e8;
border-right: 1px solid #e8e8e8;
margin-right: 4px;
&:last-child {
margin-right: 0;
border: none;
}
input {
height: 100%;
background: none;
border: none;
width: .75em;
&:focus {
outline-width: 0;
}
}
}
异步加载目录
即异步请求目录的数据,再将其转化为blockly需要的xml结构,转化为xml过程中可以给目录指定{commonUrl: string, activeUrl: string},分别代表目录在未选中,和选中下显示的图标。 将目录的code值写入xml字符串中,以便点击目录时,可以获取到code值,从而根据code值发送异步请求。
jsonToXml(categoryes: any[] = []) {
for (let i = 0, len = categoryes.length ; i < len; i++) {
if (categoryes[i].name) {
(Blockly.tree.BaseNode.prototype.categoriesInObject || {})[categoryes[i].name] = {
commonUrl: categoryes[i].commonUrl,
activeUrl: categoryes[i].activeUrl
};
}
this.categoriesInString += `<category code="${categoryes[i].code}" name="${categoryes[i].name}" colour="${categoryes[i].color || generateColor()}">`;
const children = categoryes[i].tagClassChildren || [];
if (children.length > 0) {
this.jsonToXml(children);
}
this.categoriesInString += '</category>';
}
}
toolbox目录下的block为异步加载
自行实现Blockly.Toolbox.prototype.loadVariable方法,该方法在点击目录中某一项时触发。
@ViewChild(NgBlocklyComponent, { static: true }) workspace: NgBlocklyComponent;
Blockly.Toolbox.prototype.loadVariable = (node) => {
const categoryColour = node.hexColour;
const categoryName = node.content_;
const categoryCode = node.code;
if (categoryCode && node.blocks.length === 0) {
// 异步加载blocks(此处为伪代码,思路是发起异步请求,拿到结果后,生成flyout中的xml表示,然后调用refreshSelection)
.......
const treeControl = this.workspace.workspace.getToolbox().tree_; // 每次调用renderTree都会生成新的TreeControl
const preSelectedItem = treeControl.getSelectedItem();
if (rsp[0]) {
const xml = Blockly.Xml.textToDom(`<xml>
...........
</xml>`);
preSelectedItem.blocks.push(...xml.children);
this.workspace.workspace.getToolbox().refreshSelection();
}
}
};
AndOrBlock BlocklySelfAddMutator
new AndOrBlock('logic_block_self_add', null, new BlocklySelfAddMutator('blockly_self_add_mutator', ['block_self_boolean']))
ValuesDropDownBlock SelfSelectorField
支持模糊查询及单选/多选模式的下拉列表
new ValuesDropDownBlock(dropdownBlockType, null, null, extensionName, code, categoryColour);
Blockly.Extensions.register(extensionName,
function() {
this.getInput('INPUT')
**SelfSelectorField的第一个参数是下拉列表的值[['男', '1'], ['女', '0']],第二个参数为当前选中的值,第四个参数为是否是多选模式**
.appendField(new Blockly.SelfSelectorField(labels, fieldValue, this, false), 'NAME');
});
memory recovery
组件卸载时,一定要注销使用过的自定义的filed或者extensions,以免内存泄漏
@ViewChild(NgBlocklyComponent, { static: true }) workspace: NgBlocklyComponent;
...
...
Blockly.Extensions.unregister('blockly_self_add_mutator');
Blockly.fieldRegistry.unregister('self-selector');
Blockly.tree.BaseNode.prototype.categoriesInObject = null;
Blockly.utils.IdGenerator.nextId_ = 0;
this.workspace.workspace.dispose();
联系我
目前,该项目不是开源的,如果有问题可以联系我,xiaoxiang930601@163.com