UNPKG

vvcomponent

Version:
172 lines (171 loc) 6.01 kB
class aProgress extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this._progress = 0; this._max = 100; this._min = 0; this._color = "#007bff"; this._backgroundColor = "#e0e0e0"; this._width = 500; this._height = 20; } set backgroundColor(value) { if (value == undefined || value == null || value.trim() == "") { throw new Error("背景颜色不能为空"); } this._backgroundColor = value; this.render(); } get backgroundColor() { return this._backgroundColor; } set color(value) { if (value == undefined || value == null || value.trim() == "") { throw new Error("颜色不能为空"); } this._color = value; this.render(); } get color() { return this._color; } static get observedAttributes() { return ["min", "max", "value", "background-color", "color", "width", "height"]; } render() { console.log("渲染进度条", this._progress, this._max, this._min, this._color, this._backgroundColor, this._width, this._height); // this._progress = Math.max(this._min, Math.min(this._max, this._progress)); if (this._progress < this._min) { this._progress = this._min; throw new Error(`进度值不能小于${this._min}`); } if (this._progress > this._max) { this._progress = this._max; throw new Error(`进度值不能大于${this._max}`); } if (this._width < 0) { this._width = 0; throw new Error("进度条宽度不能小于0"); } this.shadowRoot.innerHTML = `<style> .progress-bar-container { position: relative; width: ${this._width}px; height: ${this._height}px; border-radius: ${this._height / 2}px; overflow: hidden; } .progress-bar-container .progress-bar { position: absolute; top: 0; left: 0; height: 100%; background-color: ${this._color}; border-radius: ${this._height / 2}px; transition: width .6s linear(0 0%, 0 1.8%, 0.01 3.6%, 0.03 6.35%, 0.07 9.1%, 0.13 11.4%, 0.19 13.4%, 0.27 15%, 0.34 16.1%, 0.54 18.35%, 0.66 20.6%, 0.72 22.4%, 0.77 24.6%, 0.81 27.3%, 0.85 30.4%, 0.88 35.1%, 0.92 40.6%, 0.94 47.2%, 0.96 55%, 0.98 64%, 0.99 74.4%, 1 86.4%, 1 100%); box-shadow: 0 0 15px #333; } .progress-bar-container .progress-bar-background { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--progress-background-color, #e0e0e0); transition: width 0.6s ease; box-shadow: inset 0 0 15px #999; } </style> <div class="progress-bar-container"> <div class="progress-bar-background"></div> <div class="progress-bar" style="width: ${(this._progress / (this._max - this._min)) * 100}%;"></div> </div>`; } connectedCallback() { this.render(); } attributeChangedCallback(name, oldValue, newValue) { newValue = Number(newValue); if (name == "value") { this.value = newValue; } else if (name == "min") { this.min = newValue; } else if (name == "max") { this.max = newValue; } else { throw new Error(`未知的属性 ${name}`); } } set value(value) { value = Number(value); if (value == undefined || value == null || isNaN(value)) { throw new Error("进度值不能为空或非数字"); } if (value < this._min || value > this._max) { throw new Error(`进度值必须在${this._min}和${this._max}之间`); } this._progress = value; this.updateValue(); } get value() { return Number(this._progress); } set width(value) { value = Number(value); if (value == undefined || value == null || isNaN(value)) { throw new Error("进度条宽度不能为空或非数字"); } if (value < 0) { throw new Error("进度条宽度不能小于0"); } this._width = value; const progressBarContainer = this.shadowRoot.querySelector(".progress-bar-container"); progressBarContainer.style.width = `${value}px`; this.updateValue(); } get width() { return Number(this._width); } set height(value) { value = Number(value); if (value == undefined || value == null || isNaN(value)) { throw new Error("进度条高度不能为空或非数字"); } if (value < 0) { throw new Error("进度条高度不能小于0"); } this._height = value; this.render(); } get height() { return Number(this._height); } set min(value) { value = Number(value); if (value == undefined || value == null || isNaN(value)) { throw new Error("最小值不能为空或非数字"); } this._min = value; this.updateValue(); } get min() { return Number(this._min); } set max(value) { value = Number(value); if (value == undefined || value == null || isNaN(value)) { throw new Error("最大值不能为空或非数字"); } this._max = value; this.updateValue(); } get max() { return Number(this._max); } updateValue() { const progressBar = this.shadowRoot.querySelector(".progress-bar"); progressBar.style.width = `${(this._progress / (this._max - this._min)) * 100}%`; } } customElements.define('iftc-progress', aProgress);