白鷺引擎(egret)中錨點(anchoroffset)的位置體會

白鷺引擎(egret,以下簡稱egret)中對錨點(anchorOffsetX,anchorOffsetY)的使用目的,基本是和CSS3屬性中的transform-origin是一致的,大多是基于元素中心的旋轉(zhuǎn)和放大。但使用方法上是有區(qū)別的,比如,egret的默認錨點在左上角,而transform-origin默認在元素中心。此外,egret這類工具(還有createjs,pixi等)本身是基于canvas/webgl的畫布上進行繪制,如果使用chrome這些調(diào)試工具直接調(diào)試的話,元素信息無法被瀏覽器獲取,必然給調(diào)試增加難度。
紙上得來終覺淺,絕知此事要躬行

1. 錨點的作用

我們以一根線段旋轉(zhuǎn)90度為例:先繪制一根水平的直線,長度為100

protected startCreateScene(): void {
    this.drawOneLine();
}

protected drawOneLine(){
    let ns = new egret.Shape();

    ns.x = 100;
    ns.y = 100;

    ns.graphics.lineStyle(2,0xFF0000);
    ns.graphics.moveTo(0,0);
    ns.graphics.lineTo(100,0);
   
    this.addChild(ns);
}
初始水平線段

現(xiàn)在我們修改下代碼,在默認錨點的情況下,旋轉(zhuǎn)90度。為了方便觀察,我給線段做了漸變處理,越靠近90度的線段顏色越淺:

protected startCreateScene(): void {
    this.drawLine(0);
}

protected drawLine(angle): void {
    let ns = new egret.Shape();

    ns.x = 100;
    ns.y = 100;

    ns.graphics.lineStyle(2,0xFF0000);
    ns.graphics.moveTo(0,0);
    ns.graphics.lineTo(100,0);
    ns.alpha = 1-(angle/90)*0.9;
    ns.rotation = angle;

    this.addChild(ns);

    if(angle < 90){
        this.drawLine(angle+15);
    }
}

錨點默認時旋轉(zhuǎn)

從圖片中我們可以觀察到:線段順時針旋轉(zhuǎn)了90度,中心點位于線段左邊的端點

現(xiàn)在我們設(shè)置錨點,將中心點居中

protected startCreateScene(): void {
    this.drawLine(0);
    this.drawLineCenter(0);
}

protected drawLineCenter(angle): void {
    let ns = new egret.Shape();

    ns.x = 100;
    ns.y = 300;

    ns.anchorOffsetX = 50; // 設(shè)置錨點橫坐標(biāo),位于線段中心

    ns.graphics.lineStyle(2,0x000000);
    ns.graphics.moveTo(0,0);
    ns.graphics.lineTo(100,0);
    ns.alpha = 1-(angle/90)*0.9;
    ns.rotation = angle;

    this.addChild(ns);

    if(angle < 90){
        this.drawLineCenter(angle+15);
    }
}
錨點設(shè)置到線段中心

好了,錨點的示例到此為止。

接下來說這篇文章的關(guān)鍵,上圖中,有一個不太正常的地方,即黑色線段往左偏移,這個對于剛接觸錨點概念的同學(xué)來說,無疑是非常殘忍的,說白了就是個坑。明明所有元素都放在其應(yīng)該出現(xiàn)的位置上,并且實現(xiàn)了動效,所有的屬性設(shè)置也都正確,怎么元素就偏了呢?我最初發(fā)生這種事(createjs里),很不理解,結(jié)果從最基礎(chǔ)的圖片素材開始,把尺寸和位置重新計算一遍,反復(fù)查看代碼中一切有的沒的的配置,最后一點點去掉所有頁面中不相關(guān)的元素,才能發(fā)現(xiàn)是錨點惹的禍。

2. 錨點的正確打開方式

現(xiàn)在,我們?nèi)匀灰蚤L度100的水平線段為例,將錨點依次設(shè)置為0,50,100,觀察這三根線段的情況,代碼如下:

protected startCreateScene(): void {
    this.drawLineAnchor(100,100,0);
    this.drawLineAnchor(100,150,50);
    this.drawLineAnchor(100,200,100);
}

