shukantpal / pixi-essentials Goto Github PK
View Code? Open in Web Editor NEWThe best goodies for performant, enterprise-level applications built on PixiJS
Home Page: https://api.pixijs.io
License: MIT License
The best goodies for performant, enterprise-level applications built on PixiJS
Home Page: https://api.pixijs.io
License: MIT License
Hi @ShukantPal , just a question; when zoomed in we can see the sample points pixi-essentials uses to draw paths. Is there currently a way to set (in this case increase) the amount of sample points/resolution for 'rendering' the graphics?
Thanks in advance!
Currently,
When you start a transformation, the cursor based on the component hover logic.
Expected behavior:
When you start a transformation, the cursor will be static based on the started transformation.
Like fabricjs does https://codepen.io/agenziabrand/pen/XWrVoqj
Transformer imports @pixi/interaction, but it was deprecated (as i understand) for pixi 7. At least i cant find version for pixi 7. That line broke all mouse behaviour. Looks like interactive = false
, but it's not true.
I did monkey-patch for 3.0.1, just remove require('@pixi/interaction')
from assembled js file. And all will works fine.
codepen works well on 3.0.1 and 7.2.4 pixi, because that code (header from transformer.js) in reality doesn't do require('@pixi/interaction')
in browser.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@pixi/interaction'), require('@pixi/display'), require('@pixi/math'), require('@pixi-essentials/bounds'), require('@pixi-essentials/object-pool'), require('@pixi/graphics')) :
typeof define === 'function' && define.amd ? define(['exports', '@pixi/interaction', '@pixi/display', '@pixi/math', '@pixi-essentials/bounds', '@pixi-essentials/object-pool', '@pixi/graphics'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global._pixi_essentials_transformer = {}, null, global.PIXI, global.PIXI, global.PIXI, global.PIXI, global.PIXI));
}(this, (function (exports, interaction, display, math, bounds, objectPool, graphics) { 'use strict'; })));
As fix:
Is it okay to just drop @pixi/interaction
import?
cc
#84
Hey @SukantPal, what's up?
Do you have plans to implement support for multi-channel signed distance field text?
Using atlas bitmap and atlas's layout data (e.g. json) from this generator.
Other repositories that have implemented this for pixi seem to be out of date.
When importing the library using
import { Transformer } from "@pixi-essentials/transformer";
I get the following error:
Could not find a declaration file for module '@pixi-essentials/transformer'
Browsing to @pixi-essentials/transformer directory (inside node_modules) I see that indeed @types directory is missing.
Whatever I try, I can't get pointer events to work when adding an SVGScene to the stage. Whatever else I add to the stage works interactively fine and also the stage itself fires events just fine, but for some reason not the SVG Scene. Interactive of the scene is set to true
tho (also tried buttonMode just to be sure)
I tried several event types, like pointerup
, tap
and click
. Also tried both .on()
and .addListener()
on both the SVGScene object (which is extended from DisplayObject) as well as the svgScene.root
just to be sure.
Also created a complete fresh project with only pixi in it, just a stage and only the SVGScene added to it. But nothing seems to work.
According to the docs the events should be supported, so I don't get this.
Is there anything we should know, other than settings interactive to true, to make interactivity with pointers work?
As title says: SVG Elements with transparency, using fill-opacity attribute, are imported with fully opaque fills instead of (semi-)transparent. This breaks the design.
@pixi-essentials/svg: v1.1.5
I've set a displacementfilter on an SVGScene. When changing the displacement texture on a tick the SVGScene needs to update, but doesn't do that. I've tried setting _transformDirty = true;
of the scene on each tick but it doesn't update the rendering.
How can we update the effect of filter(s) on the SVGScene?
Thanks in advance!
this.width
, this.height
is the local bounds of the SVGScene (after multiplying by the local scale). It should rather than use context.viewBox.width/height
.
index.html
`
script.js
`const app = new PIXI.Application({
width: 1024,
height: 1024,
autoDensity: true,
resolution: window.devicePixelRatio || 1,
view: document.getElementById("pen-canvas"),
backgroundColor: 0xffffff,
antialias: true
})
app.stage.sortableChildren = true;
const transformer = app.stage.addChild(new PIXI.Transformer({
rotateEnabled: true,
skewEnabled: true,
boxRotationEnabled: true,
group: [],
stage: app.stage,
wireframeStyle: {
thickness: 1,
color: 0xff0000
}
}));
const circle = new PIXI.Graphics();
circle.beginFill(0xfedbac + 0x1f)
.drawCircle(0, 0, 100)
.endFill();
circle.pivot.set(50, 100);
circle.scale.set(1);
circle.position.set(300, 300);
const star = new PIXI.Graphics();
star.beginFill(0xfedbac + 0x1f)
.drawStar(0, 0, 8, 100)
.endFill();
star.position.set(800, 500);
star.pivot.set(50, 100);
const starText = star.addChild(new PIXI.Text("Hello world!", {
fontSize: 12
}));
starText.x = -30;
const container = new PIXI.Container();
container.addChild(star);
container.addChild(circle);
container.eventMode = 'static';
container.interactive = true;
container.on('pointerdown', onClick);
app.stage.addChild(container);
function onClick(event) {
console.log("clicked:" + event.target);
if (transformer.group.length > 0) {
let oldTarget = transformer.group.pop();
oldTarget.interactive = true;
}
transformer.group.push(event.target);
transformer.zIndex = event.target.zIndex;
event.target.interactive = false;
}`
In index.html
change line 11
to
<script src='https://pixijs.download/v7.1.4/pixi.min.js'></script>Changed this line, the object can be dragged normally
First of all; thanks a lot for this great project! It's so nice to be able to use SVG inside pixi while keeping it sharp while zooming!
I want to change properties of a child inside the SVG Scene, like its fillColor. I found out how to do that, but having a huge SVG how can we find the right child by its ID as set in the SVG Elements ID attribute? I've searched through the properties of for example the SVGPathNode
class, but so far I couldn't find anything that tells the actual ID/name of the child.
So my question is: where is the ID stored inside a child and/or how to find a child by it's original element's ID?
Thanks in advance!
To my surprise the rendering of rounded linejoins are different when using pixi-essentials compared to the original design file and compared to the SVG file rendered in the browsers.
So I took a look at this a little closer and did some tests to find out that stroke-linejoin isn't rounded if stroke-miterlimit is below 2 (in this test). This isn't an issue when using the svg in the browser and also in the used vector editor (Affinity Designer) it's shown as a rounded corner as expected. So it seems like pixi-essentials' render isn't rendering linejoins as supposed to.
Please take a look at the following example on codepen: the image above is the pixi renderer, the image below is the svg directly shown inside the document. As you can see in the essentials output the rounded join is gone, while it's rendered fine in svg:
https://codepen.io/Friksel/pen/LYeYpQZ
When either removing the stroke-miterlimit="1.5"
from the <svg>
or changing it to stroke-miterlimit="2"
the corner is rounded, but this obviously shouldn't be necesary and work with intended values.
According to mdn the stroke-miterlimit
could make the line join to fall back to bevel
, but only when exceeded (so higher than a certain value), not when lower than the limit. So perhaps this is build in pixi-essentials the reversed way now?
I would expect for the rest the miterlimit value should be ignored when below that value and have no influence.
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linejoin :
Images:
This should be in the else block:
There doesnt seem to be a license file available in the project. Can you clarify the license please and maybe add a MIT license file (according to setting in package.json)?
Is this correct?
it seems like you switched x and y with the paintTexture width and height in two lines.
See svg's below. When having a rectangle reaching full svg bounds and subtract a circle from it and save that to svg the fill will be flipped when loaded with pixi-essentials/svg. This is not the case when the rectangle is just 1 pixel away from the svg bounds.
That last thing we obviously don't want. We want to cover the bounds of the svg.
svg with issue in editor (screenshot):
svg with issue in pixi-essentials (screenshot):
svg without issue (borders have padding from svg bounds) in editor (screenshot):
svg without issue (borders have padding from svg bounds) in pixi-essentials (screenshot):
svg file with issue (downloadable):
svg where issue is not there because the shape has a padding on each side (downloadable):
pixi-essentials/svg version: 1.1.5
Hi again!
I will refer to movement/scale/rotation/skew as operations for brevity.
As of right now, the Transformer handles all inputs and operations by itself, but it would be nice to be able to handle some more interesting cases. Here are the main options i'm missing, forgive me if they are already present and I simply did not find them.
It would be very useful to have a callback after the changes are computed but before the actual transform is performed, to be able to handle some more interesting logic.
Some use cases that would be enabled are:
Ideally, one such callback would take as input the delta of the current frame and the delta since the beginning of the event and be able to make any change to the operation.
Please excuse the very crude example.
interface IScale {
x: number
y: number
}
interface IDelta {
x: number
y: number
scale: IScale
angle: number
}
interface IChangeCallback {
operation: string
frame: IDelta
total: IDelta
}
type IChangeCallbackFunc = (IChangeCallback) => IChangeCallback;
Let me know what you think about it
Steps:
1 Add objects and transformer
2 Start to transform object (not from corners), release the mouse NOT over handler knob.
3 Transformer will stay in the transform mode.
as shown in the figure, an exception is displayed when rendering a large svg path.
pixijs version: 6.2.0
pixi-essentials/svg version: 1.1.5
svg content: panda.svg.txt
Hello,
My team is using the texture-allocator package and see that it is pulling in pixi.js v6. Is there any kind of planned upgrade path to update the pixi-essentials modules to v7-compatible releases?
First of all thanks for that great tool.
I am using tool to manipulate object transform in my scene for deeply nested objects. If group includes objects those have different parents, objects transform in their local space but tool manipulate them using its own local space calculation I think.
To clearify the issue you can check this demo
https://codepen.io/sukantpal/pen/dyMMmZm
Just set parent of star object to circle instead of app.stage and then try to move them
There is a Typescript definition error in the index.d.ts file
[ng] Error: node_modules/@pixi-essentials/svg/index.d.ts:396:9 - error TS2611: 'currentPath' is defined as a property in class 'SVGGraphicsNode', but is overridden here in 'SVGPathNode' as an accessor.
[ng] 396 get currentPath(): any;
fix:
// @ts-ignore
get currentPath(): any;
This causes adverse side-effects, like translations not moving in sync with the cursor when the projection is non-identity.
Hi! As the title says, the transformer scale/rotate/skew actions don't work properly on mobile.
I've tested both the provided pen examples
Standard usage: https://codepen.io/sukantpal/pen/dyMMmZm
Usage with @pixi-essentials/react-bindings: https://codepen.io/sukantpal/pen/ZEWWoWX
and made a little test of my use case here https://codepen.io/thanzex/pen/JjpJQMd
On mobile the translation works fine, but I cannot scale or rotate the box, dragging any of the handles just moves the whole box or in some cases scales only along one axis, despite having set lockAspectRatio
to true
.
This behaviour can be observed also using a normal browser with the responsive developer tools.
There is a bug in the svg.js and svg.es.js files where it is passing a null element as shape:
line 1277:
buildDashedLine(
// @ts-expect-error
{
points: contour,
holes: [],
shape: null,
lineStyle,
},
this,
);
probability this can fix it:
buildDashedLine(
// @ts-expect-error
{
points: null,
holes: [],
shape: { points: contour, type: SHAPES.PATH },
lineStyle,
},
this,
);
sample svg file:
<svg viewBox = "0 0 540 360" version= "1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="none" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M126.23808,121.88715l6.99691,-2.99723l12.6611,-4.66235l16.99251,-6.6605l20.6576,-9.99075l23.65619,-11.32285l24.32263,-8.99167l23.32306,-6.32747l21.9903,-3.99631l10.66199,-1.66512l20.65756,-2.6642l28.65405,-1.99815l33.98502,0.66605l12.32788,2.33117l6.99695,2.33118l2.99865,1.66513l5.33103,3.33025l5.99734,4.99537l6.6637,6.32747l6.99695,10.98982l1.66598,4.66236l3.33182,15.65217l0.66638,12.98797l-0.33313,16.65125l-0.33325,8.99167l-5.66418,26.97504l-7.66324,18.31636l-8.66285,16.31824l-8.66293,12.98797l-7.66324,9.3247l-6.99695,7.32655l-18.65844,12.65498l-11.99472,4.66236l-14.32703,3.3302l-14.32703,2.33117l-12.32788,1.66516l-11.66153,0.99906l-11.6615,0.66604h-14.32705l-12.32788,-1.6651l-7.33008,-3.33026l-3.33191,-2.33117l-6.33054,-10.3238l-2.3323,-10.65679l-0.33319,-13.65401l3.66504,-24.31084v-4.99538l-0.33319,-3.33026l-0.66636,-2.33116l-0.99954,-1.66513l-16.65936,1.33211l-9.99555,3.99629l-27.98767,16.9843l-12.32794,8.65863l-19.32483,12.98798l-9.32922,5.66142l-7.99648,4.99538l-7.99647,5.32838l-7.33011,4.32933l-2.99867,1.99815l-9.66242,3.99631l-9.32922,2.66419h-9.66242l-5.66416,-0.99903l-4.66462,-1.99817l-7.66328,-5.32843l-5.99736,-6.66047l-2.6655,-3.99633l-1.66592,-3.33021l-1.66593,-5.99449l-0.33319,-7.99257l5.331,-24.64386l5.33096,-14.32009l1.66594,-3.66325l1.66594,-3.66328l7.66328,-9.65775l3.66506,-3.99629l1.99913,-1.66512l40.64874,-43.95929l0.99957,-0.33303z" stroke="#a0a0a0" stroke-width="1.6875" stroke-dasharray="6.75,25.3125" stroke-dashoffset="0"/></g></svg>
The controls are being displayed but I cannot interact with them, even on hover the cursor wouldn't change. I tried it with all kinds of settings. The same code works perfectly with v3.0.0
There is an issue in the lib that, after doing some research on Typescript, wasn't an issue with Typescript 3 compiler, but is with Typescript 4 (https://stackoverflow.com/questions/63750710/ts2611-foo-is-defined-as-a-property-in-class-a-but-is-overridden-here-in)
I'm working in Javascript myself, but the document builder I use to build documents for projects is using Typescript 4. Which is now stopping at the issue making the project build to fail because of this issue in the lib.
For now I downgraded the project to use the old Typescript 3, but that's obviously not the preferred solution.
Could this issue either be solved? And could you perhaps please upgrade to Typescript 4 to have the latest checks in place? That would be awesome!
I had to triple check a few times, but I noticed that the documentation for essentials is on the pixi.js domain (ex, https://api.pixijs.io/@pixi-essentials/svg/Path.html). However, the github repositories are not part of the github organization (i.e. https://github.com/pixijs/). It would be nice if that relationship is more clear. If it was official, then it would signal some kind of longevity and continuity.
Currently, the PaintServer is using the gradients package, which seems fine but it ignores all Transform Properties in the "gradientTransform" attribute.
I have tried to fix this on my own to first apply the transform matrix to my coordinates before submitting the SVG to the SVGScene, but I'm not a mathematician, and it's only near perfect but not close enough for one on one comparison with the browser, maybe this is another problem with my SVG but "gradientTransform" is still missing anyway
I've tried multiple ways (such as attaching events, defining hitArea, trying hitTest and so...) to add interactivity to SVGScene output after loading it using @pixi-essentials/svg library but the events are never triggered.
How do we add interaction to the svg after loading it?
import { SVGScene } from '@pixi-essentials/svg';
//load svg from url
const svgMarkup = await fetch("<svg_url>").then((data) => data.json());
const svgDOM = new DOMParser().parseFromString(svgMarkup, "image/svg+xml");
const svgEl = svgDOM.documentElement;
//add svg to our scene - added event gets called
let svg = new SVGScene(svgEl);
svg.on('added', function(){
console.log('svg added');
});
//svg interactions - NOTE: Click/Mouse events are not triggered
svg.interactive = true;
svg.buttonMode = true;
svg.on('click', function(){
console.log('svg clicked');
});
svg.on('mouseenter', function(){
console.log('svg mouseentered');
});
The transformer works fine but only when the mouse stays within the handles. Any ideas what might be causing this?
I do have some mouse events on the stage, could that be doing something weird?
Hello,
Thanks for the module. Its exactly what I needed. Was wondering if there is a way to dynamically set the fill and line style outside of the actual SVG. I've tried updating SVGStage.root.children[0].fill
with no luck. Would like to avoid having to use a filter if possible.
Thanks!
Update: I dig into it a little bit and found that the
GraphicsData
parsed bySVGScene
will contain severalpoints
which isNaN
, which is likely the reason that makes the filling wrong
The background color and the rotation angle can be safely ignored, the main issue lands on the incorrectness of filling the red color
Source SVG:
clampy.svg.zip
https://replit.com/@ganeshgore/pixi-essentialssvg-showcase#script.js
without the following use tag, SVG loads fine
<use xlink:href="#circ" x="10" y="10" />
PixiJS Deprecation Warning: Setting interactive is deprecated, use eventMode = 'none'/'passive'/'auto'/'static'/'dynamic' instead.Deprecated since v7.2.0
This distance is in the world, not screen space.
./node_modules/@pixi-essentials/svg/lib/svg.es.js
Module parse failed: Unexpected token (2429:42)
You may need an appropriate loader to handle this file type.
| {
| const lastCommand = commands[i - 1];
| const lastCp2 = { ...(lastCommand.cp2 || lastCommand.cp) };
|
| if (commands[i - 1].relative)
looking for a working example of @pixi-essentials/svg (probably with zoom and pan feature)
We are trying to export the canvas to png using add.renderer.generateTexture
and app.renderer.extract
, but the svg object isn't showing in the image.
After digging into the source code and found out this line is causing the issue
pixi-essentials/packages/svg/src/SVGScene.ts
Line 177 in 0c61c08
By removing this line, the svg object now can export as expected
- this._cull.cull(renderer.renderTexture.sourceFrame, true);
Although the app works fine without this line, we are not sure wether if there's side effect or not.
Just a feature request, but: AFAICT there's no way to ensure the Transformer doesn't mess with the underlying object's aspect ratio. Would be very helpful.
Thanks for your hard work!
mousemove events on the stage no longer get called as soon as the transformer is rendered.
See this codepen for instance:
https://codepen.io/adamdsmith1729/pen/YzQXYgz?editors=0010
This doesn't seem to have been an issue in earlier versions (2.2.1) of the library.
Hello. I'm making a box selection system and found that the e.stopPropagation()
from the transformer prevents my callback to be run, so I modified the transformer to accept "attached callbacks" and run them on each of its internal callbacks.
Something like
this._attachedHandlers = {
'pointerdown': [],
'pointermove': [],
'pointerup': [(e) => console.log('pointerUp')]
}
onPointerUp(e) {
...
e.stopPropagation();
this._attachedHandlers['pointerup'].forEach(callback => callback(e));
...
}
Would it be a welcome addition? If so I could make a pull request once I'm done with it (properly typed and function-wrapped obviously).
Hey! Is there an event I can hook into to know when the transformer updates the properties (for example x or y)?
I need to update an input field where I show the current value and I'm not sure how I would do it.
Something like transformer.on('transform', () => ...)
maybe?
Not sure if #64 is related?
EDIT: Okay there is the transformchange
event I've overlooked, sorry! Now I only need to figure out how I can transform the matrix to the specific properties like x, y or rotation.
This causes issues when the world transform has changed and the bounds should be smaller. However, since the bounds are not cleared, the union of the old (bigger) bounds and the new (smaller) bounds equals the old bounds.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.