V8: UI, refactoring of infinity editing to use CSS to fix issue regarding stacking of layers.

This commit is contained in:
Niels Lyngsø
2019-02-05 11:54:23 +01:00
parent ea95b4f454
commit ff497b413e
4 changed files with 135 additions and 149 deletions

View File

@@ -7,161 +7,85 @@
var evts = [];
var allowedNumberOfVisibleEditors = 3;
var editorIndent = 60;
scope.editors = [];
function addEditor(editor) {
editor.inFront = true;
editor.moveRight = true;
editor.level = 0;
editor.styleIndex = 0;
if (!editor.style)
editor.style = {};
editor.animating = true;
showOverlayOnPrevEditor();
var i = allowedNumberOfVisibleEditors;
var len = scope.editors.length;
while(i<len) {
var animeConfig = {
target: scope.editors[i].style,
easing: 'easeInOutQuint',
duration: 300
}
if(scope.editors[i].size !== "small") {
animeConfig.width = "100%";
}
if(len >= allowedNumberOfVisibleEditors) {
animeConfig.left = i * editorIndent;
} else {
animeConfig.left = (i + 1) * editorIndent;
}
anime(animeConfig);
i++;
}
editor.infinityMode = true;
// push the new editor to the dom
scope.editors.push(editor);
var indentValue = scope.editors.length * editorIndent;
// don't allow indent larger than what
// fits the max number of visible editors
if(scope.editors.length >= allowedNumberOfVisibleEditors) {
indentValue = allowedNumberOfVisibleEditors * editorIndent;
}
// indent all large editors
if(editor.size !== "small") {
editor.style.left = indentValue + "px";
}
editor.style._tx = 100;
editor.style.transform = "translateX("+editor.style._tx+"%)";
// animation config
anime({
targets: editor.style,
_tx: [100, 0],
easing: 'easeOutExpo',
duration: 480,
update: () => {
editor.style.transform = "translateX("+editor.style._tx+"%)";
scope.$digest();
},
complete: function() {
editor.animating = false;
scope.$digest();
}
});
}
function removeEditor(editor) {
$timeout(() => {
editor.moveRight = false;
})
editor.animating = true;
setTimeout(revealEditorContent.bind(this, editor), 400);
editor.style._tx = 0;
editor.style.transform = "translateX("+editor.style._tx+"%)";
updateEditors();
}
function removeEditor(editor) {
// animation config
anime({
targets: editor.style,
_tx: [0, 100],
easing: 'easeInExpo',
duration: 360,
update: () => {
editor.style.transform = "translateX("+editor.style._tx+"%)";
scope.$digest();
},
complete: function() {
scope.editors.splice(-1,1);
removeOverlayFromPrevEditor();
scope.$digest();
}
});
editor.moveRight = true;
editor.animating = true;
setTimeout(removeEditorFromDOM.bind(this, editor), 400);
expandEditors();
updateEditors(-1);
}
function expandEditors() {
function revealEditorContent(editor) {
var i = allowedNumberOfVisibleEditors + 1;
var len = scope.editors.length-1;
editor.animating = false;
scope.$digest();
}
function removeEditorFromDOM(editor) {
// push the new editor to the dom
var index = scope.editors.indexOf(editor);
if (index !== -1) {
scope.editors.splice(index, 1);
}
updateEditors();
scope.$digest();
}
/** update layer positions. With ability to offset positions, needed for when an item is moving out, then we dont want it to influence positions */
function updateEditors(offset) {
offset = offset || 0;// fallback value.
var len = scope.editors.length;
var calcLen = len + offset;
var ceiling = Math.min(calcLen, allowedNumberOfVisibleEditors);
var origin = Math.max(calcLen-1, 0)-ceiling;
var i = 0;
while(i<len) {
var animeConfig = {
target: scope.editors[i].style,
easing: 'easeInOutQuint',
duration: 300
}
if(scope.editors[i].size !== "small" && i === len) {
animeConfig.width = "500px";
}
if(scope.editors[i].size !== "small" && i === len) {
animeConfig.left = editorWidth - 500;
} else {
animeConfig.left = (index + 1) * editorIndent;
}
anime(animeConfig);
var iEditor = scope.editors[i];
iEditor.styleIndex = Math.min(i+1, allowedNumberOfVisibleEditors);
iEditor.level = Math.max(i-origin, -1);
iEditor.inFront = iEditor.level >= ceiling;
i++;
}
}
// show backdrop on previous editor
function showOverlayOnPrevEditor() {
var numberOfEditors = scope.editors.length;
if(numberOfEditors > 0) {
scope.editors[numberOfEditors - 1].showOverlay = true;
}
}
function removeOverlayFromPrevEditor() {
var numberOfEditors = scope.editors.length;
if(numberOfEditors > 0) {
scope.editors[numberOfEditors - 1].showOverlay = false;
}
}
evts.push(eventsService.on("appState.editors.open", function (name, args) {
addEditor(args.editor);
}));

View File

@@ -4,6 +4,7 @@
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
}
.umb-editor {
@@ -17,7 +18,49 @@
}
.umb-editor--animating {
will-change: transform, width, left;
//will-change: transform, width, left;
}
.umb-editor--infinityMode {
transform: none;
will-change: transform;
transition: transform 400ms ease-in-out;
&.moveRight {
transform: translateX(110%);
}
}
.umb-editor--outOfRange {
//left:0;
transform: none;
display: none;
will-change: auto;
transition: display 0s 320ms;
}
.umb-editor--level0 {
//left:0;
transform: none;
}
.umb-editor--level1 {
//left:60px;
transform: translateX(60px);
}
.umb-editor--level2 {
//left:120px;
transform: translateX(120px);
}
.umb-editor--level3 {
//left:180px;
transform: translateX(180px);
}
.umb-editor--n1 {
right:60px;
}
.umb-editor--n2 {
right:120px;
}
.umb-editor--n3 {
right:180px;
}
// hide all infinite editors by default
@@ -28,20 +71,14 @@
.umb-editor--small {
width: 500px;
will-change: transform;
left: auto;
.umb-editor-container {
max-width: 500px;
}
}
@keyframes umb-editor__overlay_fade_opacity {
from {
opacity:0;
}
to {
opacity:1;
}
}
.umb-editor__overlay {
position: absolute;
top: 0;
@@ -50,6 +87,14 @@
left: 0;
background: rgba(0,0,0,0.4);
z-index: @zIndexEditor;
animation:umb-editor__overlay_fade_opacity 600ms;
visibility: hidden;
opacity: 0;
transition: opacity 320ms 20ms, visibility 0s 400ms;
}
#contentcolumn > .umb-editor__overlay,
.--notInFront .umb-editor__overlay {
visibility: visible;
opacity: 1;
transition: opacity 320ms 20ms, visibility 0s;
}

