简体   繁体   English

扩展Paper.js中的类的推荐方法

[英]recommended way to extend classes in Paper.js

Is there a recommended way to extend classes in Paper.js? 有没有推荐的方法来扩展Paper.js中的类? In particular, I am interested in extending Path 我特别有兴趣扩展Path

Pardon if my terminology is incorrect, but I am essentailly asking the same question about paper that is being asked about three here 如果我的术语不正确,请原谅,但我是埃森塔利(Esentailly),提出了与本文有关的三个问题相同的问题

Based on your comment to the initial version of my answer, you are looking for the 'extend' function (oops, that was exactly what you meant) to do subclassing. 根据您对我的回答的初始版本的评论,您正在寻找进行子类化的“扩展”功能(哎呀,这正是您的意思)。 In an email to the paper.js mailing list , Jürg Lehni (one of the creators) said: 写给paper.js邮件列表电子邮件中 ,JürgLehni(创建者之一)说:

As for subclassing, that's not something that is supported at the moment. 至于子类,目前尚不支持。 It might work, it might not, it might work in most cases, but not in very rare cases that are hard to pinpoint, it might need only a couple of changes to make it work well, but those might be in many different places. 它可能会起作用,也许不会,在大多数情况下可能会起作用,但是在很难查明的极少数情况下却不会,它可能只需要进行一些更改即可使其正常工作,但是这些可能在许多不同的地方。

For example, each Item subclass has a _type property which is a string representing its type. 例如,每个Item子类都有一个_type属性,该属性是一个表示其类型的字符串。 Sometimes we check that instead of using instanceof, because it's faster, and so far, for example for Path we just assumed there would be no subclassing. 有时我们检查它而不是使用instanceof,因为它更快,并且到目前为止,例如对于Path,我们只是假设没有子类。

A complication is that there are no paper.Path.Rectangle objects. 复杂的是,没有paper.Path.Rectangle对象。 There are paths, and there are rectangles, but when you call new paper.Path.Rectangle() it creates a new Path using initialization code ( createRectangle ) that creates a rectangular shape. 有路径,有矩形,但是当您调用new paper.Path.Rectangle()它会使用创建矩形的初始化代码( createRectangle )创建一个新的Path

So we would need to extend paper.Path . 因此,我们需要扩展paper.Path Unfortunately, when you call new paper.Path.Rectangle it calls createPath , which always returns a Path (not your extension). 不幸的是,当您调用new paper.Path.Rectangle它将调用createPath ,该方法始终返回一个Path (而不是您的扩展名)。 It may be possible to do something like: 可能可以执行以下操作:

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

...and with correctly substituting/overriding for createRectangle or createPath get a subclass to work. ...并正确地替换/覆盖createRectanglecreatePath可以使子类正常工作。 Unfortunately, I have not been able to manage it. 不幸的是,我无法对其进行管理。

My first working recommendation is to make a factory and add your functions to the objects in that factory ( jsbin here ): 我的第一个工作建议是创建一个工厂,并将您的功能添加到该工厂中的对象( jsbin here ):

  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();

Similarly, you can use the factory to just change the prototype for your SuperRectangles, having added your functions to that prototype object (and making its prototype the one from paper.Path.__proto__ ) ( jsbin here ): 同样,您可以使用工厂为SuperRectangles更改原型,只需将功能添加到该原型对象(并从paper.Path.__proto__ 使其原型成为原型)(在jsbin这里 ):

  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();

Alternatively, you can make an object that encapsulates the Path ( jsbin here ): 另外,您可以创建一个封装Path的对象( jsbin here ):

  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;

Unfortunately, then to access the path you have to use the theRect variable. 不幸的是,然后要访问路径,您必须使用theRect变量。


Initial incorrect answer follows: 最初的错误答案如下:

I don't think you mean "extending classes". 我认为您的意思不是“扩展类”。 In Javascript you can extend objects so that they have more functions, so extending the Path "class" would mean all Path objects have the same new functions. 在Javascript中,您可以扩展对象,使其具有更多功能,因此扩展Path“类”将意味着所有Path对象都具有相同的新功能。 Javascript object extension is further described here . Javascript对象扩展在这里进一步描述。

If I'm wrong, and you do want to extend Path, then you can use: 如果我错了,并且您确实想扩展Path,那么可以使用:

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

However, I think you are actually talking about creating new objects that mostly behave like Path objects but have different functionality from each other. 但是,我认为您实际上是在讨论创建新对象,这些对象的行为与Path对象相似,但功能互不相同。 If that is the case, then you may want to look at this answer about Javascript using prototypical inheritance . 如果是这种情况,那么您可能想看看有关使用原型继承的Javascript的答案。 For example, here I create two Rectangle objects that behave differently when I ask them to doSomething ( jsbin here ): 例如,在这里我创建了两个Rectangle对象,当我要求它们执行doSomethingjsbin here )时,它们的行为有所不同:

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();

A couple of things. 有几件事。

1) You can wrap the original paperjs object but this is very much a hack paperjs playground 1)您可以包装原始的paperjs对象,但这实际上是一个hack paperjs游乐场

function SuperSquare() {
    this.square = new Path.Rectangle({
        size:50,
        fillColor:'red',
        onFrame:function(base) {
            var w2 = paper.view.element.width / 2;
            this.position.x = Math.sin(base.time) * w2 + w2;
        }
    });
}
SuperSquare.prototype.setFillColor = function(str) {
    this.square.fillColor = str;
}

var ss = new SuperSquare();
ss.setFillColor('blue');

2) I may clone & create a paper 2017 which operates off of es6 so that you can use the extend keyword. 2)我可以克隆并创建论文2017,该论文在es6之外运行,以便您可以使用extend关键字。

3) I wrote an application called Flavas but it never gained a following so I just kind of left it. 3)我编写了一个名为Flavas的应用程序,但是它从未获得关注,所以我就离开了。 That being said, I have been playing with it lately; 话虽如此,我最近一直在玩它。 upgrading it to es6. 升级到es6。 With it you can do what you're talking about. 有了它,您就可以完成您正在谈论的事情。

class Square extends com.flanvas.display.DisplayObject {
    constructor(size) {
        this.graphics.moveTo(this.x, this.y);
        this.graphics.lineTo(this.x + size, this.y);
        this.graphics.lineTo(this.x + size, this.y + size);
        this.graphics.lineTo(this.x, this.y + size);
    }

    someMethod(param) {
        trace("do something else", param);
    }
);

I wrote all this kind of quick so feel free to hit me up with Q's. 我写了所有这些快书,所以请随时给我Q的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM