diff --git a/editions/dynaviewdemo/tiddlers/SideBar-Open.tid b/editions/dynaviewdemo/tiddlers/SideBar-Open.tid index fac95637e..b3e42d2b2 100644 --- a/editions/dynaviewdemo/tiddlers/SideBar-Open.tid +++ b/editions/dynaviewdemo/tiddlers/SideBar-Open.tid @@ -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">× <$link to={{!!title}}><$view field="title"/> <$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix] }}}> -<$reveal type="match" stateTitle=<> text="true"> -LOADED +<$reveal type="match" stateTitle=<> text="0"> +OUT OF VIEW -<$reveal type="match" stateTitle=<> text="false"> -UNLOADED +<$reveal type="match" stateTitle=<> text="1"> +NEAR + +<$reveal type="match" stateTitle=<> text="2"> +VISIBLE diff --git a/editions/dynaviewdemo/tiddlers/TableOfContents.tid b/editions/dynaviewdemo/tiddlers/TableOfContents.tid index e3cc5f653..4d5559f44 100644 --- a/editions/dynaviewdemo/tiddlers/TableOfContents.tid +++ b/editions/dynaviewdemo/tiddlers/TableOfContents.tid @@ -8,9 +8,9 @@ caption: Contents <$vars item=<> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}} excluded="""[enlist<__exclude__>] -[<__tag__>]""">
  • <$link to={{{ [enlist{!!tiddler-list}] }}}> -<$list filter="[enlist{!!tiddler-list}addprefix[$:/state/viewtemplate/visibility/]text[true]limit[1]]" variable="listItem" emptyMessage="""
    """> -
    - + <$list filter="[enlist{!!tiddler-list}addprefix[$:/state/viewtemplate/visibility/]text[2]limit[1]]" variable="listItem" emptyMessage="""
    """> +
    + <$view field='caption'> <$view field='title'/> diff --git a/editions/dynaviewdemo/tiddlers/ViewTemplate.tid b/editions/dynaviewdemo/tiddlers/ViewTemplate.tid index 07f93928f..881c7aaff 100644 --- a/editions/dynaviewdemo/tiddlers/ViewTemplate.tid +++ b/editions/dynaviewdemo/tiddlers/ViewTemplate.tid @@ -12,14 +12,14 @@ $:/state/folded/$(currentTiddler)$
    > data-tags={{!!tags}} class=<>> <$set name="state" value={{{ [[$:/state/viewtemplate/visibility/]addsuffix] }}}> <$reveal stateTitle=<> type="nomatch" text="" default="" tag="div"> -
    > data-dynaview-set-value="true" data-dynaview-unset-value="false"> +
    >> <$list filter="[all[shadows+tiddlers]tag[$:/tags/ViewTemplate]!has[draft.of]]" variable="listItem"> <$transclude tiddler=<>/>
    <$reveal stateTitle=<> type="match" text="" default="" tag="div"> -
    > data-dynaview-set-value="true" data-dynaview-unset-value="false"> +
    >>
    diff --git a/plugins/tiddlywiki/dynaview/docs.tid b/plugins/tiddlywiki/dynaview/docs.tid index aa3fdfaa9..2e8dd8189 100644 --- a/plugins/tiddlywiki/dynaview/docs.tid +++ b/plugins/tiddlywiki/dynaview/docs.tid @@ -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. -!! 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 diff --git a/plugins/tiddlywiki/dynaview/dynaview.js b/plugins/tiddlywiki/dynaview/dynaview.js index bfaae66fa..12230b337 100644 --- a/plugins/tiddlywiki/dynaview/dynaview.js +++ b/plugins/tiddlywiki/dynaview/dynaview.js @@ -18,6 +18,10 @@ exports.platforms = ["browser"]; exports.before = ["story"]; exports.synchronous = true; +var STATE_OUT_OF_VIEW = "0", + STATE_NEAR_VIEW = "1", + STATE_IN_VIEW = "2"; + var isWaitingForAnimationFrame = 0, // Bitmask: 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 @@ -106,7 +110,7 @@ function setZoomClasses() { } 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) { // Calculate whether the element is visible var elementRect = element.getBoundingClientRect(), @@ -118,28 +122,30 @@ function checkVisibility() { top: 0, bottom: viewportHeight }, - title = element.getAttribute("data-dynaview-set-tiddler"), - setValue = element.getAttribute("data-dynaview-set-value") || "", - unsetValue = element.getAttribute("data-dynaview-unset-value") || ""; - if(element.classList.contains("tc-dynaview-expand-viewport")) { - viewportRect.left -= viewportWidth; - viewportRect.right += viewportWidth; - viewportRect.top -= viewportHeight; - viewportRect.bottom += viewportHeight; - } - if(elementRect.left > viewportRect.right || - elementRect.right < viewportRect.left || - elementRect.top > viewportRect.bottom || - elementRect.bottom < viewportRect.top) { - // Element is not visible - // Set the unset tiddler if required - if(title && unsetValue && $tw.wiki.getTiddlerText(title) === setValue) { - $tw.wiki.addTiddler(new $tw.Tiddler({title: title, text: unsetValue})); + title = element.getAttribute("data-dynaview-track-tiddler"); + if(title) { + var currValue = $tw.wiki.getTiddlerText(title), + newValue = currValue; + // Within viewport + if(!(elementRect.left > viewportRect.right || + elementRect.right < viewportRect.left || + elementRect.top > viewportRect.bottom || + elementRect.bottom < viewportRect.top)) { + newValue = STATE_IN_VIEW; + // Near viewport + } else if(!(elementRect.left > (viewportRect.right + viewportWidth) || + elementRect.right < (viewportRect.left - viewportWidth) || + elementRect.top > (viewportRect.bottom + viewportHeight) || + elementRect.bottom < (viewportRect.top - viewportHeight))) { + newValue = STATE_NEAR_VIEW; + } else { + // Outside viewport + if(currValue !== undefined) { + newValue = STATE_OUT_OF_VIEW; + } } - } else { - // Element is visible - if(title && $tw.wiki.getTiddlerText(title) !== setValue) { - $tw.wiki.addTiddler(new $tw.Tiddler({title: title, text: setValue})); + if(newValue !== currValue) { + $tw.wiki.addTiddler(new $tw.Tiddler({title: title, text: newValue})); } } });