html-next / smoke-and-mirrors Goto Github PK
View Code? Open in Web Editor NEWAmbitious infinite-scroll and svelte rendering for ambitious applications.
Home Page: https://html-next.github.io/vertical-collection/
License: MIT License
Ambitious infinite-scroll and svelte rendering for ambitious applications.
Home Page: https://html-next.github.io/vertical-collection/
License: MIT License
It's likely we'll need to update MagicArray, ProxiedEach, and OcclusionCollection to have MagicCollectionView
's intended behavior.
The desired API for using the occlusion-collection
is
<occlusion-collection
model as |data|
containerHeight=gridHeight
class="grid-body spec-ticket-list print-hide"
defaultHeight=30
bottomReached="loadMoreTickets"
>
...
etc with {{data}} as context
...
</occlusion-collection>
Scroll position isn't maintained during a prepend if the height of the new page is much larger than that of the current page.
Suppose that there is 1000px of scrollable area. If there is 300px of content on a page when a prepend is triggered and the height of this new content is 2000px, then the required scroll position to maintain the top visible element in the original place is greater than what the viewport can fit.
In short, this case arises when transitioning from contentHeight > viewportHeight to contentHeight < viewportHeight.
Is there any way to use this in a non-CLI project?
I am fairly new to the Ember and cant use CLI for requirements reasons. There doesnt appear to be much in the way of doing cloaking in "regular" Ember projects.
This leads the scrolling to become blank and take a while to catch up to the user.
It appears that during a model transition for a route there are some situations that prevent the topmost item from updating to the new model's content. This wasn't consistently occurring, and hasn't occurred since recent updates to magicArray, but I'd like to leave this here in case anyone else bumps into the same issue again.
When 2 planets have the same dimensions and locations, getZones fails:
ie.
planetA = planetB;
var results = planetA.getZones(planetB);
// expected result is {zoneX: 0, zoneY: 0, ...}
but result is {zoneX: 1, zoneY: 1, ...}
this bug is from lines 85 and 86 of addon/models/geography.js
because distanceX === planet.height
This is a meta ticket for tracking fastboot support.
In fastboot mode:
window
document
self
document.body
requestAnimationFrame
getBoundingClientRect
localStorage
document.createElement
element.append
addEventListener
/removeEventListener
document.title
and similar (soon to be used by the extended-router
)I'd be happy to submit a PR for any or all of the above items if you approve, with the exception of the animation section since I don't have the requisite knowledge.
I'm getting this in my Ember 1.12.0 app:
Path or pattern "bower_components/animation-frame/AnimationFrame.min.js" did not match any files
Something weird is happening with addBowerPackagesToProject
and switching to addBowerPackageToProject
doesn't help either.
When there are culled items above the current scroll position, scrolling causes the elements to be pushed down by the height of one element for a brief moment. The final scroll position is correct though.
With the addition of the <pre-render>
component, it is now possible to calculate exactly how tall or wide an item being added to the collection will be before inserting it.
To better support dynamic layouts, when alwaysUseDefaultHeight
is false
, previously un-rendered items will render into a <pre-render>
component first to calculate final size. If any img
tags are found within the component's generated markup, didPreRender
will be upgraded to wait to fire until those image's dimensions are known. You can speed this process by directly setting the width
and height
attributes on an img
.
In order to support this, a new nextFrame
queue system needs to be developed to ensure that changes to scrollTop
height
and the insertion
happen in the correct order and within the same frame (to prevent flickers). See #51.
There is currently a flicker when prepending new items to a collection. This flicker occurs because wrapper components are inserted into the collection in a different frame from the one in which scrollTop
is modified. To fix this, we need tighter control over frame scheduling.
scheduleIntoFrame
gives you access to a frameQueue
, similar in nature to backburner.schedule
(Ember.run.schedule
). This queue must be manually flushed, at which point it's work will all be performed in the nextFrame
.
We already auto-add the following rules to the container
'-webkit-overflow-scrolling': 'touch',
'overflow-scrolling': 'touch',
'overflow-y': 'scroll'
We should warn if the following aren't true while in development.
display: block
height: x
max-height: x
position: relative
The same is probably true for GPU Acceleration. Instead of auto-adding it, we should warn if it's not present during development.
With the shift to components and glimmer support, the 3 observers currently used to curry information where computations were only passively consumed previously can likely be changed to computed properties.
Very little of the vertical-collection
code is explicitly designed for vertical
scrolling. These parts should be abstracted to make a companion horizontal-collection
easy.
Features that need abstracted
Hi
I was just checking the infinite scroll demo here,
http://runspired.github.io/smoke-and-mirrors/#/infinite-scroll
I noticed some views are still being hidden when scrolled randomly up and down, even when they are in the viewport. The top view div is changing to visible as expected but its the inner view which is still being hidden.
It would be nice if you can look into this, as I am looking this as an alternate to ember-cloaking for my app.
Thanks.
I tried out occlusion-collection and it doesn't seem to work when the whole page is scrolled, like on discourse. It seems that scroll events are not triggered by regular div containers on the page. Additionally, even if the scroll events are triggered, it seems that the viewportTop is wrong?
If the collection is given an array that's shorter than it's visible area, it won't display them all. This may have been fixed by removing the "cap to bottom" on the edges check, but I'd like to leave this here until that's certain.
Code snippet has stopped working for the example app.
Note: See #98 for Implementation Progress
The vertical-collection
is currently fast enough that the initial render improvements in glimmer 2
should put an end to any noticeable lags.
Even still, we always want to push faster and support more features such as #52 (dynamic height insertions).
This ticket is a ROADMAP that takes the collection through 3 internal revisions.
Revision 1
<pre-render>
returning parent dimensions instead of child dimensions.<pre-render>
to accept a style object to render into instead of requiring an explicit parent
.<pre-render>
to pre-render multiple items at once.margin
is accounted for in a vertical-item
's Geography
Revision 2
virtual-item
Geography
Satellite
index
virtual-item
instead of vertical-item
, will require linking the twoRevision 3
vertical-item
s with virtual-item
s only
vertical-item
should not output DOM within the collection
, but essentially be a tagless pre-render
.vertical-items
for virtual-items
that are on screen.vertical-items
to match the height of remaining virtual-items
vertical-items
where possible, but don't rely on pre-calculating the number needed, just use what we have + create new / remove if more items become visible than we had before.The collection should be able to work with body
as the container.
It doesn't look like the dependency on the animation-frame package is declared anywhere in package.json or bower.json, so unless it's installed manually, a consuming application will fail to build.
Thanks for your work on this project. There's a lot of very exciting stuff here, and I hope to see and be a part of future iterations.
Sidenote: Is there a reason the project doesn't have a bower.json file?
In my app firstVisibleChanged
no longer triggers reliably, and lastReached
only triggers once. Any subsequent pages aren't loaded. The regression is in commit 5287871.
Using Ember 1.13.10.
EDIT: Fixed in 0.3.3
There is an edge case that the current logic doesn't handle. If the estimated height of the views to be prepended exceeds the current maximum scrollTop value, that difference is lost.
For instance, if there is 1500px of content in a 700px viewport, the max scrollTop value is 800px. If the scrollTop is 0px and more content which has a estimated height of 1500px is about to be prepended, the scrollTop is set to 1500px, which exceeds the 800px maximum, resulting in a 700px difference between the final scrollTop and the correct final scrollTop.
A possible fix would be to adjust the scrollTop after the items are inserted instead of before. Any other ideas, @runspired ?
Hi!
I'm having difficulty getting my Ember Acceptance tests to pass once I start using the VerticalCollection in 0.3.6.
Here is a simplified version of my test
visit '/page' // Page loads and renders vertical collection for the first time
andThen ->
click('.changeArrayContents') // Changes the contents of the array bound to the vertical collection
andThen ->
On the final andThen
I get the following
Assertion Failed: You have turned on testing mode, which disabled the run-loop's autorun.
You will need to wrap any code with asynchronous side-effects in a run
Adding a breakpoint shows that occulusion-collection#_updateChildStates
gets called which in turn calls
this.sendActionOnce('firstReached', {
item: component,
index: bottomComponentIndex
})
which triggers the error above.
Am I using the collection incorrectly?
Maybe I need to make use of this option?
/**!
* Set this to false to prevent rendering entirely.
* Useful for situations in which rendering is
* expensive enough that it interferes with a
* transition animation.
*
* In such cases, set this to false, and switch it
* to true once animation has completed.
*/
shouldRender: true,
Thanks!
Unconfirmed if this is an issue with the vertical-collection
or a specific app's implementation but the preliminary investigation indicated it was the collection.
When transitioning away from a route with the vertical-collection
on it, there is a major GC cycle to cleanup a ridiculously large number of listeners. This can lead to a slow transition, or a choppy liquid-fire animation. If this is an issue with the collection it needs addressed.
The infinite-scroll demo should be a good enough re-creation of the setup from the app this was observed in to diagnose if this is an issue with the collection itself.
Infinite scroll only loads more content above if you scroll up, but as there's nothing above to scroll into at first there's no way to scroll up. In order to load content above, you need to scroll down a little and then up again to kick it into action.
Maybe there should be a small buffer added to the top, then when rendering initially scroll down to the starting point so there's always a small area to scroll upwards.
Playing around with smoke-and-mirrors in my app it seems there is an issue when an item is deleted and replaced with a new item. Looks as if the list knows there is an item there, but doesn't know it should be revealed until there is a scroll event.
You used to be able to do this
var A = Ember.ArrayProxy({ content: myArray });
A.contentArrayDidChange = fn;
The instantiated class no longer copies to the outer object in a manner allowing this behavior to work.
This behavior changed somewhere after ember 1.11.1
.
This is the underlying issue being observed in issues #11 and #18
Likely we need to add a few pixels to the test for the topmost or bottom most element as an error buffer.
Hi,
Can someone guid me how to create a simple infinite-scroll with ember-data?
I receive: Cannot call get with 'content' on an undefined object . It suposed to work with an array of objects only, so I need to create a controller to get data from my model?
May be I do not understand very well how is suposed work. I apreciate some hints
Now that the APIs / features are starting to stabilize, I'd appreciate some help with test coverage (of which there is currently none).
Largely stable features:
Any features that aren't stable won't be exposed in /app
during a release.
Hey, this is really exciting. I'm trying to follow some of your performance tips, you mention background loading, could you share a code example?
Would also be great to see one with Ember.run.schedule. I'm not sure which parts of my code could benefit from it.
This worked in the 0.2.0 series, and is a 0.3.x series regression, likely do to the introduction of position tracking over use of jQuery.position.
While the infinite-scroll demo works nearly flawlessly, I've come across a few issues with the occlusion-collection which can be reproduced in the DBMon - Occlusion demo. When scrolling, sometimes rows disappear and fail to return until further scroll events are fired, and sometimes the scroll position jumps back to the top of the table.
The vertical-collection
and the upcoming horizontal-collection
should both support grids.
Currently grid support can be achieved by splitting your content into rows beforehand and treating each row as an individual item (or column). This degrades the consumer experience by requiring extra work and extra DOM elements to accomplish what a few CSS styles would have given you out of the box.
The collection
components should support float
s and margin
s as well as multiple items per pixel offset. Going in hand with these changes, the upgrades in #70 will allow use of float
directly on your content instead of on the vertical-item
wrappers.
Can be implemented now:
_findFirstRenderedComponent
should crawl up the component list after a resolution to check for additional components that should be rendered in case the binary search landed in the middle of a batch of items at a similar offset.defaultWidth
needs to be addeddefaultMargin
needs to be addedFor later:
vertical-item
wrappers #70filler
divs above and below the visible content.Hi!
When I scroll down my list (using 0.3.6), select a list element, the scrolling jumps back up to the top.
Not clear if this is a bug or just me not configuring it correctly.
{{#vertical-collection
defaultHeight=60
alwaysUseDefaultHeight=true
visibleBuffer=2
useContentProxy=true
containerHeight=2000
content=filteredContent
as |chatParticipant| }}
{{cvr-chat-participant
chatParticipant=chatParticipant}}
{{/vertical-collection}}
During setup
on the vertical-collection,
childForItem: function childForItem(item) {
var val = get(item, this.get("keyForId"));
return this.get("_children")[val];
}
returns undefined
, because this.get("_children") === {}
. I don't see _children
updated anywhere other than in _prepareComponent
, where it's set to {}
, so I'm not sure what's supposed to be in it other than something like {"keyForIdVal": someRepresentationOfAnObject, ...}
.
From What I've been able to determine, the overall call stack in question is setup()
--> _initializeScrollState()
--> _cycleViews()
--> _findTopView()
--> childForItem()
, whereupon it dies.
I'd be happy to try to fix this, although I'm not sure what the end case should be. Should _children
be {keyVal: childComponent, ...}
?
For what it's worth, I'm currently calling vertical collection like this:
{{#vertical-collection
content=discs
keyForId="id"
defaultHeight=350
as |disc|
}}
{{m-disc-li disc=disc}}
{{/vertical-collection}}
Best.
idForFirstItem
isn't working - it always starts at the top of the listfirstReached
doesn't trigger upon initializationTypeError: Cannot read property 'shift' of undefined
at adjustPositions (http://localhost:4200/assets/vendor.js:86881:22)
at resize (http://localhost:4200/assets/vendor.js:86830:22)
at _updateHeight (http://localhost:4200/assets/vendor.js:85109:35)
at _ov_obscure (http://localhost:4200/assets/vendor.js:85125:12)
at _setState (http://localhost:4200/assets/vendor.js:85057:40)
at cull (http://localhost:4200/assets/vendor.js:85034:12)
at http://localhost:4200/assets/vendor.js:84355:11
at Array.forEach (native)
at _removeComponents (http://localhost:4200/assets/vendor.js:84354:14)
at Object.Backburner.run (http://localhost:4200/assets/vendor.js:10767:25)
Radar
should add another scroll listener to document.body
if not already attached and use it to update the various Geography
instances.
occlusion-collection
Should reorder existing views if it's views are sorted in order to maintain glimmer + liquid-fire animation capabilities.
When scrolling very quickly to the top or bottom of content, the occlusion-collection can lose track of which elements should be visible, which causes the scrollable area to appear blank. The browser console reveals that the elements that should be visible are hidden while other offscreen elements are not. Any further scroll events correct the issue.
There appear to be a couple of factors that influence this behavior - 1) the scrollThrottle
and momentumScrollThrottle
parameters, and 2) the time it takes to render each view in the occlusion-collection. So, taking steps to decrease these values appears to be the best course of action for anyone affected by the issue.
I'll add this to the docs on occlusion-collection if you agree it would be useful. Are you aware of any other factors that would influence this behavior? I have yet to experiment with setting the loadingViewClass
to see how that might interact with it.
Edit: Looks like momentumScrollThrottle
was removed. I'll prune it from the documentation in an upcoming PR if you don't get to it first.
Dependencies:
"smoke-and-mirrors": "0.4.4"
Ember Data 2.2.0-beta.3
Ember 2.2.0-beta.2
When using vertical-collection components with an array of ember data models as the collection I'm observing that if you pass the iteration item into a link-to helper, the transition will occur successfully but the model hook for the route is invoked.
This happens when you use useContentProxy=true or useContentProxy= false and it doesn't seem to matter if you pass the item into the link helper or item.content
Thanks for all the hard work!
Opening this issue until runspired/ember-run-raf#2 is resolved.
This issue can be reproduced in the proxied-each, occlusion-collection and infinite-scroll demos.
Reported by @aquamme, This may be implementation specific. key="id"
was in use, visually it appeared no additional firstReached
events would fire.
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.