pts
pts copied to clipboard
SVGCanvas animation doesn't work with if statement
It seems like if you use an if
statement within an SVGCanvas
animation, it doesn't work as expected.
This function is a small reproduction of the problem:
export const createShapes = ({ space }) => {
const state = {
isPlaying: true
};
const form = space.getForm();
const createPlayIcon = (x, y) =>
Triangle.fromCenter(new Pt(x, y), 50).rotate2D(33);
const createStopIcon = (x, y) => Rectangle.fromCenter(new Pt(x, y), 70);
space.add({
action: (type) => {
if (type === "up") {
state.isPlaying = !state.isPlaying;
}
}
});
// Works
space.add(function () {
// Required for SVGForm
form.scope && form.scope(this);
const polygon1 = state.isPlaying
? createPlayIcon(150, 150)
: Rectangle.polygon(createStopIcon(100, 100));
form.fill("#fff").polygon(polygon1);
});
// Doesn't work in SVGCanvas
space.add(function () {
// Required for SVGForm
form.scope && form.scope(this);
if (state.isPlaying) {
form.fill("#fff").polygon(createPlayIcon(300, 150));
} else {
form.fill("#fff").rect(createStopIcon(250, 100));
}
});
return state;
};
If you pass in a CanvasSpace
for space
, it works as expected, but when you pass in a SVGSpace
, it only renders the play button, even if state.isPlaying
changes.
You can see it running in https://codesandbox.io/s/ptsjs-svg-canvas-bug-m7f36
I'm guessing it's because of something funny going on with form.scope(this)
?
Hi @taktran , I tried a simplified version of your code and it seems to work like this:
Pts.namespace( this );
var space = new SVGSpace("#pt").setup({bgcolor: "#90f", resize: true });
var form = space.getForm();
const state = { isPlaying: true };
space.add({
animate: function (time, ftime) {
form.scope && form.scope(this);
if (state.isPlaying) {
form.fill("#fff").point(space.pointer, 50);
} else {
form.fill("#000").point(space.pointer, 50);
}
},
action: function (type) {
if (type === "up") {
state.isPlaying = !state.isPlaying;
}
}
});
A couple of suggestions:
- In your code, you're making 3
space.add(...)
calls, which means there'll be 3 players created. Not sure if it's what you want to do -- consider using only onespace.add(...)
like the above. - Try using normal callback like
action: function() {...}
instead of arrow functionaction: () => {...}
The SVG implementation in Pts is in early-stage and missing a lot of features. Please continue to send feedbacks and file issues :) Thanks!
Hi @williamngan , thanks for looking into it. Really ❤️ the API of pts.js btw 😄
I'm trying to figure out how to work with pts.js without using the global namespace. Is Pts.namespace
built to work with anything other than window
? Is this the code that sets up the namespace?
I think there is something that I'm not understanding about the difference between:
- Using the same
form
creation method (ie,.polygon
)
const polygon1 = state.isPlaying
? createPlayIcon(150, 150)
: Rectangle.polygon(createStopIcon(100, 100));
form.fill("#fff").polygon(polygon1);
// or
if (state.isPlaying) {
form.fill("#fff").polygon(createPlayIcon(150, 150));
} else {
form.fill("#fff").polygon(Rectangle.polygon(createStopIcon(100, 100)));
}
- Using different
form
creation methods (ie,.polygon
and.rect
)
if (state.isPlaying) {
form.fill("#fff").polygon(createPlayIcon(300, 150));
} else {
form.fill("#fff").rect(createStopIcon(250, 100));
}
An updated of the code example: https://codesandbox.io/s/ptsjs-svg-canvas-bug-2-or0wu?file=/src/create-shapes.js
consider using only one space.add(...)
Cool, it was mainly for demonstrative purposes, but it seems like I should restructure my code so that there are data transformation steps, and then have one player for the rendering step
Try using normal callback
Oh, I thought this was only relevant to the animate
property. It doesn't seem to change anything with action
- maybe because there is no use of this
?
Hi @taktran , I'm sorry that I totally missed your comment and late to respond.
I think there's a bug somewhere in the SVG scope that seems to clash with if/else statement. I'm going to mark this as a bug and investigate further. However, I am very busy these days, it might take me a while to get to it.
Re your question on "namespace", it's mostly a convenient method to "inject" Pts to a current scope like windows (or any functional scope). It's used for quick scripting. If you're using babel etc, you don't need it -- just use import statements instead.
Re your question on "form": The examples you give should be equivalent. "form" is just to visualize the "points" as rectangles, circles, etc. The bug in SVG might have confused you. Sorry. I would suggest using the canvas version as reference since it's way more stable.
Thank you for the bug report and detailed discussion. Cheers!