html5視覺化圖形編輯器(基於canvas)
阿新 • • 發佈:2019-01-02
我以前特別喜歡flash,不過flash水平一般,那是的我並不是程式設計師,充其量也就是個愛好者,在這個html5的時代中,我依舊對那個有時間軸的flash編輯介面念念不忘。於是便有了這篇文章。我的目標是做一款線上的圖片,文件,動畫,遊戲生成器。目標比較大(個人比較貪),目前只實現了一部分,但是我相信時間能締造一切,也希望大神們多多幫忙,謝謝了!我把所有的程式碼寫上來,一是幫我記錄開發過程,二是供大家檢視研究,有興趣的多多留言交流。
建立一個js檔案起好響亮大名在webstorm中不寫hello,寫一個html5中的flash,一個基於canvas(並非基於SVG)的強大框架(哈哈目標遠大,任務重啊!)
面向物件可以簡化開發難度,便於維護,為了做到更好的面向物件,要對js中的一些東西進行完善。
1先拿陣列開刀
以上是對陣列的改造,這些東西以後會派上大用處,不過有些方法並不完善,有漏洞,需要進一步完善! 2 全域性物件 要撰寫專業的js框架而言,一般採用這種方式書寫,這種方式實現了所謂的私有化變數和方法。比如jquery就是這種寫法,對於框架安全有重要意義,對於外部要訪問的方法可以在其前面加上window。由於本人是個急性子想要現實現功能後在對框架進行封裝(習慣不好哈哈哈!所以就沒有使用這種的) (function(){ //js code })() 一些全域性物件 由於想寫一個獨立的框架,不想使用jquery(雖然很方便) 獲取dom物件
舞臺的實現
重點說一下如何實現flash中的舞臺,時間軸,層的 場景的概念 我把flash中的幀的概念當作一個場景(scane),一副畫面。場景中的畫面又有了層(Layer)的概念。 今天就說到這裡。明天繼續!
/** * 刪除陣列的元素 */ Array.prototype.remove = function (val) { if (val != null && this.length > 0) { for (var i = 0; i < this.length; i++) { if (this[i] == val) { this.splice(i, 1); break; } } } } /** * * 刪除指定索引處元素 * @param dx * @returns {Array} */ Array.prototype.del = function (dx) { if (isNaN(dx) || dx > this.length || dx < 0) { return this; } else { this.splice(dx, 1); } } /** * * 向陣列末尾追加一個元素 * @param val * @returns {Number|number} */ Array.prototype.add = function (val) { if (val != null) { return this.push(val); } } /** * * 清空陣列 * @returns {Array|T[]} */ Array.prototype.clear = function () { return this.splice(0, this.length); } /** * * * 交換兩個元素的值 * @param index1 * @param index2 * @returns {*|T} */ Array.prototype.swap = function (index1, index2) { if (index1 < this.length && index2 < this.length && index1 >= 0 && index2 >= 0) { return this[index1] = this.splice(index2, 1, this[index1])[0]; } } /** * 陣列上移 * @param index */ Array.prototype.up = function (index) { if (index != null && index >= 0 && index < this.length) { if (index == 0) { return; } this.swap(index, index - 1); } }; /** * * * 陣列下移 * @param index */ Array.prototype.down = function (index) { if (index != null && index >= 0 && index < this.length) { if (index == this.length - 1) { return; } this.swap(index, index + 1); } }; /** * * 陣列元素變為第一個元素 * @param index */ Array.prototype.dips = function (index) { if (index != null && index >= 0 && index < this.length) { if (index == 0) { return; } this.swap(index, 0); } } /** * * 陣列元素變為最後一個元素 * @param index */ Array.prototype.floats = function (index) { if (index != null && index >= 0 && index < this.length) { if (index == this.length - 1) { return; } this.swap(index, this.length - 1); } } Array.prototype.find = function (val) { if (this.length > 0) { for (var i = 0; i < this.length; i++) { if (this[i] == val) { return i; } } } }
以上是對陣列的改造,這些東西以後會派上大用處,不過有些方法並不完善,有漏洞,需要進一步完善! 2 全域性物件 要撰寫專業的js框架而言,一般採用這種方式書寫,這種方式實現了所謂的私有化變數和方法。比如jquery就是這種寫法,對於框架安全有重要意義,對於外部要訪問的方法可以在其前面加上window。由於本人是個急性子想要現實現功能後在對框架進行封裝(習慣不好哈哈哈!所以就沒有使用這種的) (function(){ //js code })() 一些全域性物件 由於想寫一個獨立的框架,不想使用jquery(雖然很方便) 獲取dom物件
</pre><div></div><div><pre class="javascript" name="code">var scaneArray = new Array(); var layerArray = new Array(); /*** * * 場景 * @constructor */ function Scane() { scaneArray.add(this); this.id = ''; this.playtime = 1000; //指定場景播放時間 this.playflag = false; this.order = ''; //場景編號 this.loopflag = false; //迴圈標誌 this.nextframe = ""; //在限定時間播放後調到指定編號場景 this.layer = new Layer(); //場景中的圖層 this.addplayer = function (val) { this.layer.array.add(val); } this.startplay = function () { this.playflag = true; } this.stopplay = function () { this.playflag = false; } } /** * * * 場景中的層 * @constructor */ function Layer() { this.array = new Array(); this.add = function (val) { this.array.add(val) } this.remove = function (val) { if (this.array.length > 0) { //alert(val); for (var i in this.array) { if ((val == this.array[i]) && this.array[i].role == "weather") { $s("stage").removeChild($s(val.id)); } if ((val == this.array[i]) && this.array[i].role == "pickj") { $s("stage").removeChild($s(val.canId)); } } this.array.remove(val); } } this.top = function (val) { if (this.array.length > 0) { this.array.floats(this.array.find(val)); } } this.clear=function(){ if (this.array.length > 0) { for (var i in this.array) { this.remove(this.array[i]); } } } this.hides=function(){ if (this.array.length > 0) { for (var i in this.array) { if (this.array[i].role === "pickj"&&$s(this.array[i].canId)!=null) { $s(this.array[i].canId).width=0; $s(this.array[i].canId).height=0; } } } } this.show=function(){ if (this.array.length > 0) { for (var i in this.array) { if (this.array[i].role === "pickj"&&($s(this.array[i].canId))!=null) { $s(this.array[i].canId).width=this.array[i].w; $s(this.array[i].canId).height=this.array[i].h; } } } } }
舞臺的實現
function Stage(w, h, color, id,bg) { Stage.array = array; Stage.cmdArray = cmdArray; Stage.shapeArray = shapeArray; Stage.background=bg; Stage.w = w; Stage.h = h; canvas.width = w; canvas.height = h; canvas.style.backgroundColor = color; onload = function () { try { document.getElementById(id).appendChild(canvas); Toolcan=document.getElementById("timeline"); toolpaint=Toolcan.getContext("2d"); } catch (e) { alert("找不到對應的id值無法建立畫板" + e.message); } }; Stage.update = function () { } Stage.draw = function () { } Stage.Aexe = function (mv) { if (cmdArray.length > 0) { if (cmdArray != null && cmdArray.length > 0) { setInterval(function () { if (i < cmdArray.length) { mc.speed = 1; mc.statu = true; mc.shortsport = true; if (cmdArray[i] == 'up') { mc.fx = 'up' } else if (cmdArray[i] == 'down') { mc.fx = 'down' } else if (cmdArray[i] == 'left') { mc.fx = 'left' } else if (cmdArray[i] == 'right') { mc.fx = 'right' } i++; } }, 1000); } } } Stage.findScane=function(id){ if(scaneArray.length>0){ for(var i=0;i<scaneArray.length;i++){ if(scaneArray[i].id==id) { return scaneArray[i]; }}} } Stage.removeScane=function(id){ if(scaneArray.length>0){ for(var i=0;i<scaneArray.length;i++){ if(scaneArray[i].id==id){ scaneArray.remove(scaneArray[i]); } } } } Stage.add = function (moveclip) { if (moveclip != null) { if (Stage.array.length == 0) { Stage.array.push(moveclip); } else if (Stage.array.length > 0) { var k = 0 for (var m = 0; m < Stage.array.length; m++) { if (moveclip.id !== Stage.array[m].id) { k++; } else { alert("id=" + id + "id重複,請更換!"); return; } } if (k >= Stage.array.length) { Stage.array.push(moveclip); } } } }; Stage.remove = function (val) { if (val != null) { Stage.array.remove(val); } }; Stage.findByid = function (id) { if (id != null && Stage.array.length > 0) { for (var i = 0; i < Stage.array.length; i++) { if (Stage.array[i].id == id) { return Stage.array[i]; } } } else { return null; } } Stage.removeById = function (id) { if (id != null && Stage.array.length > 0) { var k = 0; for (var i = 0; i < Stage.array.length; i++) { if (Stage.array[i].id == id) { Stage.array.remove(Stage.array[i]); } else { k++; if (k >= Stage.array.length) { alert("此id不存在!") } } } } }
重點說一下如何實現flash中的舞臺,時間軸,層的 場景的概念 我把flash中的幀的概念當作一個場景(scane),一副畫面。場景中的畫面又有了層(Layer)的概念。 今天就說到這裡。明天繼續!