blockly研究(一)自定义菜单栏

由于最近一直比较忙,所以没有更新博客

由于博主做的项目不需要舞台与模拟器的概念,所以在技术选型上也就没有选择s3等其他的图形化编程框架

今天给大家带来的是blockly自定义左侧菜单栏、以及交互效果如何去加

首先先看一下效果:修改之前:blockly研究(一)自定义菜单栏_第1张图片  修改之后:  blockly研究(一)自定义菜单栏_第2张图片

 

首先我们得了解blockly是什么?以及他提供的一些api、怎么用?

谷歌blockly官网

blockly源码

某书上看到的一个api入门介绍

看了上面做这几个之后你就能清楚的解决上面提的问题(这部分自己看,就不详细介绍了,如果有不懂得可以留言,一起研究)

接下来就可以说这篇博客要做的事了

首先看一下dom结构

blockly研究(一)自定义菜单栏_第3张图片

发现他自己生成的就是圈起来的这样的结构,好了现在的思路就很简单了,源代码的结构与咱们的结构就只差一个icon,所以就想到既然他能生成这样的一个dom结构,我们也就可以随意的生成咱们所需要的dom,比如img元素、当然你也可以随意生成dom然后给背景图

于是大致思路就是找到源码生成左侧dom的关键代码,生成我们需要的dom

so:

goog.ui.tree.BaseNode.prototype.getLabelSafeHtml = function() {
    var a = goog.html.SafeHtml.create("span", { "class": this.config_.cssItemLabel, title: this.getToolTip() || null }, this.getSafeHtml());
    return goog.html.SafeHtml.concat(a, goog.html.SafeHtml.create("span", {}, this.getAfterLabelSafeHtml()))
};

这个方法就是生成咱们刚才圈起来的span的,哈哈哈 你肯定想到了咱们当然可以利用这个来创建一个img标签

so:

// add 生成img标签解析器
goog.ui.tree.BaseNode.prototype.getLabelSafeself = function() {
    var a = goog.html.SafeHtml.create("image", { "class": this.config_.cssItemLabel, title: this.getToolTip(), "src": this.getCategoryImg().trueUrl || null,"backgroundData":JSON.stringify(this.getCategoryImg()) });
    return goog.html.SafeHtml.concat(a, '')
};

上面这段代码做的事就是生成了一个image标签,并给了一个src属性

其中这个this.getCategoryImg()是我自己给每个类别匹配相应icon的方法,代码如下:

// 获取图片类别
goog.ui.tree.BaseNode.prototype.getCategoryImg = function() {
    let style_pt = this.html_.privateDoNotAccessOrElseSafeHtmlWrappedValue_,
        trueUrl = '',clickUrl='';
    if (style_pt) {
        switch (style_pt) {
            case "逻辑":
                trueUrl = "http://pic38.nipic.com/20140225/2531170_214014788000_2.jpg";
                clickUrl= "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                break;
            case "If":
                trueUrl = "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                clickUrl= "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                break;
            case "Boolean":
                trueUrl = "http://img17.3lian.com/d/file/201702/14/3d1d78481dbe5db4802f4b1eb548f365.jpg";
                clickUrl= "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                break;
                // pt case start
            case "变量":
                trueUrl = "block/img/variable.png";
                clickUrl= "block/img/variable_click.png";
                break;
            case "运动":
                trueUrl = "block/img/movement.png";
                clickUrl= "block/img/movement_click.png";
                break;
            case "IO":
                trueUrl = "block/img/IO.png";
                clickUrl= "block/img/IO_click.png";
                break;
            case "流程":
                trueUrl = "block/img/process.png";
                clickUrl= "block/img/process_click.png";
                break;
            case "文本注释":
                trueUrl = "block/img/annotations.png";
                clickUrl= "block/img/annotations_click.png";
                break;
            case "等待与暂停":
                trueUrl = "block/img/wait.png";
                clickUrl= "block/img/wait_click.png";
                break;
            case "函数":
                trueUrl = "block/img/function.png";
                clickUrl= "block/img/function_click.png";
                break;
            case "通信":
                trueUrl = "block/img/communication.png";
                clickUrl= "block/img/communication_click.png";
                break;    
            case "输入输出":
                trueUrl = "block/img/InputAndOutput.png";
                clickUrl= "block/img/InputAndOutput_click.png";
                break;
            case "中断":
                trueUrl = "block/img/interrupt.png";
                clickUrl= "block/img/interrupt_click.png";
                break;
            case "运算":
                trueUrl = "block/img/operation.png";
                clickUrl= "block/img/operation_click.png";
                break;
            case "ARL":
                trueUrl = "block/img/ARL.png";
                clickUrl= "block/img/ARL_click.png";
                break;
            case "开关":
                trueUrl = "block/img/switch.png";
                clickUrl= "block/img/switch_click.png";
                break;
            case "循环":
                trueUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1552469926587&di=a3b53aa7c4a4934cc11659d1012cda05&imgtype=0&src=http%3A%2F%2Fpic.51yuansu.com%2Fpic3%2Fcover%2F01%2F64%2F60%2F595710c280190_610.jpg";
                clickUrl= "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                break;
            case "数学":
                trueUrl = "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4064586137,4089318435&fm=26&gp=0.jpg";
                clickUrl= "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                break;
            case "列表":
                trueUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1552470101548&di=ea43919ba160ac50a6bece8757d4291c&imgtype=0&src=http%3A%2F%2Fpic46.nipic.com%2F20140814%2F19268738_232534528000_2.jpg";
                clickUrl= "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                break;
            default:
                trueUrl = "http://img1.imgtn.bdimg.com/it/u=929944757,2734192754&fm=26&gp=0.jpg";
                clickUrl= "http://img2.imgtn.bdimg.com/it/u=1694287427,1534841493&fm=26&gp=0.jpg";
                break;
        }
    }
    return {
        clickUrl:clickUrl,
        trueUrl:trueUrl
    };
}