View File

@@ -1,7 +1,8 @@
<div id="leftcolumn" ng-controller="Umbraco.NavigationController" ng-mouseleave="leaveTree($event)" ng-mouseenter="enterTree($event)">
<!-- navigation container -->
<div id="navigation" ng-show="showNavigation" class="fill umb-modalcolumn" ng-animate="'slide'" nav-resize>
<div id="navigation" ng-show="showNavigation" class="fill umb-modalcolumn" ng-animate="'slide'" nav-resize
ng-class="{'--notInFront': infiniteMode}">
<div class="navigation-inner-container">
@@ -45,7 +46,7 @@
</div>
<div class="umb-editor__overlay" ng-show="infiniteMode"></div>
<div class="umb-editor__overlay"></div>
</div>

View File

@@ -1,9 +1,25 @@
<div class="umb-editors">
<div class="umb-editor" ng-repeat="model in editors" ng-style="model.style" ng-class="{'umb-editor--small': model.size === 'small', 'umb-editor--animating': model.animating}">
<div class="umb-editor"
ng-repeat="model in editors"
ng-class="{'umb-editor--small': model.size === 'small',
'umb-editor--animating': model.animating,
'--notInFront': model.inFront !== true,
'umb-editor--infinityMode': model.infinityMode,
'moveRight': model.moveRight,
'umb-editor--n0': model.styleIndex === 0,
'umb-editor--n1': model.styleIndex === 1,
'umb-editor--n2': model.styleIndex === 2,
'umb-editor--n3': model.styleIndex === 3,
'umb-editor--outOfRange': model.level === -1,
'umb-editor--level0': model.level === 0,
'umb-editor--level1': model.level === 1,
'umb-editor--level2': model.level === 2,
'umb-editor--level3': model.level === 3}"
>
<div ng-if="!model.view && !model.animating" ng-transclude></div>
<div ng-if="model.view && !model.animating" ng-include="model.view"></div>
<div ng-if="model.showOverlay" class="umb-editor__overlay"></div>
<div class="umb-editor__overlay"></div>
</div>
</div>