New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug: Graphics with only strokes that don't have a closePath, but an event is fired where a closePath would have been #10303
Comments
Share what I've debugged.
If closePath is false, that code => src\scene\graphics\shared\GraphicsContext.ts line @ 1156 |
Below is my custom eventable line code. Heavily depends on #7058 comments (v7) and migrated to v8. Because this is event-enabled code for graphics with only a single stroke & no fill, I haven't tested its suitability for some of the basic situations that pixi supports (with linecap, using with fill). It would be nice to see this as pseudo code for the adjustable width eventable line. export class EventableLine extends Graphics {
...
#contains(x: number, y: number) {
this.#hitAreaPolygon ??= this.#createHitAreaPolygon();
return this.#hitAreaPolygon.contains(x, y);
}
#createHitAreaPolygon(): Polygon {
const instruction = this.context.instructions[0];
if (instruction.action !== "stroke") return new Polygon([]);
const shape = instruction.data.path.shapePath.shapePrimitives[0].shape;
if (shape instanceof Polygon === false) return new Polygon([]);
const points = chunk(shape.points, 2) as [x: number, y: number][];
const lefts = [] as PointData[];
const rights = [] as PointData[];
// Until last point (skip last point to avoid writing conditional code)
for (let index = 0; index < points.length - 1; index++) {
const drawingVector = getDrawingVector(points[index], points[index + 1]!);
if (drawingVector.x !== 0 || drawingVector.y !== 0) {
const [left, right] = getLeftRight(
points[index],
drawingVector,
this.hitAreaWidth,
);
lefts.push(left);
rights.push(right);
}
}
// Last point
{
const drawingVector = getDrawingVector(points.at(-1)!, points.at(-2)!);
if (drawingVector.x !== 0 || drawingVector.y !== 0) {
const [left, right] = getLeftRight(
points.at(-1)!,
drawingVector,
this.hitAreaWidth,
);
lefts.push(right);
rights.push(left);
}
}
const hitAreaPoints = lefts.concat(rights.reverse());
return new Polygon(hitAreaPoints);
}
...
}
function getDrawingVector(
curPoint: [x: number, y: number],
nextPoint: [x: number, y: number],
) {
return subtractVector(
{ x: nextPoint[0], y: nextPoint[1] },
{ x: curPoint[0], y: curPoint[1] },
);
}
function getLeftRight(
curPoint: [x: number, y: number],
drawingVector: PointData,
hitAreaWidth: number,
) {
return orthogonalVectors(drawingVector).map((v) => {
const unit = unitVector(v);
const hitAreaVector = multiplyVector(unit, hitAreaWidth / 2);
return addVector({ x: curPoint[0], y: curPoint[1] }, hitAreaVector);
}) as [PointData, PointData];
} |
I rewrote eventable-line with almost copy & paste from To fundamentally fix the issue, might need to add export class EventableLine extends Graphics {
#strokeContains(x: number, y: number) {
const instruction = this.context.instructions[0];
if (instruction.action !== "stroke") return false;
const shape = instruction.data.path.shapePath.shapePrimitives[0].shape;
if (shape instanceof Polygon === false) return false;
const halfHitAreaWidth = this.hitAreaWidth / 2;
const halfHitAreaWidthSqrd = halfHitAreaWidth * halfHitAreaWidth;
const points = shape.points;
// skip last line segment => i < points.length - 2
for (let i = 0; i < points.length - 2; i += 2) {
const x1 = points[i];
const y1 = points[i + 1];
const x2 = points[(i + 2) % points.length];
const y2 = points[(i + 3) % points.length];
const distanceSqrd = squaredDistanceToLineSegment(x, y, x1, y1, x2, y2);
if (distanceSqrd <= halfHitAreaWidthSqrd) {
return true;
}
}
return false;
}
} |
Current Behavior
Graphics is not closed, but events are fired there as if there is a path to close.
Expected Behavior
Events should not be fired in areas where no strokes are drawn.
Steps to Reproduce
you can check running example codesandbox
Environment
pixi.js
version: 8.0.1Possible Solution
Might need to check if closePath was called.
Additional Information
I know that events were not supported in strokes only graphics in v7.
#7058
The text was updated successfully, but these errors were encountered: