UNPKG

ng-cw-v12

Version:

Angular UI component library

179 lines (174 loc) 8.8 kB
import * as i0 from '@angular/core'; import { EventEmitter, Directive, Input, Output, NgModule } from '@angular/core'; class BorderBeamDirective { constructor(el, renderer) { this.el = el; this.renderer = renderer; this.ncSize = 50; // 光条大小 单位px this.ncDuration = 6000; // 动画时长,ms this.ncStopTime = 0; // 停止动画时间,ms,0表示不停止 this.ncColorFrom = '#ffaa40'; // 渐变起始颜色 this.ncColorTo = '#9c40ff'; // 渐变结束颜色 this._reverse = false; // 是否反向动画 this.ncInitialOffset = 0; // 初始偏移位置 (0-100) 单位% this.ncBorderWidth = 1; // 边框宽度 单位px this.ncEnabled = true; // 是否启用动画 this.ncEnabledChange = new EventEmitter(); // 双向绑定输出事件 this.isInitialized = false; // 为每个实例生成唯一的动画名称 this.animationName = `ncBorderBeam_${Math.random().toString(36).substring(2, 11)}`; } set ncReverse(val) { this._reverse = val !== null && val !== undefined && val !== false && val !== 'false'; } get ncReverse() { return this._reverse; } ngOnInit() { this.createBorderBeamContainer(); this.isInitialized = true; if (this.ncEnabled) { this.startAnimation(); } } ngOnChanges(changes) { if (this.isInitialized && changes['ncEnabled']) { if (this.ncEnabled) { this.startAnimation(); } else { this.stopAnimation(); } } } ngOnDestroy() { if (this.stopTimer) { clearTimeout(this.stopTimer); } } createBorderBeamContainer() { // 创建边框容器 this.borderContainer = this.renderer.createElement('div'); this.renderer.addClass(this.borderContainer, 'border-beam-container'); // 设置边框容器样式 this.renderer.setStyle(this.borderContainer, 'position', 'absolute'); this.renderer.setStyle(this.borderContainer, 'inset', '0'); this.renderer.setStyle(this.borderContainer, 'borderRadius', 'inherit'); this.renderer.setStyle(this.borderContainer, 'pointerEvents', 'none'); this.renderer.setStyle(this.borderContainer, 'border', `${this.ncBorderWidth}px solid transparent`); this.renderer.setStyle(this.borderContainer, 'maskClip', 'padding-box, border-box'); this.renderer.setStyle(this.borderContainer, 'maskComposite', 'intersect'); this.renderer.setStyle(this.borderContainer, 'maskImage', 'linear-gradient(transparent, transparent), linear-gradient(#000, #000)'); // 创建光条元素 this.beamElement = this.renderer.createElement('div'); this.renderer.addClass(this.beamElement, 'border-beam'); // 设置光条样式 this.renderer.setStyle(this.beamElement, 'position', 'absolute'); this.renderer.setStyle(this.beamElement, 'width', `${this.ncSize}px`); this.renderer.setStyle(this.beamElement, 'aspectRatio', '1'); this.renderer.setStyle(this.beamElement, 'background', `linear-gradient(to left, ${this.ncColorFrom}, ${this.ncColorTo}, transparent)`); this.renderer.setStyle(this.beamElement, 'offsetPath', `rect(0 auto auto 0 round ${this.ncSize}px)`); // 初始状态下隐藏光条 this.renderer.setStyle(this.beamElement, 'opacity', '0'); const elementPosition = this.el.nativeElement.style.position; if (!elementPosition || elementPosition === 'static') { this.renderer.setStyle(this.el.nativeElement, 'position', 'relative'); } // 添加关键帧动画样式 this.styleElement = this.renderer.createElement('style'); const startOffset = this.ncReverse ? `${100 - this.ncInitialOffset}%` : `${this.ncInitialOffset}%`; const endOffset = this.ncReverse ? `${-this.ncInitialOffset}%` : `${100 + this.ncInitialOffset}%`; const keyframes = ` @keyframes ${this.animationName} { 0% { offset-distance: ${startOffset}; } 100% { offset-distance: ${endOffset}; } } `; this.renderer.appendChild(this.styleElement, this.renderer.createText(keyframes)); this.renderer.appendChild(this.el.nativeElement, this.styleElement); // 将光条添加到边框容器中 this.renderer.appendChild(this.borderContainer, this.beamElement); // 将边框容器添加到宿主元素中 this.renderer.appendChild(this.el.nativeElement, this.borderContainer); } startAnimation() { if (!this.beamElement) return; // 显示光条元素 this.renderer.setStyle(this.beamElement, 'opacity', '1'); this.renderer.setStyle(this.beamElement, 'animation', `${this.animationName} ${this.ncDuration}ms linear infinite`); // 如果设置了停止时间,则在指定时间后标记需要停止 if (this.ncStopTime > 0) { this.stopTimer = setTimeout(() => { this.stopAnimation(); // 当因为 ncStopTime 停止动画时,更新 ncEnabled 值并发出事件 this.ncEnabled = false; this.ncEnabledChange.emit(false); }, this.ncStopTime); } } stopAnimation() { if (!this.beamElement) return; if (this.stopTimer) { clearTimeout(this.stopTimer); this.stopTimer = null; } this.renderer.setStyle(this.beamElement, 'animation', 'none'); this.renderer.setStyle(this.beamElement, 'opacity', '0'); } } BorderBeamDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: BorderBeamDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); BorderBeamDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.1.5", type: BorderBeamDirective, selector: "[ncBorderBeam]", inputs: { ncSize: "ncSize", ncDuration: "ncDuration", ncStopTime: "ncStopTime", ncColorFrom: "ncColorFrom", ncColorTo: "ncColorTo", ncReverse: "ncReverse", ncInitialOffset: "ncInitialOffset", ncBorderWidth: "ncBorderWidth", ncEnabled: "ncEnabled" }, outputs: { ncEnabledChange: "ncEnabledChange" }, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: BorderBeamDirective, decorators: [{ type: Directive, args: [{ selector: '[ncBorderBeam]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { ncSize: [{ type: Input }], ncDuration: [{ type: Input }], ncStopTime: [{ type: Input }], ncColorFrom: [{ type: Input }], ncColorTo: [{ type: Input }], ncReverse: [{ type: Input }], ncInitialOffset: [{ type: Input }], ncBorderWidth: [{ type: Input }], ncEnabled: [{ type: Input }], ncEnabledChange: [{ type: Output }] } }); class NcBorderBeamModule { } NcBorderBeamModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcBorderBeamModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); NcBorderBeamModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcBorderBeamModule, declarations: [BorderBeamDirective], exports: [BorderBeamDirective] }); NcBorderBeamModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcBorderBeamModule, imports: [[]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcBorderBeamModule, decorators: [{ type: NgModule, args: [{ declarations: [ BorderBeamDirective ], imports: [], exports: [ BorderBeamDirective ] }] }] }); /** * Generated bundle index. Do not edit. */ export { BorderBeamDirective, NcBorderBeamModule }; //# sourceMappingURL=ng-cw-v12-border-beam.js.map