vvcomponent
Version:
VV组件
172 lines (171 loc) • 6.01 kB
JavaScript
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);