mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-24 00:50:28 +00:00
Lots of fixes to storyview mechanism
And a new scroller mechanism
This commit is contained in:
parent
a21d96adc1
commit
f412dd19d9
@ -17,8 +17,6 @@ exports.info = {
|
||||
params: {
|
||||
story: {byName: "default", type: "text"}, // Actually a tiddler, but we don't want it to be a dependency
|
||||
history: {byName: "default", type: "text"}, // Actually a tiddler, but we don't want it to be a dependency
|
||||
defaultViewTemplate: {byName: true, type: "tiddler"},
|
||||
defaultEditTemplate: {byName: true, type: "tiddler"},
|
||||
set: {byName: true, type: "tiddler"}
|
||||
}
|
||||
};
|
||||
@ -64,8 +62,7 @@ exports.eventMap["tw-navigate"] = function(event) {
|
||||
// Update the story tiddler if specified
|
||||
if(this.hasParameter("story")) {
|
||||
this.getStory();
|
||||
var template = this.params.defaultViewTemplate || "$:/templates/ViewTemplate",
|
||||
t,tiddler,slot;
|
||||
var t,tiddler,slot;
|
||||
// See if the tiddler is already there
|
||||
for(t=0; t<this.story.tiddlers.length; t++) {
|
||||
if(this.story.tiddlers[t].title === event.navigateTo) {
|
||||
@ -102,13 +99,46 @@ exports.eventMap["tw-navigate"] = function(event) {
|
||||
this.history.stack.push({
|
||||
title: event.navigateTo,
|
||||
fromTitle: event.navigateFromTitle,
|
||||
fromPosition: event.navigateFrom.getNodeBounds()
|
||||
fromPosition: event.navigateFrom.getNodeBounds(),
|
||||
scrollPosition: $tw.utils.getScrollPosition()
|
||||
});
|
||||
this.saveHistory();
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Navigate to a specified tiddler
|
||||
exports.eventMap["tw-NavigateBack"] = function(event) {
|
||||
// Pop a record record off the top of the history stack
|
||||
this.getHistory();
|
||||
if(this.history.stack.length < 2) {
|
||||
return false; // Bail if there is not enough entries on the history stack
|
||||
}
|
||||
var fromHistoryInfo = this.history.stack.pop(),
|
||||
toHistoryInfo = this.history.stack[this.history.stack.length-1];
|
||||
this.saveHistory();
|
||||
// Make sure that the tiddler we're navigating back to is open in the story
|
||||
if(this.hasParameter("story") && toHistoryInfo) {
|
||||
this.getStory();
|
||||
var t,tiddler,slot;
|
||||
// See if the tiddler is already there
|
||||
for(t=0; t<this.story.tiddlers.length; t++) {
|
||||
if(this.story.tiddlers[t].title === toHistoryInfo.title) {
|
||||
tiddler = t;
|
||||
}
|
||||
}
|
||||
// If not we need to add it
|
||||
if(tiddler === undefined) {
|
||||
// Add the tiddler
|
||||
this.story.tiddlers.splice(slot,0,{title: toHistoryInfo.title});
|
||||
// Save the story
|
||||
this.saveStory();
|
||||
}
|
||||
}
|
||||
event.stopPropagation();
|
||||
return false;
|
||||
};
|
||||
|
||||
// Place a tiddler in edit mode
|
||||
exports.eventMap["tw-EditTiddler"] = function(event) {
|
||||
if(this.hasParameter("story")) {
|
||||
@ -204,7 +234,7 @@ exports.executeMacro = function() {
|
||||
this.content[t].execute(this.parents,this.tiddlerTitle);
|
||||
}
|
||||
return $tw.Tree.Element("div",attributes,this.content,{
|
||||
events: ["tw-navigate","tw-EditTiddler","tw-SaveTiddler","tw-CloseTiddler"],
|
||||
events: ["tw-navigate","tw-EditTiddler","tw-SaveTiddler","tw-CloseTiddler","tw-NavigateBack"],
|
||||
eventHandler: this
|
||||
});
|
||||
};
|
||||
|
@ -19,7 +19,11 @@ And the history tiddler is the stack of tiddlers that were navigated to in turn:
|
||||
|
||||
{
|
||||
stack: [
|
||||
{title: <string>}
|
||||
{
|
||||
title: <string>,
|
||||
fromTitle: <string>,
|
||||
fromPosition: {bottom: <num>, height: <num>, top: <num>, right: <num>, left: <num>, width: <num>}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -132,6 +136,9 @@ exports.removeStoryElement = function(storyElementIndex) {
|
||||
// Only delete the DOM element if the storyview.remove() returned false
|
||||
storyElement.domNode.parentNode.removeChild(storyElement.domNode);
|
||||
}
|
||||
} else {
|
||||
// Always delete the story element if we didn't invoke the storyview
|
||||
storyElement.domNode.parentNode.removeChild(storyElement.domNode);
|
||||
}
|
||||
// Then delete the actual renderer node
|
||||
this.storyNode.children.splice(storyElementIndex,1);
|
||||
@ -169,8 +176,10 @@ exports.executeMacro = function() {
|
||||
};
|
||||
|
||||
exports.postRenderInDom = function() {
|
||||
// Reset the record of the previous history stack
|
||||
this.prevHistory = {stack: []};
|
||||
// Get the history object and use it to set the previous history
|
||||
this.getHistory();
|
||||
this.prevHistory = this.history;
|
||||
this.history = null;
|
||||
// Instantiate the story view
|
||||
var storyviewName;
|
||||
if(this.hasParameter("storyviewTiddler")) {
|
||||
@ -278,7 +287,7 @@ exports.processHistoryChange = function() {
|
||||
// Read the history tiddler
|
||||
this.getHistory();
|
||||
if(this.storyview) {
|
||||
var t,index,
|
||||
var t,indexTo,indexFrom,
|
||||
topCommon = Math.min(this.history.stack.length,this.prevHistory.stack.length);
|
||||
// Find the common heritage of the new history stack and the previous one
|
||||
for(t=0; t<topCommon; t++) {
|
||||
@ -289,16 +298,21 @@ exports.processHistoryChange = function() {
|
||||
}
|
||||
// We now navigate backwards through the previous history to get back to the common ancestor
|
||||
for(t=this.prevHistory.stack.length-1; t>=topCommon; t--) {
|
||||
index = this.findStoryElementByTitle(0,this.prevHistory.stack[t].title);
|
||||
if(index !== undefined && this.storyview.navigateBack) {
|
||||
this.storyview.navigateBack(this.storyNode.children[index],this.history.stack[t]);
|
||||
indexTo = this.findStoryElementByTitle(0,this.prevHistory.stack[t].fromTitle);
|
||||
indexFrom = this.findStoryElementByTitle(0,this.prevHistory.stack[t].title);
|
||||
// Call the story view if it defines a navigateBack() method
|
||||
if(indexTo !== undefined && indexFrom !== undefined && this.storyview.navigateBack) {
|
||||
this.storyview.navigateBack(this.storyNode.children[indexTo],this.storyNode.children[indexFrom],this.prevHistory.stack[t]);
|
||||
}
|
||||
}
|
||||
// And now we navigate forwards through the new history to get to the latest tiddler
|
||||
for(t=topCommon; t<this.history.stack.length; t++) {
|
||||
index = this.findStoryElementByTitle(0,this.history.stack[t].title);
|
||||
if(index !== undefined && this.storyview.navigateForward) {
|
||||
this.storyview.navigateForward(this.storyNode.children[index],this.history.stack[t]);
|
||||
indexTo = this.findStoryElementByTitle(0,this.history.stack[t].title);
|
||||
indexFrom = this.findStoryElementByTitle(0,this.history.stack[t].fromTitle);
|
||||
if(indexTo !== undefined && this.storyview.navigateForward) {
|
||||
this.storyview.navigateForward(this.storyNode.children[indexTo],
|
||||
indexFrom !== undefined ? this.storyNode.children[indexFrom] : undefined,
|
||||
this.history.stack[t]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ ClassicScroller.prototype.remove = function(storyElementNode) {
|
||||
}
|
||||
},false);
|
||||
// Animate the closure
|
||||
var d = ($tw.config.preferences.animationDuration/1000).toFixed(8) + "s";
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
wrapperElement.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, " +
|
||||
"opacity " + d + " ease-out, " +
|
||||
"height " + d + " ease-in-out";
|
||||
@ -48,12 +48,12 @@ ClassicScroller.prototype.remove = function(storyElementNode) {
|
||||
return true;
|
||||
};
|
||||
|
||||
ClassicScroller.prototype.navigateBack = function(storyElementNode,historyInfo) {
|
||||
$tw.utils.scrollIntoView(storyElementNode.domNode);
|
||||
ClassicScroller.prototype.navigateBack = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
};
|
||||
|
||||
ClassicScroller.prototype.navigateForward = function(storyElementNode,historyInfo) {
|
||||
$tw.utils.scrollIntoView(storyElementNode.domNode);
|
||||
ClassicScroller.prototype.navigateForward = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
};
|
||||
|
||||
exports.classic = ClassicScroller;
|
||||
|
@ -30,13 +30,23 @@ function SidewaysView(story) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Visualise navigation to a new tiddler
|
||||
toStoryElementNode: tree node of the tiddler macro we're navigating to
|
||||
fromStoryElementNode: optionally, tree node of the tiddler we're navigating from
|
||||
historyInfo: record from the history tiddler corresponding to this navigation
|
||||
*/
|
||||
SidewaysView.prototype.navigateForward = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
};
|
||||
|
||||
/*
|
||||
Visualise insertion of the specified tiddler macro, optionally specifying a source node for the visualisation
|
||||
storyElementNode: tree node of the tiddler macro we're navigating to
|
||||
*/
|
||||
SidewaysView.prototype.insert = function(storyElementNode) {
|
||||
setStoryElementStyles(storyElementNode.domNode);
|
||||
$tw.utils.scrollIntoView(storyElementNode.domNode);
|
||||
$tw.scroller.scrollIntoView(storyElementNode.domNode);
|
||||
};
|
||||
|
||||
SidewaysView.prototype.remove = function(storyElementNode) {
|
||||
@ -48,7 +58,7 @@ SidewaysView.prototype.remove = function(storyElementNode) {
|
||||
targetElement.parentNode.insertBefore(wrapperElement,targetElement);
|
||||
wrapperElement.appendChild(targetElement);
|
||||
// Animate the closure
|
||||
var d = ($tw.config.preferences.animationDuration/1000).toFixed(8) + "s";
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
wrapperElement.style.display = "inline-block";
|
||||
wrapperElement.style[$tw.browser.transformorigin] = "0% 0%";
|
||||
wrapperElement.style[$tw.browser.transform] = "translateY(0px)";
|
||||
|
@ -3,7 +3,11 @@ title: $:/core/modules/macros/story/views/zoomin.js
|
||||
type: application/javascript
|
||||
module-type: storyview
|
||||
|
||||
A storyview that shows a single tiddler and navigates by zooming into links
|
||||
A storyview that shows a single tiddler and navigates by zooming into links.
|
||||
|
||||
To do this, the story wrapper is set to `position:relative` and then each of the story elements to `position:absolute`. This results in all of the tiddlers being stacked on top of one another flush with the top left of the story wrapper.
|
||||
|
||||
Navigating between tiddlers is accomplished by switching the story nodes between `display:block` and `display:none`, but the implementation is considerably more complex due to the animation.
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
@ -16,6 +20,8 @@ function Zoomin(story) {
|
||||
// Save the story
|
||||
this.story = story;
|
||||
this.storyNode = this.story.child.domNode;
|
||||
// Set the current tiddler
|
||||
this.currentTiddler = this.story.child.children[0];
|
||||
// Make all the tiddlers position absolute, and hide all but the first one
|
||||
this.storyNode.style.position = "relative";
|
||||
for(var t=0; t<this.storyNode.children.length; t++) {
|
||||
@ -24,10 +30,6 @@ function Zoomin(story) {
|
||||
}
|
||||
this.storyNode.children[t].style.position = "absolute";
|
||||
}
|
||||
// Record the current tiddler node
|
||||
this.currTiddler = this.story.child.children[0];
|
||||
// Set up the stack of previously viewed tiddlers
|
||||
this.prevTiddlers = [this.currTiddler.children[0].params.target];
|
||||
}
|
||||
|
||||
/*
|
||||
@ -55,128 +57,120 @@ function findTitleNode(node) {
|
||||
}
|
||||
|
||||
/*
|
||||
Visualise removal of the the specified tiddler macro, optionally specifying a source node for the visualisation
|
||||
storyElementNode: tree node of the tiddler macro we're navigating to
|
||||
Visualise navigation to a new tiddler
|
||||
toStoryElementNode: tree node of the tiddler macro we're navigating to
|
||||
fromStoryElementNode: optionally, tree node of the tiddler we're navigating from
|
||||
historyInfo: record from the history tiddler corresponding to this navigation
|
||||
*/
|
||||
Zoomin.prototype.navigateForward = function(storyElementNode,historyInfo) {
|
||||
// Do nothing if the target tiddler is already the current tiddler
|
||||
if(storyElementNode === this.currTiddler) {
|
||||
return;
|
||||
}
|
||||
// Make the new tiddler be position absolute and visible
|
||||
storyElementNode.domNode.style.position = "absolute";
|
||||
storyElementNode.domNode.style.display = "block";
|
||||
storyElementNode.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "none";
|
||||
Zoomin.prototype.navigateForward = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
// Make the new tiddler be position absolute and visible so that we can measure it
|
||||
toStoryElement.domNode.style.position = "absolute";
|
||||
toStoryElement.domNode.style.display = "block";
|
||||
toStoryElement.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
toStoryElement.domNode.style[$tw.browser.transition] = "none";
|
||||
toStoryElement.domNode.style.opacity = "0.0";
|
||||
// Get the position of the source node, or use the centre of the window as the source position
|
||||
var sourceBounds = historyInfo.fromPosition || {
|
||||
left: window.innerWidth/2 - 2,
|
||||
top: window.innerHeight/2 - 2,
|
||||
width: 4,
|
||||
height: 4
|
||||
width: window.innerWidth/8,
|
||||
height: window.innerHeight/8
|
||||
};
|
||||
// Try to find the title node in the target tiddler
|
||||
var titleNode = findTitleNode(storyElementNode) || storyElementNode;
|
||||
var titleNode = findTitleNode(toStoryElement) || toStoryElement,
|
||||
titleBounds = titleNode.getNodeBounds();
|
||||
// Compute the transform for the target tiddler to make the title lie over the source rectange
|
||||
var targetBounds = storyElementNode.getNodeBounds(),
|
||||
titleBounds = titleNode.getNodeBounds(),
|
||||
var targetBounds = toStoryElement.getNodeBounds(),
|
||||
scale = sourceBounds.width / titleBounds.width,
|
||||
x = sourceBounds.left - targetBounds.left - (titleBounds.left - targetBounds.left) * scale,
|
||||
y = sourceBounds.top - targetBounds.top - (titleBounds.top - targetBounds.top) * scale;
|
||||
// Transform the target tiddler
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
// Transform the target tiddler to its starting position
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
// Get the animation duration
|
||||
var d = ($tw.config.preferences.animationDuration/1000).toFixed(8) + "s";
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
// Apply the ending transitions with a timeout to ensure that the previously applied transformations are applied first
|
||||
var self = this,
|
||||
currTiddler = this.currTiddler;
|
||||
prevCurrentTiddler = this.currentTiddler;
|
||||
this.currentTiddler = toStoryElement;
|
||||
$tw.utils.nextTick(function() {
|
||||
// Transform the target tiddler
|
||||
var currTiddlerBounds = currTiddler.getNodeBounds(),
|
||||
x = (currTiddlerBounds.left - targetBounds.left),
|
||||
y = (currTiddlerBounds.top - targetBounds.top);
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
storyElementNode.domNode.style.opacity = "1.0";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(1)";
|
||||
storyElementNode.domNode.style.zIndex = "500";
|
||||
// Transform the current tiddler
|
||||
var scale = titleBounds.width / sourceBounds.width;
|
||||
x = titleBounds.left - targetBounds.left - (sourceBounds.left - currTiddlerBounds.left) * scale;
|
||||
y = titleBounds.top - targetBounds.top - (sourceBounds.top - currTiddlerBounds.top) * scale;
|
||||
currTiddler.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
currTiddler.domNode.style.opacity = "0.0";
|
||||
currTiddler.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
currTiddler.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
currTiddler.domNode.style.zIndex = "0";
|
||||
// Transform the target tiddler to its natural size
|
||||
toStoryElement.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
toStoryElement.domNode.style.opacity = "1.0";
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
toStoryElement.domNode.style.zIndex = "500";
|
||||
// Transform the previous tiddler out of the way and then hide it
|
||||
if(prevCurrentTiddler && prevCurrentTiddler !== toStoryElement) {
|
||||
var scale = titleBounds.width / sourceBounds.width;
|
||||
x = titleBounds.left - targetBounds.left - (sourceBounds.left - targetBounds.left) * scale;
|
||||
y = titleBounds.top - targetBounds.top - (sourceBounds.top - targetBounds.top) * scale;
|
||||
prevCurrentTiddler.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
prevCurrentTiddler.domNode.style.opacity = "0.0";
|
||||
prevCurrentTiddler.domNode.style[$tw.browser.transformorigin] = "0 0";
|
||||
prevCurrentTiddler.domNode.style[$tw.browser.transform] = "translateX(" + x + "px) translateY(" + y + "px) scale(" + scale + ")";
|
||||
prevCurrentTiddler.domNode.style.zIndex = "0";
|
||||
var eventHandler = function(event) {
|
||||
// Hide the DOM node when the transition is over
|
||||
if(self.currentTiddler !== prevCurrentTiddler) {
|
||||
prevCurrentTiddler.domNode.style.display = "none";
|
||||
}
|
||||
prevCurrentTiddler.domNode.removeEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
};
|
||||
prevCurrentTiddler.domNode.addEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
}
|
||||
// Scroll the target into view
|
||||
$tw.scroller.scrollIntoView(toStoryElement.domNode);
|
||||
});
|
||||
// Record the new current tiddler
|
||||
this.currTiddler = storyElementNode;
|
||||
// Save the tiddler in the stack
|
||||
this.prevTiddlers.push(storyElementNode.children[0].params.target);
|
||||
};
|
||||
|
||||
/*
|
||||
Visualise removing a tiddler
|
||||
Visualise navigating back to the previous tiddler
|
||||
toStoryElement: story element being navigated back to
|
||||
fromStoryElement: story element being navigated back from
|
||||
historyInfo: member of the history stack[] array being navigated back through
|
||||
*/
|
||||
Zoomin.prototype.remove = function(storyElementNode) {
|
||||
// Remove the last entry from the navigation stack, which will be to navigate to the current tiddler
|
||||
this.prevTiddlers.pop();
|
||||
// Find the top entry in the navigation stack that still exists
|
||||
var storyElementIndex,storyElement;
|
||||
while(this.prevTiddlers.length > 0) {
|
||||
var title = this.prevTiddlers.pop();
|
||||
storyElementIndex = this.story.findStoryElementByTitle(0,title);
|
||||
if(storyElementIndex !== undefined) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(storyElementIndex !== undefined) {
|
||||
storyElement = this.story.storyNode.children[storyElementIndex];
|
||||
}
|
||||
Zoomin.prototype.navigateBack = function(toStoryElement,fromStoryElement,historyInfo) {
|
||||
// Get the animation duration
|
||||
var d = ($tw.config.preferences.animationDuration/1000).toFixed(8) + "s";
|
||||
var d = $tw.config.preferences.animationDuration + "ms";
|
||||
// Set up the tiddler that is being closed
|
||||
storyElementNode.domNode.style.position = "absolute";
|
||||
storyElementNode.domNode.style.display = "block";
|
||||
storyElementNode.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "none";
|
||||
storyElementNode.domNode.style.zIndex = "0";
|
||||
// Set up the tiddler we're moving back in
|
||||
if(storyElement !== undefined) {
|
||||
storyElement.domNode.style.position = "absolute";
|
||||
storyElement.domNode.style.display = "block";
|
||||
storyElement.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
storyElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(10)";
|
||||
storyElement.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
storyElement.domNode.style.opacity = "0.0";
|
||||
storyElement.domNode.style.zIndex = "500";
|
||||
// Push the tiddler we're moving back to back on the stack
|
||||
this.prevTiddlers.push(storyElement.children[0].params.target);
|
||||
this.currTiddler = storyElement;
|
||||
} else {
|
||||
this.currTiddler = null;
|
||||
if(fromStoryElement) {
|
||||
fromStoryElement.domNode.style.position = "absolute";
|
||||
fromStoryElement.domNode.style.display = "block";
|
||||
fromStoryElement.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
fromStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
fromStoryElement.domNode.style[$tw.browser.transition] = "none";
|
||||
fromStoryElement.domNode.style.zIndex = "0";
|
||||
}
|
||||
// Set up the tiddler we're moving back in
|
||||
toStoryElement.domNode.style.position = "absolute";
|
||||
toStoryElement.domNode.style.display = "block";
|
||||
toStoryElement.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(10)";
|
||||
toStoryElement.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
toStoryElement.domNode.style.opacity = "0.0";
|
||||
toStoryElement.domNode.style.zIndex = "500";
|
||||
this.currentTiddler = toStoryElement;
|
||||
// Animate them both
|
||||
$tw.utils.nextTick(function() {
|
||||
// First, the tiddler we're closing
|
||||
storyElementNode.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
storyElementNode.domNode.style.opacity = "0.0";
|
||||
storyElementNode.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
storyElementNode.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(0.1)";
|
||||
storyElementNode.domNode.style.zIndex = "0";
|
||||
storyElementNode.domNode.addEventListener($tw.browser.transitionEnd,function(event) {
|
||||
// Delete the DOM node when the transition is over
|
||||
if(storyElementNode.domNode.parentNode) {
|
||||
storyElementNode.domNode.parentNode.removeChild(storyElementNode.domNode);
|
||||
}
|
||||
},true);
|
||||
// Now the tiddler we're going back to
|
||||
if(storyElement !== undefined) {
|
||||
storyElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
storyElement.domNode.style.opacity = "1.0";
|
||||
if(fromStoryElement) {
|
||||
fromStoryElement.domNode.style[$tw.browser.transition] = "-" + $tw.browser.prefix.toLowerCase() + "-transform " + d + " ease-in-out, opacity " + d + " ease-out";
|
||||
fromStoryElement.domNode.style.opacity = "0.0";
|
||||
fromStoryElement.domNode.style[$tw.browser.transformorigin] = "50% 50%";
|
||||
fromStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(0.1)";
|
||||
fromStoryElement.domNode.style.zIndex = "0";
|
||||
var eventHandler = function(event) {
|
||||
// Delete the DOM node when the transition is over
|
||||
if(fromStoryElement.domNode.parentNode) {
|
||||
fromStoryElement.domNode.parentNode.removeChild(fromStoryElement.domNode);
|
||||
}
|
||||
fromStoryElement.domNode.removeEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
};
|
||||
fromStoryElement.domNode.addEventListener($tw.browser.transitionEnd,eventHandler,true);
|
||||
}
|
||||
// Now the tiddler we're going back to
|
||||
toStoryElement.domNode.style[$tw.browser.transform] = "translateX(0px) translateY(0px) scale(1)";
|
||||
toStoryElement.domNode.style.opacity = "1.0";
|
||||
});
|
||||
return true; // Indicate that we'll delete the DOM node
|
||||
};
|
||||
|
59
core/modules/scroller.js
Normal file
59
core/modules/scroller.js
Normal file
@ -0,0 +1,59 @@
|
||||
/*\
|
||||
title: $:/core/modules/scroller.js
|
||||
type: application/javascript
|
||||
module-type: utils
|
||||
|
||||
Plugin that creates a $tw.utils.Scroller object prototype that manages scrolling in the browser
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var slowInSlowOut = function(t) {
|
||||
return (1 - ((Math.cos(t * Math.PI) + 1) / 2));
|
||||
};
|
||||
|
||||
/*
|
||||
Creates a Scroller object
|
||||
*/
|
||||
var Scroller = function() {
|
||||
};
|
||||
|
||||
Scroller.prototype.cancel = function() {
|
||||
if(this.timerId) {
|
||||
window.clearInterval(this.timerId);
|
||||
this.timerId = null;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Smoothly scroll an element back into view if needed
|
||||
*/
|
||||
Scroller.prototype.scrollIntoView = function(element) {
|
||||
var scrollPosition = $tw.utils.getScrollPosition();
|
||||
this.cancel();
|
||||
this.startTime = new Date();
|
||||
this.startX = scrollPosition.x;
|
||||
this.startY = scrollPosition.y;
|
||||
this.endX = element.offsetLeft;
|
||||
this.endY = element.offsetTop;
|
||||
if((this.endX < this.startX) || (this.endX > (this.startX + window.innerWidth)) || (this.endY < this.startY) || (this.endY > (this.startY + window.innerHeight))) {
|
||||
var self = this;
|
||||
this.timerId = window.setInterval(function() {
|
||||
var t = ((new Date()) - self.startTime) / $tw.config.preferences.animationDuration;
|
||||
if(t >= 1) {
|
||||
self.cancel();
|
||||
t = 1;
|
||||
}
|
||||
t = slowInSlowOut(t);
|
||||
window.scrollTo(self.startX + (self.endX - self.startX) * t,self.startY + (self.endY - self.startY) * t);
|
||||
}, 10);
|
||||
}
|
||||
};
|
||||
|
||||
exports.Scroller = Scroller;
|
||||
|
||||
})();
|
@ -76,34 +76,18 @@ exports.applyStyleSheet = function(id,css) {
|
||||
};
|
||||
|
||||
/*
|
||||
Smoothly scroll an element back into view if needed
|
||||
Get the scroll position of the viewport
|
||||
Returns:
|
||||
{
|
||||
x: horizontal scroll position in pixels,
|
||||
y: vertical scroll position in pixels
|
||||
}
|
||||
*/
|
||||
exports.scrollIntoView = function(element) {
|
||||
var slowInSlowOut = function(t) {
|
||||
return (1 - ((Math.cos(t * Math.PI) + 1) / 2));
|
||||
},
|
||||
animateScroll = function(startX,startY,endX,endY,duration) {
|
||||
var startTime = new Date(),
|
||||
timerId = window.setInterval(function() {
|
||||
var t = ((new Date()) - startTime) / duration;
|
||||
if(t >= 1) {
|
||||
window.clearInterval(timerId);
|
||||
t = 1;
|
||||
}
|
||||
t = slowInSlowOut(t);
|
||||
var x = startX + (endX - startX) * t,
|
||||
y = startY + (endY - startY) * t;
|
||||
window.scrollTo(x,y);
|
||||
}, 10);
|
||||
},
|
||||
x = element.offsetLeft,
|
||||
y = element.offsetTop,
|
||||
winWidth = window.innerWidth,
|
||||
winHeight = window.innerHeight,
|
||||
scrollLeft = window.scrollX || document.documentElement.scrollLeft,
|
||||
scrollTop = window.scrollY || document.documentElement.scrollTop;
|
||||
if((x < scrollLeft) || (x > (scrollLeft + winWidth)) || (y < scrollTop) || (y > (scrollTop + winHeight))) {
|
||||
animateScroll(scrollLeft,scrollTop,x,y,$tw.config.preferences.animationDuration);
|
||||
exports.getScrollPosition = function() {
|
||||
if("scrollX" in window) {
|
||||
return {x: window.scrollX, y: window.scrollY};
|
||||
} else {
|
||||
return {x: document.documentElement.scrollLeft, y: document.documentElement.scrollTop};
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user