其中注意到 this.html_.privateDoNotAccessOrElseSafeHtmlWrappedValue_  是干嘛的呢,这个是获取类别内容的也就是那些个case

那么你该问了,具体是在哪生成左侧tree的呢,好把我们的代码放到相应的位置

so:

// 获取行内html样式
goog.ui.tree.BaseNode.prototype.getRowSafeHtml = function() {
    var a = {};
    a["padding-" + (this.isRightToLeft() ? "right" : "left")] = this.getPixelIndent_() + "px";
    a = { "class": this.getRowClassName(), style: a };
    //判断如果不为空  再生成img
    var b = [this.getExpandIconSafeHtml(), this.getIconSafeHtml(), this.getLabelSafeHtml(), this.html_.privateDoNotAccessOrElseSafeHtmlWrappedValue_ ? this.getLabelSafeself() : ''];
    return goog.html.SafeHtml.create("div", a, b)
};

上面的b数组就是存储将来要遍历生成dom的,我们把生成image的添加进去,不过这里需要注意的是只给类别前添加icon

blockly研究(一)自定义菜单栏_第4张图片blockly研究(一)自定义菜单栏_第5张图片

 所以我们只需要给有类别的blocklyTreeRow的div下添加咱们的icon  ,还记得我们刚才说的this.html_.privateDoNotAccessOrElseSafeHtmlWrappedValue_ 吗?这个就是类别信息,所以说我们在给b赋值的时候三目了一下,你就应该懂了是什么意思了

样式添加完成之后,有个问题就来了,点击效果怎么加?

提供给你们一个思路吧:

$('body').on('touchstart', '.blocklyTreeRow', function() {
        let bj = JSON.parse($(this).children('img').attr('backgroundData'));
        redoColor();
        $(this).children('img').attr('src', bj.clickUrl);
    })

const redoColor = () => {
    let obj = $('.blocklyTreeRow');
    for (let i = 0; i < obj.length; i++) {
        i != 0 && obj.eq(i).children('img').attr('src', JSON.parse($('.blocklyTreeRow').eq(i).children('img').attr('backgroundData')).trueUrl);
    }
}

因为我的项目这里需要一个点击换icon,所以说我在创建dom的时候就绑定了其点击后的变换信息,然后js去控制换图,只是一个思路,你也可以直接修改源码实现。

接下来你就可以随意的创建dom来完成自己的交互样式了、

博主菜单栏的块和工作区域的是不一样,所以又修改了菜单生成(左边挂图片就可以了) 效果图如下:

以上代码研究都是我们项目需要,所以说我花了一个多月去看blcokly,所有的改动都是自己的想法,很可能大家有更好的想法,

点个关注呗,项目中还有很多瑕疵在优化,接下来我会接着更新

如何自定义生成代码(博主的项目生成的c++代码)、如何自定义blockly块的形状,以及块与块之间的衔接交互如何修改,

还有就是一个小更改,比如说根据变量的类型,生成不同的变量,这些都会在后续文档中写出来,

你可能感兴趣的:(blockly)