Paper.js, как настроить несколько холстов, используя только javascript
Я пытаюсь использовать paper.js в webapp, но мне не удалось заставить его работать с несколькими холстами. Это подобно областям, которые смешиваются между холстами, поэтому, когда я намереваюсь рисовать на холсте 1, он появляется на холсте 2.
В каждом представлении я инициализирую документ следующим образом:
this.mypaper = new paper.PaperScope();
this.mypaper.setup($("myCanvasId")[0]);
Когда я создаю новые бумажные объекты, я использую то, что должно быть локальной областью:
var circle = new this.mypaper.Path.Circle(10, 10, 5);
Однако, когда я создаю круг в view1, он рисует его в view2.
Я много читал, но я до сих пор не нашел четкого объяснения того, как настраивать несколько бумаг или как изолировать представления друг от друга.
Кто-нибудь знает, как правильно использовать несколько холстов с paper.js?
EDIT: я создал jsFiddle, чтобы проиллюстрировать проблему: http://jsfiddle.net/94RTX/1/
Ответы
Ответ 1
Я не работал с Paper.js широко, но кажется, что каждый вызов Path
не использует PaperScope
, из которого он обращается, но глобальный объект paper
. Поэтому, если вы перезаписываете paper
на нужный PaperScope перед каждым экземпляром, он должен работать.
Смотрите мою обновленную скрипту.
Ответ 2
Я действительно решаю это немного по-другому:
var scope1 = new paper.PaperScope();
var scope2 = new paper.PaperScope();
Когда я хочу рисовать в области 1:
scope1.activate();
// now I draw
Аналогично, когда я хочу рисовать в области видимости 2
scope2.activate();
// now I draw
Ответ 3
Используйте массивы для разделения ваших документов.
this.mypapers = []
var mypaper = new paper.PaperScope();
mypaper.setup($("myCanvasId")[0]);
mypapers.push(mypaper);
mypaper = new paper.PaperScope();
mypaper.setup($("myCanvasId")[1]);
mypapers.push(mypaper);
var circle = new this.mypapers[0].Path.Circle(10,10,5);
var circle2 = new this.mypapers[1].Path.Circle(10,10,10);
EDIT: я обновил скрипт js:
http://jsfiddle.net/94RTX/3/
По-видимому, каждая установка стирает предыдущую, поэтому решение должно сделать это в следующем порядке:
setup canvas 1-> draw canvas 1 -> setup canvas 2 -> draw canvas 2
Ответ 4
Я думаю, что нашел решение: я расширил скрипт от @freejosh, чтобы также работать с обратными вызовами (например, изменить размер): трюк заключается в повторной выборке правильной области внутри функции обратного вызова:
http://jsfiddle.net/rassoh/mx9n3vsf/7/
var mypapers = [];
initPaper(0, $("#canvas1")[0]);
initPaper(1, $("#canvas2")[0]);
function initPaper(id, canvasElement) {
var mousePosition = new paper.Point(0,0);
mypapers[id] = new paper.PaperScope();
paper = mypapers[id];
paper.setup(canvasElement);
var myCircle;
createCircle = function() {
if( "undefined" !== typeof myCircle) {
myCircle.remove();
}
// this function is called on resize, so we have to re-fetch the scope!
paper = mypapers[id];
myCircle = new paper.Path.Circle(30, 30, 20);
var lightRed = new paper.Color(1, 0.5, 0.5);
var lightBlue = new paper.Color(0.5, 0.5, 1);
myCircle.style = {
fillColor: id === 0 ? lightRed : lightBlue,
strokeColor: "black"
};
}
createCircle();
var tool = new paper.Tool();
tool.onMouseMove = function(event) {
mousePosition = event.lastPoint;
};
paper.view.onFrame = function() {
if( "undefined" === typeof myCircle) {
return;
}
var dist = mousePosition.subtract( myCircle.position );
dist = dist.divide( 3 );
myCircle.position = myCircle.position.add( dist );
};
paper.view.onResize = function() {
createCircle();
};
}
$(window).resize(function() {
var width = $(".container").width() / 2;
var height = $(".container").height();
// this automatically triggeres paper onResize event registered above
mypapers[0].view.viewSize = new paper.Size( width, height );
mypapers[1].view.viewSize = new paper.Size( width, height );
});
Обратите внимание, что я также включил простое взаимодействие с кругами, чтобы проверить там правильное поведение.
Ответ 5
Чтобы более точно управлять тем, с каким бумажным ящиком вы добавляете элементы, вы можете рассмотреть возможность установки опции insertItems
на false
.
var paper1 = new paper.PaperScope();
paper1.setup(canvasElement);
paper1.settings.insertItems = false;
Таким образом, при создании новых элементов бумаги они автоматически не добавляются к бумаге. Таким образом, независимо от того, в какой области был создан ваш бумажный элемент, вы все равно решили добавить его в одну или другую бумагу. Например, теоретически вы можете:
// create a second scope
var paper2 = new paper.PaperScope();
// create a circle in the first scope
var myCircle = new paper1.Path.Circle(new paper1.Point(100, 70), 50);
myCircle.fillColor = 'black';
// add that circle to the second scope paper
paper2.project.activeLayer.addChild(myCircle);