Added a new animated dialog stack
This is to replace the animated-pages hack with Blaze component built for purpose
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
.dialog-stack {
|
||||
background: rgba(0,0,0,0.4);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.dialog-stack .dialog-sizer {
|
||||
position: relative;
|
||||
height: 80%;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.dialog-stack .dialog {
|
||||
position: absolute;
|
||||
transform-origin: top left;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: white;
|
||||
box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14),
|
||||
0 3px 14px 2px rgba(0, 0, 0, 0.12),
|
||||
0 5px 5px -3px rgba(0, 0, 0, 0.4);
|
||||
transition: all ease 0.5s;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
Dialog stack should be placed last in the root layout template
|
||||
It creates a stack of dialogs that can be closed individually
|
||||
-->
|
||||
<template name="dialogStack">
|
||||
<div class="fit dialog-stack layout vertical center center-justified" style={{dialogStackStyle}}>
|
||||
<div class="dialog-sizer">
|
||||
{{#each dialogs}}
|
||||
<div class="dialog" style={{dialogStyle @index}}>
|
||||
{{> UI.dynamic template=template data=data}}
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template name="testDialog">
|
||||
<paper-toolbar>
|
||||
Test dialog {{data}}
|
||||
</paper-toolbar>
|
||||
<div>
|
||||
<div class="testButton"
|
||||
style="height: 200px; width: 100px; background: red; border-radius: 30px;">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
104
rpg-docs/client/views/paperTemplates/dialogStack/dialogStack.js
Normal file
104
rpg-docs/client/views/paperTemplates/dialogStack/dialogStack.js
Normal file
@@ -0,0 +1,104 @@
|
||||
dialogs = new ReactiveArray();
|
||||
const offset = 16;
|
||||
|
||||
pushDialogStack = function({template, data, element, callback}){
|
||||
// Generate a new _id so that Blaze knows how to shuffle the array
|
||||
const _id = Random.id();
|
||||
dialogs.push({
|
||||
_id,
|
||||
template,
|
||||
data,
|
||||
element,
|
||||
callback,
|
||||
});
|
||||
};
|
||||
|
||||
popDialogStack = function(result){
|
||||
const dialog = dialogs.pop();
|
||||
if (!dialog) return;
|
||||
dialog.callback && dialog.callback(result);
|
||||
};
|
||||
|
||||
Template.dialogStack.helpers({
|
||||
dialogStackStyle(){
|
||||
if (!dialogs.get().length) return "display: none;";
|
||||
},
|
||||
dialogs(){
|
||||
return dialogs.get();
|
||||
},
|
||||
dialogStyle(index){
|
||||
const num = dialogs.get().length - 1;
|
||||
const left = (num - index) * -offset;
|
||||
const top = (num - index) * -offset;
|
||||
return `left:${left}px; top:${top}px;`;
|
||||
},
|
||||
});
|
||||
|
||||
Template.dialogStack.events({
|
||||
"click .dialog-stack": function(event){
|
||||
popDialogStack();
|
||||
},
|
||||
"click .dialog-sizer": function(event){
|
||||
// Returning false from an event handler is the same as calling both
|
||||
// stopImmediatePropagation and preventDefault on the event.
|
||||
return false;
|
||||
},
|
||||
});
|
||||
|
||||
Template.dialogStack.uihooks({
|
||||
".dialog": {
|
||||
container: ".dialog-sizer",
|
||||
insert: function(node, next, tpl) {
|
||||
$(node).insertBefore(next);
|
||||
|
||||
const data = Blaze.getData(node);
|
||||
if (data.element){
|
||||
data.element.style.visibility = "hidden";
|
||||
const toRect = node.getBoundingClientRect();
|
||||
const fromRect = data.element.getBoundingClientRect();
|
||||
const deltaLeft = fromRect.left - toRect.left;
|
||||
const deltaTop = fromRect.top - toRect.top;
|
||||
const deltaWidth = fromRect.width / toRect.width;
|
||||
const deltaHeight = fromRect.height / toRect.height;
|
||||
node.style.transition = "none";
|
||||
node.style.transform = `translate(${deltaLeft}px, ${deltaTop}px) ` +
|
||||
`scale(${deltaWidth}, ${deltaHeight})`;
|
||||
node.style.borderRadius = $(data.element).css("border-radius");
|
||||
node["data-element"] = data.element;
|
||||
_.defer(() => {
|
||||
node.style.transition = "";
|
||||
node.style.transform = "";
|
||||
node.style.borderRadius = "";
|
||||
});
|
||||
}
|
||||
},
|
||||
remove: function(node, tpl) {
|
||||
//TODO maybe make the element transform to the dialog size
|
||||
// and then return to its place?
|
||||
const element = node["data-element"];
|
||||
if (element){
|
||||
const toRect = node.getBoundingClientRect();
|
||||
const fromRect = element.getBoundingClientRect();
|
||||
let deltaLeft = fromRect.left - toRect.left;
|
||||
let deltaTop = fromRect.top - toRect.top;
|
||||
const deltaWidth = fromRect.width / toRect.width;
|
||||
const deltaHeight = fromRect.height / toRect.height;
|
||||
node.style.transform = `translate(${deltaLeft}px, ${deltaTop}px) ` +
|
||||
`scale(${deltaWidth}, ${deltaHeight})`;
|
||||
node.style.borderRadius = $(element).css("border-radius");
|
||||
_.delay(() => {
|
||||
element.style.visibility = "";
|
||||
node.remove();
|
||||
}, 500);
|
||||
} else {
|
||||
node.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Template.testDialog.events({
|
||||
"click .testButton": function(event, template){
|
||||
pushDialogStack({template: "testDialog", element: event.currentTarget, data: Random.id()});
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user