import {
AfterViewInit,
ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, OnDestroy, OnInit, Output, ViewChild
} from '@angular/core';
import * as _ from 'lodash';
import {Observable} from 'rxjs';
@Component({
selector: 'dc-step',
template: `
0" class="step-box">
currentIndex)}">
{{item[showKey]}}
currentIndex)}">
`,
styles: [
`
ul, li {
list-style: none;
margin: 0;
padding: 0;
}
.step-box {
display: flex;
flex-direction: row;
height: 55px;
}
.step-action-left,
.step-action-right {
flex-shrink: 0;
flex-grow: 0;
width: 30px;
height: 30px;
cursor: pointer;
}
.step-action-left {
margin-right: 10px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQyIDc5LjE2MDkyNCwgMjAxNy8wNy8xMy0wMTowNjozOSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjk5ODM3NTJGOEYwNjExRThBQTU5QURDMjEzMEIxMTExIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjk5ODM3NTMwOEYwNjExRThBQTU5QURDMjEzMEIxMTExIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTk4Mzc1MkQ4RjA2MTFFOEFBNTlBREMyMTMwQjExMTEiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OTk4Mzc1MkU4RjA2MTFFOEFBNTlBREMyMTMwQjExMTEiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5Yp4h0AAAC6ElEQVR42sxXvasaQRDf+4iXh+g1QSuRpEi0MZA2qQQrg6DYvlajYB3SPEiRP8JKLERECSKIhWBSJLVoF5WAogiSxq9CvY/sXvbM6vO82yMPsjDs6c7Mb2d2dmaWAdYHYzCrBrMlZWbrLP7WZ+YMWCeFmK9ugjEBZQniMLHEBgABhEjGpBCk0rgUKeYhCZCckMRCoRAaj8fvt9vtF0mS5oqi7CFt9/v9T/hfZzKZfEA8iBfLCFgHa8GzJ6CPIbmLxeLL1Wr1WVVVSTUfEuJFMkgW67AEroPeoJ0PBoOULMsblXJAT2ygbBpbf0OAG1qrWyrOZrM7pEO1P5TpdHqHwXXLmUugHD4X93A4fEcDul6vDcGRLux2AWMw58CPUFCg80Gusgra6/XUXC6nzUZux2fuxBgMIPyuXxE+Ho9/ZBjGaSX8+/0+yOfzYLfbgdFodPn8oC6kkzhnFpwlBA7u7KnL5XpLAwqvFohEIiCRSBjyIp2lUukZ4WqGtJiDCpJ4kQo0mUyaiXDhcDhJJKATi1lRFN88AKg23G7360sWa8AOh+P5Q4CiIQjCCzLP8+QPjuOeGAk2Gg3QarUAjFJqUM3Xf3QfiwtvRWixWIBms6l9+/1+alCjFHksazA9/rrE5PF4QDQaBSzLAlgoQK1WowbCunWs4z3WShusNAMjwVgsBjKZDOB5HrTbbWpweNd/kEaSFivL5fLbNeFQKATS6bQtcFi1vuNafQQGehGHymp48V+Dy51Op0Y0CX+DDidxEe6sbjVHZ7NZNZVKqdVq9Sov0omrlF4oTrKUFuqBQKAPrbqFOdZxzQSv1wt8Ph/odrtanj4cDiAYDN7jg7jbSqVyW6/XUXBJ5x61XRZNqpNpWbzXCKAibhV8s9nYbgSMWp80TW222/qYNXuyBUwZBZKdZs+wvS2Xy6/m8/kn2Mp+JdrbPfpG/6E1xGO1vbXT0HMGLwmZpqH/L58w1x5t53Iq7aPttwADAHRPvaTBT/N4AAAAAElFTkSuQmCC) no-repeat center center transparent;
}
.step-action-right {
margin-left: 10px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQyIDc5LjE2MDkyNCwgMjAxNy8wNy8xMy0wMTowNjozOSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjk5MkFENTc3OEYwNjExRThBOUVFQjkzOTI3NTUyM0YyIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjk5MkFENTc4OEYwNjExRThBOUVFQjkzOTI3NTUyM0YyIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6OTkyQUQ1NzU4RjA2MTFFOEE5RUVCOTM5Mjc1NTIzRjIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OTkyQUQ1NzY4RjA2MTFFOEE5RUVCOTM5Mjc1NTIzRjIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz6pBYSXAAAC7klEQVR42sxXvYsaQRSf3fXcnIJ25zUiCJdgYyDYJZVgIYIg+DdoEKxDmgsp0uUfsBILsVDUxkowV1xq0S4qAUWRSCD4RdC4u3lPZi+juDprLpCBx6zue7/fvJl5HysQ/iEYzJrBzAV26r1In/VZ2CPWRWXmo4sQTpCKjEhURGYBhCFCUaiojGhmthSBLSAyiB3Emc1m/YPB4O1yuWys1+uvqqouQdabzWYM/33q9/tvUAd1qY1MMUSOnd0hfQLiyOVyz2ezWVnTtI12emxQF23QlmJwkeukl7jyTqeTBK8WmsmhKMoCbBPU+0uG3NBb3VPncDi8BQxVO3+oo9HolpLrnguHSCV6Lo5ut/vaiHQ+n5siRyy67TLlEPaJL/BS4PkYbW+r1dLS6fR25mYGLHrmdsohEGbf9RCxxGKx94Ig2A+dRa/XI6vVimQyGdJut/lCBLAQkznnLafE3OSLfD5/EwgEPhpdBJ/PtyXGBTSbTeJ2u4nL5TpJLsvyjdfrLVar1R96bLMeS8FgME4XYzji8TgJhUIE4teM5xLYxJkEtJMCJYfD8ZIH5Rxyp9P5iuXbyb2wJc9405tZcqvV+pRNJHoYWTHQ4RJ+o5eAe5RKJVKv14koiiQcDpNoNHpQD7B/gc41PP4EWYvkLwd67vF4CIQNqdVqZDKZcNmJbGmDVPfdLDF6DAVi63EkEiFXV1cH9Sj2Qwm1sD8gVL7YbLZrs9tssVhIMpkkfr/fUBcqWoctkyJDrEBl+fwvSHFMp9N7hvghjrdFvNFolGghf1RSxAT9EtMk/AlwmsSd4HX1WO4tFotaIpHQUqkUd85GTFql9EJBWI9RNpVK5R3oLg8tu1wum/UUw2iJmIjN8Jgri2dUp5NlkbsRWCy4GxIVMU41Ao/a+qAN2vK2PseaPbxwCk+7dW6zZ9jeFgqFF+Px+AO0snfY0mJry7S3d/gOdXjb23MaesngS0Ix09D/l58wxz7a9u00sx9tvwUYAP+6zi4St3UbAAAAAElFTkSuQmCC) no-repeat center center transparent;
}
.step-ul-outer {
flex: 1;
position: relative;
overflow: hidden;
}
.step-ul {
display: flex;
flex-direction: row;
align-items: center;
font-size: 14px;
position: absolute;
padding: 5px 0;
margin-left: 70px;
}
.step-item {
position: relative;
width: 12px;
height: 12px;
color: #0081cc;
flex-shrink: 0;
flex-grow: 0;
background: #fff;
border-radius: 6px;
text-align: center;
}
.step-desc {
position: absolute;
top: 23px;
left: -50px;
width: 100px;
overflow: hidden;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 12px;
color: #333;
}
.step-item.stepDone {
background: #0081cc;
color: #fff;
}
.step-item.stepDoing {
background: #0081cc;
box-shadow: 0 0 0 3px rgba(0, 129, 204, 0.3);
}
.step-item.stepUndo {
background: #c1c0c1;
}
.step-line {
height: 1px;
width: 100px;
background-color: #ccc;
flex-shrink: 0;
flex-grow: 0;
}
.step-line.stepDone {
background-color: #0081cc;
}
.step-new .step-item.stepDone {
background: #3fb992;
color: #fff;
}
.step-new .step-line.stepDone{
background-color: #3fb992;
}
.step-new .step-item.stepDoing {
background: #2bb1ff;
box-shadow: 0 0 0 3px rgba(43, 177, 255, 0.3);
}
.step-new .step-item.stepUndo {
background: #e1e1e1;
}
.step-new .step-line{
background-color: #e1e1e1;
}
`
],
})
export class StepComponent implements OnInit, AfterViewInit, OnDestroy {
@ViewChild('stepUl') stepUl: ElementRef;
@ViewChild('stepUlP') stepUlP: ElementRef;
@Input() stepData: Array;
@Input() showKey = 'name';
@Input() idKey = 'id';
@Input() currentData: any;
@Input() newStep: boolean;
@Input() newWidth: number=100;
currentIndex = 0;
showActionFlag = false;
resizeEvent: any;
hoverMoveTimer: any;
itemWidth = 12;
constructor() {
}
ngOnInit() {
this.findCurrentIndex();
this.resizeEvent = Observable.fromEvent(window, 'resize').subscribe(event => {
this.calcIsShowStepAction();
});
}
ngOnDestroy() {
if (this.resizeEvent) {
this.resizeEvent.unsubscribe();
}
}
ngAfterViewInit() {
setTimeout(() => {
this.calcIsShowStepAction();
}, 10);
setTimeout(() => {
this.showActionItem();
}, 20);
}
showActionItem() {
const i = this.currentIndex;
if (i * this.newWidth + i * this.itemWidth + 120 > this.stepUlP.nativeElement.offsetWidth) {
if (i === this.stepData.length - 1) { // 最后一个
this.stepUl.nativeElement.style.left = -(i * this.newWidth + i * this.itemWidth + 120 - this.stepUlP.nativeElement.offsetWidth) + 'px';
} else { // 非最后一个
this.stepUl.nativeElement.style.left = -(i * this.newWidth + i * this.itemWidth + 220 - this.stepUlP.nativeElement.offsetWidth) + 'px';
}
}
}
calcIsShowStepAction() {
if (!this.stepUl || !this.stepUlP) {
return false;
}
const l = this.stepData.length;
const ulWidth = (l - 1) * this.newWidth + l * this.itemWidth;
const ulPWidth = this.stepUlP.nativeElement.offsetWidth;
if (ulWidth + 120 > ulPWidth) {
this.showActionFlag = true;
} else {
this.showActionFlag = false;
}
}
findCurrentIndex() {
if (this.currentData) {
let flag = true;
for (let i = 0; i < this.stepData.length; i++) {
if (this.stepData[i][this.idKey] == this.currentData[this.idKey]) {
this.currentIndex = i;
flag = false;
break;
}
}
if (flag) {
this.currentIndex = this.stepData.length;
}
} else {
this.currentIndex = this.stepData.length;
}
}
stepActionHout() {
if (this.hoverMoveTimer) {
clearInterval(this.hoverMoveTimer);
this.hoverMoveTimer = null;
}
}
stepActionHover(offset: string) {
if (this.hoverMoveTimer) {
clearInterval(this.hoverMoveTimer);
this.hoverMoveTimer = null;
}
this.hoverMoveTimer = setInterval(() => {
this.stepUlMove(offset, 2);
}, 10);
}
stepActionDown(offset: string) {
if (this.hoverMoveTimer) {
clearInterval(this.hoverMoveTimer);
this.hoverMoveTimer = null;
}
this.hoverMoveTimer = setInterval(() => {
this.stepUlMove(offset, 6);
}, 10);
}
stepActionUp(offset: string) {
if (this.hoverMoveTimer) {
clearInterval(this.hoverMoveTimer);
this.hoverMoveTimer = null;
}
this.hoverMoveTimer = setInterval(() => {
this.stepUlMove(offset, 1);
}, 10);
}
stepUlMove(offset: string, step: number) {
const stepUl = this.stepUl.nativeElement;
const left = stepUl.offsetLeft - 70;
const l = this.stepData.length;
const ulWidth = (l - 1) * this.newWidth + l * this.itemWidth + (this.newWidth==100 ? 120 : this.newWidth);
const ulPWidth = this.stepUlP.nativeElement.offsetWidth;
let leftRes = 0;
if (offset === 'left') {
if (ulWidth - Math.abs(left) <= ulPWidth) {
leftRes = left;
} else {
if (ulWidth - Math.abs(left) - step <= ulPWidth) {
leftRes = -(ulWidth - ulPWidth);
} else {
leftRes = left - step;
}
}
} else if (offset === 'right') {
if (left >= 0) {
leftRes = 0;
} else {
if (left + step >= 0) {
leftRes = 0;
} else {
leftRes = left + step;
}
}
}
stepUl.style.left = leftRes + 'px';
}
}