Comments (10)
Go back to using real DOM events, which is only acceptable if we find a way to not completely thrash performance with them.
how did you dispatch events? if you dispatch without bubble & compose then I would be surprised if it trashes performance? 🤔 - any way to test this?
from three-elements.
how did you dispatch events? if you dispatch without bubble & compose then I would be surprised if it trashes performance? 🤔 - any way to test this?
Bubbling was disabled (of course.)
Consider that this happens 60 times per second (or more, if you're on a higher-frequency monitor). If you have 1 element that hooks into this, that's 60 events per second -- not a big problem. But if you have 10, you're already at 600. If you have 100, at 6000.
With a normal EventEmitter pattern, 100 (or event many more) of these are not a problem at all, but going through dispatchEvent
quickly becomes problematic (starting with the hight number of objects created and ending with the relative overhead of the event dispatching mechanism.)
from three-elements.
If they're named ontick
then I would absolutely expect a tick
event to be fired that I could listen for traditionally - so I'd advocate either for renaming or finding a way to make it work.
Remove element-specific ticker event listeners, have only three-game emit ticks as proper DOM Events, and require that all per-frame code hook into that and only that. A pretty radical idea that would make things completely non-surprising at the cost of API approachability.
This feels like a good approach?
from three-elements.
This feels like a good approach?
I need to think about it some more. Semantically, it feels like a good change, since it is not the scene objects that are doing the ticking, they're just reacting on it. But the impact this would have on the overall approachability of the library worries me.
In the current setup, the most simple thing you can do to make a mesh spin is to just do this on the mesh element:
<three-mesh ontick="this.object.rotateZ(0.01)">
When you add a framework on top -- let's use lit-html as an example -- you can do this, which sidesteps all the string attribute stuff:
<three-mesh .ontick=${(dt, element) => element.object.rotateZ(0.01)}>
And of course you can do it fully in JS-land, once you have a reference to the element:
element.ontick = () => element.object.rotateZ(0.01)
But -- today -- you can also directly subscribe to the game's eventemitter:
element.game.emitter.on("tick", (e) => e.target.object.rotateZ(0.01))
If we implement a change like the one we're talking about, the user would be forced into JS-land to do something like the following as the only option available to them, and do their own lifecycle management on top:
element.game.addEventListener("tick", (e) => e.target.object.rotateZ(0.01))
tl;dr I'm not a fan, but I will think on it some more.
from three-elements.
I stand corrected... only dispatching the event makes the code already sooooo much slower (~99% slower 😱 )
https://jsbench.me/qmkkfcfpcw/2
Knowing that my gut feeling would vote for an callback name + using a lib to set it as a property
<three-mesh .tickCallback=${(dt, element) => element.object.rotateZ(0.01)}>
and if you really want it to work with attributes alone... then it might be a good idea to follow the data-*
or svg like stroke-width
pattern to make it clearly different then the property. I would even go as far as adding a separate attribute like use-unsafe-attributes
(name to be discussed) to enable this behavior
<three-mesh use-unsafe-attributes tick-callback="this.object.rotateZ(0.01)">
from three-elements.
if you really want it to work with attributes alone
There might be a misunderstanding here. This is certainly not the case. I also want to support setting ticker callbacks as attributes; I certainly don't want to make it the only option.
vote for an callback name + using a lib to set it as a property
This is already very close to (if not the same as?) what I'm doing today, except of course for using on*
names, which would need to be changed (see the second option from my list at the bottom of the original post.) If I had to make a decision right now, this would be my preferred option.
from three-elements.
Current favorite, after some thinking: update
, update.late
, update.frame
, update.render
and later update.[customname]
(when we allow users to expose additional ticking stages.)
The dot-less version being the default per-rAF tick.
Doesn't have to be update
, can also be tick
, or callback
, or something else, as long as it doesn't start with on
.
from three-elements.
I'm getting ready to implement this, but I've moved away from the "dotty" syntax. The goal is to implement the following properties on ThreeElement to replace ontick
, onlatetick
etc.:
tickUpdate
tickLateUpdate
tickFrame
tickRender
And also the following attributes that map to the above properties:
tick-update
tick-late-update
tick-frame
tick-render
This checks the following boxes:
- The naming is aligned with custom element conventions (kebab-case attributes mapping to camelCase properties)
- It no longer causes confusing by properties/attributes'
on*
naming suggesting that there are DOM events of the same names that you could listen to (there are not, and they're not coming back as long as dispatching a massive amount of DOM events is multiple orders of magnitudes slower than using an EventEmitter pattern, sorry) - It doesn't actually change any of the functionality that is on place now; we're just renaming things
- It leaves the door open for future tick callback types that user may be adding, like
tick-physics
ortick-animation
, if we ever do such a thing on a property/attribute level - It doesn't change the fact that you can (and always will be able to) hook into ThreeGame's emitter directly, which you will most likely do instead of setting element properties or attributes in non-trivial, JS-driven projects.
Note how I've literally added checked boxes. I'm good.
from three-elements.
The above patch implements this, with the addition of tick
being available as a shortcut for tickUpdate
, since this is the most common callback to hook into. Closing this, thanks to everyone who gave feedback!
from three-elements.
I've done another pass on this, the properties are now tick
, lateTick
, frameTick
and renderTick
, and the attributes tick
, late-tick
, frame-tick
and render-tick
. I think it's good now!
from three-elements.
Related Issues (20)
- 'getThreeObjectBySelector' only works on light DOM HOT 1
- Custom camera issue HOT 1
- Directive collision HOT 1
- Projected pointer position isn't recalculated when pointer doesn't move
- BaseElement.setAttribute should track super.setAttribute succes/failure
- Generate TypeDoc and deploy it to website HOT 2
- 🐞 "pointerenter" and "pointerleave" should also be triggered on groups containing the raycasted object HOT 1
- Allow setting of "deg(n)" in numerical attributes
- Set up CI test matrix to test three-elements against different versions of Three.js HOT 2
- Support bracket-less array syntax for "args"
- Convert repository into monorepo HOT 2
- 0.3 Release Checklist
- [core] Support MutationObserver behind a flag HOT 5
- [core] Similar to `tick` `late-tick` etc., also offer `mount` and `unmount` (or similar) HOT 2
- [core] Provide a way to customize which elements get created HOT 1
- [proxy] Improve proxy typings
- [core] Explore how we can integrate shaders and three-elements HOT 1
- [core] When handling click events, make sure a raycast has been performed this frame
- Restructure repository; create "extras" package
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from three-elements.