8

Paper.js でクラスを拡張するための推奨される方法はありますか? 特に、パスの拡張に興味があります

私の用語が間違っている場合はご容赦ください。ただし、本質的には、ここで 3 つについて尋ねられている紙について同じ質問をしています。

4

2 に答える 2

5

私の回答の最初のバージョンへのコメントに基づいて、サブクラス化を行うための「拡張」機能 (おっと、それはまさにあなたが意図したものでした) を探しています。paper.js メーリング リストへの電子メールで、Jürg Lehni (作成者の 1 人) は次のように述べています。

サブクラス化に関しては、現時点ではサポートされていません。うまくいくかもしれませんし、うまくいかないかもしれませんが、ほとんどの場合はうまくいくかもしれませんが、特定するのが難しい非常にまれなケースではありません。

たとえば、各 Item サブクラスには、そのタイプを表す文字列である _type プロパティがあります。場合によっては、instanceof を使用する代わりにそれをチェックします。これは、より高速であるためです。これまでのところ、たとえば Path については、サブクラス化はないと想定していました。

paper.Path.Rectangle複雑なのは、オブジェクトがないことです。パスがあり、四角形がありますが、呼び出すnew paper.Path.Rectangle()と、四角形を作成する新しいPath使用初期化コード ( createRectangle) が作成されます。

したがって、拡張する必要がありますpaper.Path。残念ながら、new paper.Path.Rectangleそれを呼び出すと が呼び出されcreatePath、常に a Path(内線番号ではありません) が返されます。次のようなことができるかもしれません:

var SuperRectangle = paper.Path.extend({
    otherFunc: function() {
        console.log('dat');
    }
});

...そして、サブクラスを正しく置換/オーバーライドするcreateRectanglecreatePath、サブクラスを機能させます。残念ながら、私はそれを管理することができませんでした。

私の最初の実用的な推奨事項は、ファクトリを作成し、そのファクトリ内のオブジェクトに関数を追加することです (ここでは jsbin )。

  var createSuperRectangle = function(arguments){
    var superRect = new paper.Path.Rectangle(arguments);
    superRect.otherFunc = function(){
      console.log('dat');
    }
    return superRect;
  }
  var aRect = new Rectangle(20, 30, 10, 15);
  var aPath = createSuperRectangle({
    rectangle: aRect,
    strokeColor: 'black'
  });
  aPath.otherFunc();

同様に、ファクトリを使用して、SuperRectangles のプロトタイプを変更するだけで、そのプロトタイプ オブジェクトに関数を追加して (そのプロトタイプを からのプロトタイプにするpaper.Path.__proto__) ( jsbin here ):

  var superRectProto = function(){};
  var tempRect = new paper.Path.Rectangle();
  tempRect.remove();
  superRectProto.__proto__ = tempRect.__proto__;
  superRectProto.otherFunc = function(){
    console.log('dat');
  }
  delete tempRect;
  var createSuperRectangle = function(arguments){
    var superRect = new paper.Path.Rectangle(arguments);
    superRect.__proto__ = superRectProto;
    return superRect;
  }
  var aRect = new Rectangle(20, 30, 10, 15);
  var aPath = createSuperRectangle({
    rectangle: aRect,
    strokeColor: 'black'
  });
  aPath.otherFunc();

または、パスをカプセル化するオブジェクトを作成することもできます (ここでは jsbin )。

  var SuperRectangle = function(arguments){
    this.theRect = new paper.Path.Rectangle(arguments);
    this.otherFunc = function(){
      console.log('dat');
    }
  }
  var aRect = new Rectangle(20, 30, 10, 15);
  var aPath = new SuperRectangle({
    rectangle: aRect,
    strokeColor: 'black'
  });
  aPath.otherFunc();
  aPath.theRect.strokeWidth = 5;

残念ながら、パスにアクセスするには、theRect変数を使用する必要があります。


最初の不正解は次のとおりです。

「クラスを拡張する」という意味ではないと思います。Javascript では、オブジェクトを拡張してより多くの機能を持たせることができるため、Path の「クラス」を拡張すると、すべての Path オブジェクトが同じ新しい機能を持つことになります。Javascript オブジェクト拡張については、こちらで詳しく説明しています。

私が間違っていて、パスを拡張したい場合は、次を使用できます。

paper.Path.inject({
    yourFunctionName: function(anyArgumentsHere) {
        // your function here
    }
});

ただし、実際には、ほとんどが Path オブジェクトのように動作するが、互いに異なる機能を持つ新しいオブジェクトの作成について話していると思います。その場合は、原型継承を使用した Javascriptに関するこの回答を参照してください。たとえば、ここでは 2 つの Rectangle オブジェクトを作成し、要求したときに異なる動作をしますdoSomething(ここでは jsbin )。

var rect1 = new Path.Rectangle({
    point: [0, 10],
    size: [100, 100],
    strokeColor: 'black'
    });
rect1.doSomething = function() {
    this.fillColor = new Color('red');
};
var rect2 = new Path.Rectangle({
    point: [150, 10],
    size: [100, 100],
    strokeColor: 'black'
    });
rect2.doSomething = function() {
    this.strokeWidth *= 10;
};
rect1.doSomething();
rect2.doSomething();
于 2013-08-02T19:16:47.173 に答える