由於最近一直比較忙,所以沒有更新博客
由於博主做的項目不需要舞臺與模擬器的概念,所以在技術選型上也就沒有選擇s3等其他的圖形化編程框架
今天給大家帶來的是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塊的形狀,以及塊與塊之間的銜接交互如何修改,
還有就是一個小更改,比如說根據變量的類型,生成不同的變量,這些都會在後續文檔中寫出來,