blockly研究(一)自定義菜單欄

由於最近一直比較忙,所以沒有更新博客

由於博主做的項目不需要舞臺與模擬器的概念,所以在技術選型上也就沒有選擇s3等其他的圖形化編程框架

今天給大家帶來的是blockly自定義左側菜單欄、以及交互效果如何去加

首先先看一下效果:修改之前:  修改之後:  

 

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

谷歌blockly官網

blockly源碼

某書上看到的一個api入門介紹

看了上面做這幾個之後你就能清楚的解決上面提的問題(這部分自己看,就不詳細介紹了,如果有不懂得可以留言,一起研究)

接下來就可以說這篇博客要做的事了

首先看一下dom結構

發現他自己生成的就是圈起來的這樣的結構,好了現在的思路就很簡單了,源代碼的結構與咱們的結構就只差一個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

 所以我們只需要給有類別的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塊的形狀,以及塊與塊之間的銜接交互如何修改,

還有就是一個小更改,比如說根據變量的類型,生成不同的變量,這些都會在後續文檔中寫出來,

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章