import { Component, OnInit, HostBinding, Input, ContentChildren, AfterContentInit, QueryList, ComponentFactoryResolver, ViewContainerRef, Injector, ApplicationRef, Renderer2, ElementRef, ViewChild, AfterViewInit } from '@angular/core';
import { SplitterPaneComponent } from './splitter-pane.component';
import { SplitterBarComponent } from './splitter-bar.component';
@Component({
selector: 'farris-splitter',
template: `
`,
styles: []
})
export class SplitterComponent implements OnInit, AfterContentInit, AfterViewInit {
@HostBinding('class.f-component-splitter') splitterCls = true;
// @HostBinding('class.d-flex') flexCls = true;
@Input() orientation = "horizontal";
hostEl: HTMLElement;
@ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;
@ContentChildren(SplitterPaneComponent) pane: QueryList;
barComponentRefArray: any[] = [];
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private injector: Injector,
private renderer: Renderer2,
private elementRef: ElementRef
) { }
ngOnInit() {
}
ngAfterContentInit() {
}
ngAfterViewInit() {
//使用的是ngResizable,没有使用Bar,此处方法可不执行
this.hostEl = this.elementRef.nativeElement;
// this.initPane();
}
initPane() {
if (this.pane && this.pane['_results'] && this.pane['_results'].length) {
let hostWidth = this.hostEl.offsetWidth;
const length = this.pane['_results'].length;
const restPane = this.pane['_results'].filter(item => {
return !item._size;
});
const restLength = restPane.length;
this.pane['_results'].forEach((item, index) => {
item.order = index * 2;
if (!!item._size) {
hostWidth = hostWidth - this.getElementSize(hostWidth, item._size);
}
})
restPane.forEach(item => {
item.size = hostWidth / restLength;
})
if (length > 1) {
this.createBar(length - 1);
}
this.listenPaneSizeChange();
}
}
listenPaneSizeChange() {
const hostWidth = this.hostEl.offsetWidth;
this.pane['_results'].forEach((item, index) => {
item.sizeChange.subscribe(size => {
const nextIndex = index + 1;
const diff = item.el.offsetWidth - size;
if (this.pane['_results'][nextIndex]) {
const nextPaneMin = this.getElementSize(hostWidth, this.pane['_results'][nextIndex].min);
if (this.barComponentRefArray[nextIndex]) {
// 拖拽向左的最大宽度
if (nextPaneMin >= item.el.offsetWidth || nextPaneMin <= 0) {
this.barComponentRefArray[nextIndex].instance.leftMovedMax = this.pane['_results'][nextIndex].el.offsetWidth + diff;
} else {
this.barComponentRefArray[nextIndex].instance.leftMovedMax = this.pane['_results'][nextIndex].el.offsetWidth + diff - nextPaneMin;
}
}
}
})
})
}
// 获取目标元素的size
getElementSize(hostWidth: number, size: any): number {
let targetSize: number;
if (!size) {
targetSize = 0;
return targetSize;
}
if (size.indexOf('px') !== -1 || typeof size === 'number') {
targetSize = parseInt(size);
} else if (size.indexOf('%') !== -1) {
targetSize = hostWidth * parseInt(size) / 100;
}
return targetSize;
}
createBar(len: number) {
let size: any;
const hostWidth = this.hostEl.offsetWidth;
for (let i = 0; i < len; i++) {
const factory = this.componentFactoryResolver.resolveComponentFactory(SplitterBarComponent);
const componentRef = this.container.createComponent(factory);
const prevPane = this.pane['_results'][i];
const prevPaneOriginWidth = prevPane.el.offsetWidth;
const nextPane = this.pane['_results'][i + 1];
const nextPaneOriginWidth = nextPane.el.offsetWidth;
const prePaneMax = this.getElementSize(hostWidth, this.pane['_results'][i].max);
const prePaneMin = this.getElementSize(hostWidth, this.pane['_results'][i].min);
// 拖拽向右的最大宽度
if (prePaneMax <= prevPaneOriginWidth && prePaneMax > 0) {
componentRef.instance.rightMovedMax = 0;
} else if (prePaneMax >= prevPaneOriginWidth + nextPaneOriginWidth || prePaneMax === 0) {
componentRef.instance.rightMovedMax = nextPaneOriginWidth;
} else {
componentRef.instance.rightMovedMax = prePaneMax - prevPaneOriginWidth;
}
// 拖拽向左的最大宽度
if (prePaneMin >= prevPaneOriginWidth || prePaneMin <= 0) {
componentRef.instance.leftMovedMax = prevPaneOriginWidth;
} else {
componentRef.instance.leftMovedMax = prevPaneOriginWidth - prePaneMin;
}
// 横向拖拽还是纵向拖拽
if (this.orientation === 'horizontal') {
componentRef.instance.lockAxis = 'y';
} else if (this.orientation === 'vertical') {
componentRef.instance.lockAxis = 'x';
}
componentRef.instance.order = 2 * i + 1;
// 拖拽变化
componentRef.instance.endOffset.subscribe(data => {
prevPane.size = prevPane.el.offsetWidth + data.x;
nextPane.size = nextPane.el.offsetWidth - data.x;
// console.log(prevPanelOriginWidth + data.x, nextPanelOriginWidth - data.x)
})
this.barComponentRefArray.push(componentRef);
componentRef.changeDetectorRef.detectChanges();
}
}
}