protected drawLineAnchor(x,y,anchorX):void{
    let ns = new egret.Shape();

    ns.x = x;
    ns.y = y;

    ns.anchorOffsetX = anchorX;

    ns.graphics.lineStyle(2,0x000000);
    ns.graphics.moveTo(0,0);
    ns.graphics.lineTo(100,0);
    this.addChild(ns);
}
從上到下依次為0,50,100

從上圖中可以很明顯的看到錨點對于畫面中真實繪制出線段的影響

即,有元素a,a在畫面中實際的橫坐標(biāo)為x',則x' = a.x - a.anchorOffsetX

關(guān)鍵代碼實際在于moveTo那一行,比如,當(dāng)元素根據(jù)屬性被定位到x=100,y=100后,由于其左上角的錨點由于被設(shè)置為anchorOffsetX=50,anchorOffsetY=0的關(guān)系,當(dāng)代碼進行到moveTo時,會按照錨點的坐標(biāo)向左偏移50位置開始繪制初始點。

所以,如果我們必須改變moveTo的初始點和重點,或者改變元素本身的x坐標(biāo),才能達到和原線段相同的位置:

protected startCreateScene(): void {
    this.drawLineAnchor(100, 100, 0); 
    this.drawLineAnchorFixMove(100, 150, 50); // 修改起點終點
    this.drawLineAnchorFixX(100, 200, 100); // 修改x坐標(biāo)
}

protected drawLineAnchor(){...} // 方法略

protected drawLineAnchorFixMove(x, y, anchorX): void {
    let ns = new egret.Shape();

    ns.x = x;
    ns.y = y;

    ns.anchorOffsetX = anchorX;

    ns.graphics.lineStyle(1, 0x000000);
    ns.graphics.moveTo(0 + anchorX, 0); // 修改線段起始點
    ns.graphics.lineTo(100 + anchorX, 0); // 修改線段終點
    this.addChild(ns);
}

protected drawLineAnchorFixX(x, y, anchorX): void {
    let ns = new egret.Shape();

    ns.x = x + anchorX; // 修改整個容器的橫坐標(biāo)
    ns.y = y;

    ns.anchorOffsetX = anchorX;

    ns.graphics.lineStyle(1, 0x000000);
    ns.graphics.moveTo(0, 0);
    ns.graphics.lineTo(100, 0);
    this.addChild(ns);
}
修改后的結(jié)果

同理,我們可以得知如果修改了anchorOffsetY會發(fā)生怎樣的變化,

有元素a,a在畫面中實際的橫坐標(biāo)為x',縱坐標(biāo)為y',則
x' = a.x - a.anchorOffsetX
y' = a.y - a.anchorOffsetY

現(xiàn)在大家應(yīng)該能理解設(shè)置錨點之后元素的具體位置了??傊?dāng)設(shè)置了錨點后,為了回到原位,最通用最簡單的做法,就是將其x,y減去自己對應(yīng)的anchorOffset屬性。

以上。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.紋理集實際上就是將一些零碎的小圖放到一張大圖當(dāng)中。游戲中也經(jīng)常使用到紋理集。使用紋理集的好處很多,我們通過將大...
    別人家的程序員閱讀 8,398評論 1 21
  • 一:canvas簡介 1.1什么是canvas? ①:canvas是HTML5提供的一種新標(biāo)簽 ②:HTML5 ...
    GreenHand1閱讀 4,881評論 2 32
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評論 19 139
  • 娛樂圈每天都在上演著狗血的事情,比如XX給XX求婚,XX和XX結(jié)婚,XX其實是小三上位……這種事情猶如輪回一樣在娛...
    最愛時尚閱讀 439評論 0 0
  • A已經(jīng)入伙兩年了,和一幫兄弟姐妹行騙多年,現(xiàn)在在C國的某島上和詐騙團伙成員們共30多人集體住在一棟豪華別墅里。 A...
    meilidedoudou閱讀 580評論 7 5

友情鏈接更多精彩內(nèi)容