分析するGraphics
9041 ワード
createjsを長期にわたって使用する過程で、私はずっとこのような経験を持っています:“
の原因となる
createjs.Graphics上の描画グラフィックAPIは、最終的には元のcanvas文に変換されます.まず原生canvasの表現を見てみましょう.
コード1 var ctx=canvas.getContext("2d");
最終的な状況は次のとおりです.
コード2 var ctx=canvas.getContext("2d");
最終的な状況は次のとおりです.
どうしてコード2に赤い矩形が見えないのですか?photoshopに塗りつぶし色も線の色もない図形を描くと、描き終わったらこの図形は見えません.この理屈もcanvasに適用されます.
canvasの場合、グラフィックを描画してから塗りつぶし(fill)またはストローク(stroke)を行うには、最終的にグラフィックがキャンバスにレンダリングされます.塗りつぶしまたは線を引いてからグラフィックを描くと、グラフィックはレンダリングされません.
比喩的に言えば
まず穴を掘ってから水を注ぐ==水を入れる;まず水を注いでから穴を掘る==穴を1つ掘る
原生canvasの充填または線引き方法は4つあり、以下の通りです. fill stroke fillRect strokeRect
分析するGraphicsのソース
createjs.Graphicsのソースアドレス:http://www.createjs.com/docs/...
私は前の説明で「すべてのGraphics上のグラフィックAPIが最終的にオリジナルcanvas文に変換される」と言ったことがありますが、createjsのソースコードを見ても確かにそうです.APIが多すぎるため、
まず研究したソースコードはGraphics構造関数であり、以下の図である.
次に、GはGraphics構造関数そのものを表し、pはGraphicsを表す.prototype、以下の通りです.
第三にGraphics.prototype.drawRectはGraphicsを指す.prototype.rect、次のようにします.
第四にGraphics.prototype.rectは
第五に、まずG.Rectが何をしたかを見てみましょう.以下のようにします.
ここには
第六に、
ここで得られる情報は、
ここでの情報は重要すぎる:p.appendの役割は「コマンドオブジェクト(command object)」を「画像キュー(graphics queue)」にプッシュすることである.「グラフィックインスタンス(Shape instance)」が
ステップ7、
ここでは、
手順8:
上図コードから分かるように、
私から見ればcreatejsはGraphicsの方法を2種類3種類に分けている.
第1クラス
グラフィックの描画
描画方法;例えば、rect/moveTo/lineToなど
第2クラス
グラフィックのレンダリング
充填方法(fill);ストローク方法(stroke);
現在の分析の
ステップ9、分析
ステップ10、
第2のクラスメソッドは、
1615行の
どうして陥没井戸なの?1614~1615行を振り返ると、
これは、第2のクラスのメソッドが生成したコマンドがキューの位置にあるのは、次の第2のクラスのメソッドが存在するチェーンの位置であることを意味します(第2のクラスのメソッドが1つしかない場合、チェーンの最後にあります).しかし、上記の結論は、本文書が投げ出した知識点を解決するものではありません.「beginFillはdrawXXXの前に置かなければなりません.そうしないと、beginFillは無視されます」.
1577行の判定文:
PS:第2クラスのコマンドのすべての方法--beginFill,beginStroke,setStrokeStyle,setStrokeDash.機能的にはbeginFillは形式的に全く同じなので、beginFillを分析するだけでよい.次のようになります.
マルチグラフィックインスタンス
createjs.Graphicsは、var instance=new createjsのようなマルチグラフィックインスタンスを作成することができる.Shape(); instance.graphics
実は私が想像していたのは、Shapeインスタンスが1つのグラフィックしか作成できないということですが、実際にはShapeインスタンスが複数のグラフィックを作成できるということです.原生canvasからマルチグラフィックがどのように描かれているかを説明します.
var ctx = canvas.getContext("2d");
厳密には、オリジナルcanvasのグラフィックの描画とレンダリングは
コードはvar ctx=canvasと簡単にできます.getContext("2d");
矩形と円形の中間の
この場合、矩形と円形は同じ図形に属するので、fillは最後の色を塗りつぶします.
振り返ると
別の結論を簡単に得ることができます.第2の方法は、チェーン上の位置にbeginPathのコマンドを挿入して、前のグラフィックの終了と次のグラフィックの開始をマークします.1つの図形を研究対象とする場合、Graphicsが1つの図形を描画する言語:第2の方法()を難しくしない.[.第2の方法()...].第一類の方法()[.第一類の方法()...]
上の式は簡単に書くことができる:第2類の方法グループ.第1のメソッドグループ.次に、メソッドを対応するオリジナルコマンドに変換すると、これらのコマンドの実行順序は、第1のメソッドで生成されたコマンド->第2のメソッドで生成されたコマンドです.ちょうど語式の左右と入れ替わる.
まとめ
本文はGraphicsソースコードを解析した後、以下の結論を出した.第2のクラスメソッドが生成するコマンドは、キューの位置にある次の第2のクラスメソッドが存在するチェーン位置である(第2のクラスメソッドが1つしかない場合はチェーンの最後にある) . Graphicsのチェーン末尾が第2のクラスのメソッドである場合、これらのメソッドが生成するコマンドは .第2のクラスの方法は、チェーンの位置フラグの前のグラフィックの終了と次のグラフィックの開始 である.
3つの結論があるが、記憶されにくい.
もっと価値があるのは図形を描く語式であるべきです:“第2類の方法グループ.第1類の方法グループ”しかし実用価値についてまだ冒頭のあの文です:
beginFill
はdrawXXX
の前に呼び出さなければなりません.そうしないとbeginFill
は無視されます(はい、間違いを報告しません).しかし、なぜそうなったのか、実は深く研究していない.今日はGraphicsがどのように働いているのか知りたいです.の原因となる
createjs.Graphics上の描画グラフィックAPIは、最終的には元のcanvas文に変換されます.まず原生canvasの表現を見てみましょう.
コード1 var ctx=canvas.getContext("2d");
ctx.rect(0, 0, 100, 100);
ctx.fillStyle = "#ff0000";
ctx.fill();
最終的な状況は次のとおりです.
コード2 var ctx=canvas.getContext("2d");
ctx.fillStyle = "#ff0000";
ctx.fill();
ctx.rect(0, 0, 100, 100);
最終的な状況は次のとおりです.
どうしてコード2に赤い矩形が見えないのですか?photoshopに塗りつぶし色も線の色もない図形を描くと、描き終わったらこの図形は見えません.この理屈もcanvasに適用されます.
fill
というAPIは、色を塗りつぶすために使用されます.canvasの場合、グラフィックを描画してから塗りつぶし(fill)またはストローク(stroke)を行うには、最終的にグラフィックがキャンバスにレンダリングされます.塗りつぶしまたは線を引いてからグラフィックを描くと、グラフィックはレンダリングされません.
比喩的に言えば
まず穴を掘ってから水を注ぐ==水を入れる;まず水を注いでから穴を掘る==穴を1つ掘る
原生canvasの充填または線引き方法は4つあり、以下の通りです.
分析するGraphicsのソース
createjs.Graphicsのソースアドレス:http://www.createjs.com/docs/...
私は前の説明で「すべてのGraphics上のグラフィックAPIが最終的にオリジナルcanvas文に変換される」と言ったことがありますが、createjsのソースコードを見ても確かにそうです.APIが多すぎるため、
Graphics.prototype.drawRect
から先に切り込むしかありません.まず研究したソースコードはGraphics構造関数であり、以下の図である.
次に、GはGraphics構造関数そのものを表し、pはGraphicsを表す.prototype、以下の通りです.
第三にGraphics.prototype.drawRectはGraphicsを指す.prototype.rect、次のようにします.
第四にGraphics.prototype.rectは
this.append
に直接戻り、G.Rectメソッドを同時に呼び出します.以下のようにします.第五に、まずG.Rectが何をしたかを見てみましょう.以下のようにします.
ここには
exec
が出てきて何をしているのか分かりませんが、exec
がdrawRect
をオリジナルのcanvasコードに変換しているのが見えます!!!第六に、
Graphics.prototype.append
を振り返ってみると、以下のようになっています.ここで得られる情報は、
new G.Rect(x, y, w, h)
pushを配列_activeInstructions
に入れることである.私が欲しいものはないようですが、上を見ると以下の注釈があります.// TODO: deprecated.
/**
* Removed in favour of using custom command objects with {{#crossLink "Graphics/append"}}{{/crossLink}}.
* @method inject
* @deprecated
**/
/**
* Appends a graphics command object to the graphics queue. Command objects expose an "exec" method
* that accepts two parameters: the Context2D to operate on, and an arbitrary data object passed into
* {{#crossLink "Graphics/draw"}}{{/crossLink}}. The latter will usually be the Shape instance that called draw.
*
* This method is used internally by Graphics methods, such as drawCircle, but can also be used directly to insert
* built-in or custom graphics commands. For example:
*
* // attach data to our shape, so we can access it during the draw:
* myShape.color = "red";
*
* // append a Circle command object:
* myShape.graphics.append(new createjs.Graphics.Circle(50, 50, 30));
*
* // append a custom command object with an exec method that sets the fill style
* // based on the shape's data, and then fills the circle.
* myShape.graphics.append({exec:function(ctx, shape) {
* ctx.fillStyle = shape.color;
* ctx.fill();
* }});
*
* @method append
* @param {Object} command A graphics command object exposing an "exec" method.
* @param {boolean} clean The clean param is primarily for internal use. A value of true indicates that a command does not generate a path that should be stroked or filled.
* @return {Graphics} The Graphics instance the method is called on (useful for chaining calls.)
* @chainable
**/
ここでの情報は重要すぎる:p.appendの役割は「コマンドオブジェクト(command object)」を「画像キュー(graphics queue)」にプッシュすることである.「グラフィックインスタンス(Shape instance)」が
draw
メソッドを呼び出すと、「コマンドオブジェクト」が「画像キュー(graphics queue)」から取り出され、そのインスタンスの様子が描かれます.ステップ7、
p.draw
を参照してください.以下のようにします.ここでは、
draw
が実行されると、配列_instructions
に対してキュー操作が行われることが一目瞭然である.しかし、6番目のステップで述べた配列は_activeInstructions
であるが、_instructions
と_activeInstructions
とはどのような関係があるのだろうか.上の図にはthis._updateInstructions()
という答えがあるかもしれません.手順8:
_updateInstructions
の方法を参照してください.上図コードから分かるように、
_activeInstructions
は_instructions
の一部である.さらに深く分析すると、上図コードの次のthis._fill
とthis._stroke
が表示されます.私から見ればcreatejsはGraphicsの方法を2種類3種類に分けている.
第1クラス
グラフィックの描画
描画方法;例えば、rect/moveTo/lineToなど
第2クラス
グラフィックのレンダリング
充填方法(fill);ストローク方法(stroke);
現在の分析の
drawRect
が第1クラスである.第2のクラスを分析する必要があります.ステップ9、分析
beginFill
:beginFill
はthis.append
ではなくthis._setFill
であることがわかる.ステップ10、
p._setFill
を参照してください.以下のようにします.第2のクラスメソッドは、
this._updateInstructions(true)
を直接呼び出し、第2のクラスメソッドが生成したコマンドも_activeInstructions
配列に格納されなくなった(実際には_activeInstructions配列は、第1のクラスメソッドが生成したコマンドの配列である).1615行の
this.command = this._fill = fill
は、実は重要です.ステップ8の_updateInstructions
を振り返ると、第2のクラスのメソッドは、_updateInstructions
を内部的に呼び出し、boolean値trueに入力し、_activeInstructions
配列をクリアする役割を果たす(1602行参照).「1577行~1606行」のコードを解析すると、この20行のコードの役割は、第2の方法で生成されたコマンドを_instructions
配列に追従することであることがわかる.ここには論理トラップがあります.現在の第2のコマンドをinstructions
配列に追加します.どうして陥没井戸なの?1614~1615行を振り返ると、
this._fill
は_updateInstructions
を呼び出した後に付与される.これは、第2のクラスのメソッドによって生成されたコマンドが、次の呼び出し_updateInstructions
が_instructions
配列に追加されることを意味する._updateInstructions
に呼び出されるアクションはどれですか?第2の方法はp.drawである.これは、第2のクラスのメソッドが生成したコマンドがキューの位置にあるのは、次の第2のクラスのメソッドが存在するチェーンの位置であることを意味します(第2のクラスのメソッドが1つしかない場合、チェーンの最後にあります).しかし、上記の結論は、本文書が投げ出した知識点を解決するものではありません.「beginFillはdrawXXXの前に置かなければなりません.そうしないと、beginFillは無視されます」.
1577行の判定文:
if (this._dirty && active.length)
に戻ります.実際には、第2のクラスのメソッドが_updateInstructions
メソッドを呼び出すと、_activeInstructions
配列が空になります(すなわち、active.length === 0
).またp.draw
は_activeInstructions
配列を空にしないが、これを空にする.dirtyはfalseに設定されます(行:1599参照).これは、Graphicsのチェーン末尾が第2の方法であり、これらの方法で生成されたコマンドが_instructions
配列に追加されない(すなわち、実行されない)ことを意味する.var rect=new createjs.Shape(); rect.graphics.drawRect(0, 0, 100, 100).beginFill("#ff0000").setStrokeStyle("#000000").beginStroke(4);stage.addChild(rect);上のコードは実行後空白です.PS:第2クラスのコマンドのすべての方法--beginFill,beginStroke,setStrokeStyle,setStrokeDash.機能的にはbeginFillは形式的に全く同じなので、beginFillを分析するだけでよい.次のようになります.
マルチグラフィックインスタンス
createjs.Graphicsは、var instance=new createjsのようなマルチグラフィックインスタンスを作成することができる.Shape(); instance.graphics
.beginFill("#ff0000").drawRect(0, 0, 100, 100) //
.beginFill("#ffff00").drawCircle(150, 150, 50) //
実は私が想像していたのは、Shapeインスタンスが1つのグラフィックしか作成できないということですが、実際にはShapeインスタンスが複数のグラフィックを作成できるということです.原生canvasからマルチグラフィックがどのように描かれているかを説明します.
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.rect(0, 0, 100, 100);
ctx.fillStyle = "#ff0000";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.arc(150, 150, 50, 150, 100 * Math.PI * 2);
ctx.fillStyle = "#ffff00";
ctx.fill();
ctx.closePath();
厳密には、オリジナルcanvasのグラフィックの描画とレンダリングは
beginPath()
から始まり、closePath()
から終わります.実際には、beginPath()
は、前の図形の終了および次の図形の開始を表す.コードはvar ctx=canvasと簡単にできます.getContext("2d");
ctx.rect(0, 0, 100, 100);
ctx.fillStyle = "#ff0000";
ctx.fill();
ctx.beginPath();
ctx.arc(150, 150, 50, 150, 100 * Math.PI * 2);
ctx.fillStyle = "#ffff00";
ctx.fill();
矩形と円形の中間の
beginPath()
がなくなったらどうなりますか?var ctx = canvas.getContext("2d"); ctx.rect(0, 0, 100, 100);
ctx.fillStyle = "#ff0000";
ctx.fill();
ctx.arc(150, 150, 50, 150, 100 * Math.PI * 2);
ctx.fillStyle = "#ffff00";
ctx.fill();
この場合、矩形と円形は同じ図形に属するので、fillは最後の色を塗りつぶします.
振り返ると
createjs.Graphics
のp._updateInstructions
:別の結論を簡単に得ることができます.第2の方法は、チェーン上の位置にbeginPathのコマンドを挿入して、前のグラフィックの終了と次のグラフィックの開始をマークします.1つの図形を研究対象とする場合、Graphicsが1つの図形を描画する言語:第2の方法()を難しくしない.[.第2の方法()...].第一類の方法()[.第一類の方法()...]
上の式は簡単に書くことができる:第2類の方法グループ.第1のメソッドグループ.次に、メソッドを対応するオリジナルコマンドに変換すると、これらのコマンドの実行順序は、第1のメソッドで生成されたコマンド->第2のメソッドで生成されたコマンドです.ちょうど語式の左右と入れ替わる.
まとめ
本文はGraphicsソースコードを解析した後、以下の結論を出した.
_instructions
配列に追加されない(すなわち実行されない)3つの結論があるが、記憶されにくい.
もっと価値があるのは図形を描く語式であるべきです:“第2類の方法グループ.第1類の方法グループ”しかし実用価値についてまだ冒頭のあの文です:
beginFill
はdrawXXX
の前に呼び出さなければならなくて、さもなくばbeginFill
は無視されます(はい間違いを報告しません)