UNPKG

ng-cw-v12

Version:

Angular UI component library

165 lines (160 loc) 8.03 kB
import * as i0 from '@angular/core'; import { EventEmitter, Directive, Input, Output, NgModule } from '@angular/core'; class ShineBorderDirective { constructor(el, renderer) { this.el = el; this.renderer = renderer; this.ncBorderWidth = 1; // 边框宽度 单位px this.ncDuration = 14000; // 动画时长,ms this.ncStopTime = 0; // 停止动画时间,ms,0表示不停止 this.ncShineColor = ["#A07CFE", "#FE8FB5", "#FFBE7B"]; // 光效颜色,可以是单色或颜色数组 this.ncEnabled = true; // 是否启用动画 this.ncEnabledChange = new EventEmitter(); // 双向绑定输出事件 this.isInitialized = false; // 为每个实例生成唯一的动画名称 this.animationName = `ncShineBorder_${Math.random().toString(36).substring(2, 11)}`; } ngOnInit() { this.createShineBorderContainer(); 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); } } createShineBorderContainer() { // 创建shine边框元素 this.shineElement = this.renderer.createElement('div'); this.renderer.addClass(this.shineElement, 'shine-border'); // 确保宿主元素具有相对定位 const elementPosition = this.el.nativeElement.style.position; if (!elementPosition || elementPosition === 'static') { this.renderer.setStyle(this.el.nativeElement, 'position', 'relative'); } // 获取shine颜色 const shineColors = Array.isArray(this.ncShineColor) ? this.ncShineColor.join(',') : this.ncShineColor; // 设置shine边框样式 this.renderer.setStyle(this.shineElement, 'position', 'absolute'); this.renderer.setStyle(this.shineElement, 'inset', '0'); this.renderer.setStyle(this.shineElement, 'width', '100%'); this.renderer.setStyle(this.shineElement, 'height', '100%'); this.renderer.setStyle(this.shineElement, 'borderRadius', 'inherit'); this.renderer.setStyle(this.shineElement, 'pointerEvents', 'none'); this.renderer.setStyle(this.shineElement, 'backgroundImage', `radial-gradient(transparent,transparent, ${shineColors},transparent,transparent)`); this.renderer.setStyle(this.shineElement, 'backgroundSize', '300% 300%'); this.renderer.setStyle(this.shineElement, 'padding', `${this.ncBorderWidth}px`); // 设置mask属性 this.renderer.setStyle(this.shineElement, 'mask', 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)'); this.renderer.setStyle(this.shineElement, '-webkit-mask', 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)'); this.renderer.setStyle(this.shineElement, '-webkit-mask-composite', 'xor'); this.renderer.setStyle(this.shineElement, 'mask-composite', 'exclude'); this.renderer.setStyle(this.shineElement, 'will-change', 'background-position'); // 初始状态下隐藏边框 this.renderer.setStyle(this.shineElement, 'display', 'none'); // 添加关键帧动画样式 this.styleElement = this.renderer.createElement('style'); const keyframes = ` @keyframes ${this.animationName} { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } `; this.renderer.appendChild(this.styleElement, this.renderer.createText(keyframes)); this.renderer.appendChild(this.el.nativeElement, this.styleElement); // 将shine元素添加到宿主元素中 this.renderer.appendChild(this.el.nativeElement, this.shineElement); } startAnimation() { if (!this.shineElement) return; // 启动动画时显示边框 this.renderer.setStyle(this.shineElement, 'display', 'block'); // 启动shine动画 this.renderer.setStyle(this.shineElement, 'animation', `${this.animationName} ${this.ncDuration}ms ease-in-out infinite`); // 如果设置了停止时间,则在指定时间后标记需要停止 if (this.ncStopTime > 0) { this.stopTimer = setTimeout(() => { this.stopAnimation(); // 当因为 ncStopTime 停止动画时,更新 ncEnabled 值并发出事件 this.ncEnabled = false; this.ncEnabledChange.emit(false); }, this.ncStopTime); } } stopAnimation() { if (!this.shineElement) return; if (this.stopTimer) { clearTimeout(this.stopTimer); this.stopTimer = null; } this.renderer.setStyle(this.shineElement, 'animation', 'none'); // 停止动画时隐藏边框 this.renderer.setStyle(this.shineElement, 'display', 'none'); } } ShineBorderDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ShineBorderDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); ShineBorderDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.1.5", type: ShineBorderDirective, selector: "[ncShineBorder]", inputs: { ncBorderWidth: "ncBorderWidth", ncDuration: "ncDuration", ncStopTime: "ncStopTime", ncShineColor: "ncShineColor", ncEnabled: "ncEnabled" }, outputs: { ncEnabledChange: "ncEnabledChange" }, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: ShineBorderDirective, decorators: [{ type: Directive, args: [{ selector: '[ncShineBorder]' }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { ncBorderWidth: [{ type: Input }], ncDuration: [{ type: Input }], ncStopTime: [{ type: Input }], ncShineColor: [{ type: Input }], ncEnabled: [{ type: Input }], ncEnabledChange: [{ type: Output }] } }); class NcShineBorderModule { } NcShineBorderModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcShineBorderModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); NcShineBorderModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcShineBorderModule, declarations: [ShineBorderDirective], exports: [ShineBorderDirective] }); NcShineBorderModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcShineBorderModule, imports: [[]] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.5", ngImport: i0, type: NcShineBorderModule, decorators: [{ type: NgModule, args: [{ declarations: [ ShineBorderDirective ], imports: [], exports: [ ShineBorderDirective ] }] }] }); /** * Generated bundle index. Do not edit. */ export { NcShineBorderModule, ShineBorderDirective }; //# sourceMappingURL=ng-cw-v12-shine-border.js.map