1. 程式人生 > >html5視覺化圖形編輯器(基於canvas)

html5視覺化圖形編輯器(基於canvas)

我以前特別喜歡flash,不過flash水平一般,那是的我並不是程式設計師,充其量也就是個愛好者,在這個html5的時代中,我依舊對那個有時間軸的flash編輯介面念念不忘。於是便有了這篇文章。我的目標是做一款線上的圖片,文件,動畫,遊戲生成器。目標比較大(個人比較貪),目前只實現了一部分,但是我相信時間能締造一切,也希望大神們多多幫忙,謝謝了!我把所有的程式碼寫上來,一是幫我記錄開發過程,二是供大家檢視研究,有興趣的多多留言交流。 建立一個js檔案起好響亮大名在webstorm中不寫hello,寫一個html5中的flash,一個基於canvas(並非基於SVG)的強大框架(哈哈目標遠大,任務重啊!) 面向物件可以簡化開發難度,便於維護,為了做到更好的面向物件,要對js中的一些東西進行完善。 1先拿陣列開刀
/**
* 刪除陣列的元素
*/

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)的概念。 今天就說到這裡。明天繼續!