1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-09-28 07:08:20 +00:00

Dynaview: Simplify visibility tracking logic

This commit is contained in:
Jermolene 2019-03-21 12:56:26 +00:00
parent 7709192cc8
commit 9f0d726f7d
5 changed files with 53 additions and 37 deletions

View File

@ -18,11 +18,14 @@ caption: {{$:/language/SideBar/Open/Caption}}
<$button message="tm-close-tiddler" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class="tc-btn-invisible tc-btn-mini">&times;</$button> <$link to={{!!title}}><$view field="title"/></$link> <$button message="tm-close-tiddler" tooltip={{$:/language/Buttons/Close/Hint}} aria-label={{$:/language/Buttons/Close/Caption}} class="tc-btn-invisible tc-btn-mini">&times;</$button> <$link to={{!!title}}><$view field="title"/></$link>
<$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix<currentTiddler>] }}}> <$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix<currentTiddler>] }}}>
<$reveal type="match" stateTitle=<<state>> text="true"> <$reveal type="match" stateTitle=<<state>> text="0">
<span style="display: inline-block; background: red; color: white; padding: 2px; border-radius: 2px;font-size: 0.5em;line-height: 1;text-shadow: none;font-weight: bold;vertical-align: middle;">LOADED</span> <span style="display: inline-block; background: red; color: white; padding: 2px; border-radius: 2px;font-size: 0.5em;line-height: 1;text-shadow: none;font-weight: bold;vertical-align: middle;">OUT OF VIEW</span>
</$reveal> </$reveal>
<$reveal type="match" stateTitle=<<state>> text="false"> <$reveal type="match" stateTitle=<<state>> text="1">
<span style="display: inline-block; background: green; color: white; padding: 2px; border-radius: 2px;font-size: 0.5em;line-height: 1;text-shadow: none;font-weight: bold;vertical-align: middle;">UNLOADED</span> <span style="display: inline-block; background: green; color: white; padding: 2px; border-radius: 2px;font-size: 0.5em;line-height: 1;text-shadow: none;font-weight: bold;vertical-align: middle;">NEAR</span>
</$reveal>
<$reveal type="match" stateTitle=<<state>> text="2">
<span style="display: inline-block; background: purple; color: white; padding: 2px; border-radius: 2px;font-size: 0.5em;line-height: 1;text-shadow: none;font-weight: bold;vertical-align: middle;">VISIBLE</span>
</$reveal> </$reveal>
</$set> </$set>
</div> </div>

View File

@ -8,9 +8,9 @@ caption: Contents
<$vars item=<<currentTiddler>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}} excluded="""[enlist<__exclude__>] -[<__tag__>]"""> <$vars item=<<currentTiddler>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}} excluded="""[enlist<__exclude__>] -[<__tag__>]""">
<li> <li>
<$link to={{{ [enlist{!!tiddler-list}] }}}> <$link to={{{ [enlist{!!tiddler-list}] }}}>
<$list filter="[enlist{!!tiddler-list}addprefix[$:/state/viewtemplate/visibility/]text[true]limit[1]]" variable="listItem" emptyMessage="""<div style="display:inline-block;width:4px;height:1em;background-color:transparent;"></div>"""> <$list filter="[enlist{!!tiddler-list}addprefix[$:/state/viewtemplate/visibility/]text[2]limit[1]]" variable="listItem" emptyMessage="""<div style="display:inline-block;width:4px;height:1em;background-color:transparent;"></div>""">
<div style="display:inline-block;width:4px;height:1em;background-color:red;"></div> <div style="display:inline-block;width:4px;height:1em;background-color:red;"></div>
</$list> </$list>
<$view field='caption'> <$view field='caption'>
<$view field='title'/> <$view field='title'/>
</$view> </$view>

View File

@ -12,14 +12,14 @@ $:/state/folded/$(currentTiddler)$
<div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class=<<frame-classes>>> <div data-tiddler-title=<<currentTiddler>> data-tags={{!!tags}} class=<<frame-classes>>>
<$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix<currentTiddler>] }}}> <$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix<currentTiddler>] }}}>
<$reveal stateTitle=<<state>> type="nomatch" text="" default="" tag="div"> <$reveal stateTitle=<<state>> type="nomatch" text="" default="" tag="div">
<div class="tc-dynaview-set-tiddler-when-visible tc-dynaview-expand-viewport" data-dynaview-set-tiddler=<<state>> data-dynaview-set-value="true" data-dynaview-unset-value="false"> <div class="tc-dynaview-track-tiddler-when-visible" data-dynaview-track-tiddler=<<state>>>
<$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"> <$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem">
<$transclude tiddler=<<listItem>>/> <$transclude tiddler=<<listItem>>/>
</$list> </$list>
</div> </div>
</$reveal> </$reveal>
<$reveal stateTitle=<<state>> type="match" text="" default="" tag="div"> <$reveal stateTitle=<<state>> type="match" text="" default="" tag="div">
<div class="tc-dynaview-set-tiddler-when-visible tc-dynaview-expand-viewport" style="min-height: 5em;" data-dynaview-set-tiddler=<<state>> data-dynaview-set-value="true" data-dynaview-unset-value="false"> <div class="tc-dynaview-track-tiddler-when-visible" style="min-height: 5em;" data-dynaview-track-tiddler=<<state>>>
</div> </div>
</$reveal> </$reveal>
</$set> </$set>

View File

