рекомендуемый способ расширения классов в Paper.js

Есть ли рекомендуемый способ расширения классов в Paper.js? В частности, меня интересует расширение Path

Простите, если моя терминология неверна, но я, по сути, задаю тот же вопрос о документе о котором здесь спрашивают о трех


person jefftimesten    schedule 25.07.2013    source источник
comment
Как вам эта грязная работа @avall?   -  person VoronoiPotato    schedule 25.07.2013
comment
Я не понимал, что прошу кого-то сделать грязную работу. пожалуйста, объясни   -  person jefftimesten    schedule 25.07.2013
comment
Я недостаточно хорошо знаю paperjs, чтобы оказать конкретную помощь, но посмотрите на их код, попробуйте увидеть, как они обрабатывают наследование.   -  person VoronoiPotato    schedule 25.07.2013


Ответы (2)


Основываясь на вашем комментарии к первоначальной версии моего ответа, вы ищете функцию «расширить» (упс, это было именно то, что вы имели в виду) для создания подклассов. В письме в список рассылки paper.js Юрг Лени (один из создателей) сказал:

Что касается подклассов, это не то, что поддерживается на данный момент. Это может работать, а может и нет, может работать в большинстве случаев, но не в очень редких случаях, которые трудно точно определить, может потребоваться всего пара изменений, чтобы заставить его работать хорошо, но они могут быть в разных местах.

Например, каждый подкласс Item имеет свойство _type, представляющее собой строку, представляющую его тип. Иногда мы проверяем это вместо использования instanceof, потому что это быстрее, и до сих пор, например, для Path мы просто предполагали, что не будет подклассов.

Сложность в том, что нет paper.Path.Rectangle объектов. Есть пути и есть прямоугольники, но когда вы вызываете new paper.Path.Rectangle(), он создает новый Path, используя код инициализации (createRectangle), который создает прямоугольную форму.

Поэтому нам нужно расширить paper.Path. К сожалению, когда вы вызываете new paper.Path.Rectangle, он вызывает createPath, который всегда возвращает Path (не ваш добавочный номер). Возможно, можно сделать что-то вроде:

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

... и с правильной заменой/переопределением createRectangle или createPath заставьте подкласс работать. К сожалению, мне не удалось им управлять.

Моя первая рабочая рекомендация — создать фабрику и добавить свои функции к объектам этой фабрики (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();

Точно так же вы можете использовать фабрику, чтобы просто изменить прототип ваших суперпрямоугольников, добавив свои функции в этот объект-прототип (и сделав прототип его прототипом из 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();

Кроме того, вы можете создать объект, который инкапсулирует путь (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 с использованием прототипического наследования. Например, здесь я создаю два объекта 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();
person beaslera    schedule 02.08.2013
comment
Большое спасибо за ответ, но на самом деле я не говорю ни об одной из этих вещей. Что я хочу сделать, так это создать, скажем, Path.SuperRectangle, который получает всю функциональность Path.Rectangle, но я также могу добавить дополнительные функции и свойства. Так что я могу сделать var foo = new Path.SuperRectangle() - person jefftimesten; 05.08.2013

Несколько вещей.

1) You can wrap the original paperjs object but this is very much a 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) Я могу клонировать и создать документ 2017, который работает на es6, чтобы вы могли использовать ключевое слово extend.

3) Я написал приложение под названием Flavas, но оно так и не получило подписчиков, поэтому я просто написал оставил его. При этом я играл с ним в последнее время; обновить его до es6. С ним вы можете делать то, о чем говорите.

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

Я написал все так быстро, так что не стесняйтесь задавать мне вопросы.

person Jacksonkr    schedule 31.05.2017