@ -25,17 +25,24 @@ Optionally, ~DynaView can store the current scroll position in local storage and
Note that it is not recommended to use this setting at the same time as the "UpdateAddressBar" option. Note that it is not recommended to use this setting at the same time as the "UpdateAddressBar" option.
!! Set tiddler field when visible !! Visibility tracking
The background task detects when elements with the class `tc-dynaview-set-tiddler-when-visible` scroll into view. The first time that they do, the background task assigns the value in the attribute `data-dynaview-set-value` to the tiddler whose title is in the attribute `data-dynaview-set-tiddler`. The background task detects when elements with the class `tc-dynaview-track-tiddler-when-visible` scroll in and out of view. It tracks four different states:
This assignment can be tied to a reveal widget to cause content to be displayed when it becomes visible. * ''Blank/missing'' -- The element has not yet been scrolled into view
* ''0'' -- The element has been scrolled into view, but subsequently scrolled out of view
* ''1'' -- The element is near the viewport
* ''2'' -- The element is partially or wholly within the viewport
If the class `tc-dynaview-expand-viewport` is set then the viewport is expanded so that the processing occurs when elements move near the viewport. The processing applied to each element is as follows:
!!! Unset tiddler field when set visible before but then scrolled out of view * If the element is partially or wholly within the viewport then set the state to "2"
* If the element is near the viewport then set the state to "1"
* If the element is fully outside the viewport then only set the state to "0" if it is currently unset (ie blank/missing)
In addition to the processing described above, if the element also has the attribute `data-dynaview-unset-value` then its value will be assigned to the associated tiddler if the element is out of view and the current value of the tiddler corresponds to the value specified in the `data-dynaview-set-value` attribute. Attributes on the tracked element specify the following parameters:
* ''data-dynaview-track-tiddler'' -- specifies the tiddler in which the element tracking state will be stored
!! Update address bar when scrolling !! Update address bar when scrolling

View File

@ -18,6 +18,10 @@ exports.platforms = ["browser"];
exports.before = ["story"]; exports.before = ["story"];
exports.synchronous = true; exports.synchronous = true;
var STATE_OUT_OF_VIEW = "0",
STATE_NEAR_VIEW = "1",
STATE_IN_VIEW = "2";
var isWaitingForAnimationFrame = 0, // Bitmask: var isWaitingForAnimationFrame = 0, // Bitmask:
ANIM_FRAME_CAUSED_BY_LOAD = 1, // Animation frame was requested because of page load ANIM_FRAME_CAUSED_BY_LOAD = 1, // Animation frame was requested because of page load
ANIM_FRAME_CAUSED_BY_SCROLL = 2, // Animation frame was requested because of page scroll ANIM_FRAME_CAUSED_BY_SCROLL = 2, // Animation frame was requested because of page scroll
@ -106,7 +110,7 @@ function setZoomClasses() {
} }
function checkVisibility() { function checkVisibility() {
var elements = document.querySelectorAll(".tc-dynaview-set-tiddler-when-visible"); var elements = document.querySelectorAll(".tc-dynaview-track-tiddler-when-visible");
$tw.utils.each(elements,function(element) { $tw.utils.each(elements,function(element) {
// Calculate whether the element is visible // Calculate whether the element is visible
var elementRect = element.getBoundingClientRect(), var elementRect = element.getBoundingClientRect(),
@ -118,28 +122,30 @@ function checkVisibility() {
top: 0, top: 0,
bottom: viewportHeight bottom: viewportHeight
}, },
title = element.getAttribute("data-dynaview-set-tiddler"), title = element.getAttribute("data-dynaview-track-tiddler");
setValue = element.getAttribute("data-dynaview-set-value") || "", if(title) {
unsetValue = element.getAttribute("data-dynaview-unset-value") || ""; var currValue = $tw.wiki.getTiddlerText(title),
if(element.classList.contains("tc-dynaview-expand-viewport")) { newValue = currValue;
viewportRect.left -= viewportWidth; // Within viewport
viewportRect.right += viewportWidth; if(!(elementRect.left > viewportRect.right ||
viewportRect.top -= viewportHeight; elementRect.right < viewportRect.left ||
viewportRect.bottom += viewportHeight; elementRect.top > viewportRect.bottom ||
} elementRect.bottom < viewportRect.top)) {
if(elementRect.left > viewportRect.right || newValue = STATE_IN_VIEW;
elementRect.right < viewportRect.left || // Near viewport
elementRect.top > viewportRect.bottom || } else if(!(elementRect.left > (viewportRect.right + viewportWidth) ||
elementRect.bottom < viewportRect.top) { elementRect.right < (viewportRect.left - viewportWidth) ||
// Element is not visible elementRect.top > (viewportRect.bottom + viewportHeight) ||
// Set the unset tiddler if required elementRect.bottom < (viewportRect.top - viewportHeight))) {
if(title && unsetValue && $tw.wiki.getTiddlerText(title) === setValue) { newValue = STATE_NEAR_VIEW;
$tw.wiki.addTiddler(new $tw.Tiddler({title: title, text: unsetValue})); } else {
// Outside viewport
if(currValue !== undefined) {
newValue = STATE_OUT_OF_VIEW;
}
} }
} else { if(newValue !== currValue) {
// Element is visible $tw.wiki.addTiddler(new $tw.Tiddler({title: title, text: newValue}));
if(title && $tw.wiki.getTiddlerText(title) !== setValue) {
$tw.wiki.addTiddler(new $tw.Tiddler({title: title, text: setValue}));
} }
} }
}); });