From 7b8bf84d3c8cdefa708eda30116c468318047fe9 Mon Sep 17 00:00:00 2001 From: duanzhijiang Date: Fri, 9 Sep 2022 11:00:22 +0800 Subject: [PATCH 1/4] =?UTF-8?q?TASK:=20#=E7=82=B9=E5=87=BBsliderBar?= =?UTF-8?q?=E5=B0=8F=E7=90=83=E8=B7=B3=E8=BD=AC=E4=BB=A5=E5=8F=8Adisabled?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E3=80=81unfilled=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/slider/slider-styles.ts | 9 +++ src/components/slider/slider.ts | 93 +++++++++++++++++--------- src/test/panels/slider/slider.ts | 12 ++-- 3 files changed, 79 insertions(+), 35 deletions(-) diff --git a/src/components/slider/slider-styles.ts b/src/components/slider/slider-styles.ts index 237be0a..68f873d 100644 --- a/src/components/slider/slider-styles.ts +++ b/src/components/slider/slider-styles.ts @@ -46,4 +46,13 @@ export const sharedStyles: CSSResult = css` right: 5px; top: 1px; } + :host([disabled]) .progress { + background: #c0c0c0; + } + :host([disabled]) .dot { + background: #d5d5d5; + } + :host([unfilled]) .progress { + background: none; + } ` diff --git a/src/components/slider/slider.ts b/src/components/slider/slider.ts index fa55319..a5cce7b 100644 --- a/src/components/slider/slider.ts +++ b/src/components/slider/slider.ts @@ -1,6 +1,7 @@ import {html, LitElement, CSSResultArray} from 'lit' import {customElement, property, query} from 'lit/decorators.js' import {sharedStyles} from './slider-styles' +import {state} from 'lit/decorators.js' export const variants = ['filled', 'tick'] @@ -16,6 +17,7 @@ export class StarSlider extends LitElement { @query('.progress') progress!: HTMLDivElement @query('.dot') dot!: HTMLDivElement @query('p') p!: HTMLParagraphElement + @property({type: Boolean}) disabled = false @property({type: Number}) startX = 0 @property({type: Number}) touchX = 0 @property({type: Number}) moveX = 0 @@ -24,11 +26,7 @@ export class StarSlider extends LitElement { @property({type: Number}) dotL = 0 @property({type: Number}) proportion = 0 @property({type: String}) pValue = '' - @property({type: Number}) sliderBarLeft = 0 - @property({type: Number}) sliderBarRight = 0 - @property({type: Number}) ball = 0 - @property({type: String}) sliderCoverWidth = '' - @property({type: String}) ballMove = '' + @property({type: Number}) barX = 0 @property({type: String}) get coverWidth() { return this._coverWidth @@ -36,16 +34,18 @@ export class StarSlider extends LitElement { set coverWidth(value: string) { this.style.setProperty('--cover-width', value) this._coverWidth = value + this.style.setProperty('--dot-move', this._coverWidth) } render() { return html`

${this.pValue}

-
+
` } + private touchStart(evt: TouchEvent) { - this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth //总长度减去小球覆盖的部分 - this.dotL = this.dot.offsetLeft //小球左侧相对于父元素的左边距 - this.startX = evt.touches[0].clientX //手指点下的 X 坐标 + if (!this.disabled) { + this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth //总长度减去小球覆盖的部分 + this.dotL = this.dot.offsetLeft //小球左侧相对于父元素的左边距 + console.log('dotL', this.dotL) + this.startX = evt.touches[0].clientX //手指点下的 X 坐标 + } } private touchMove(evt: TouchEvent) { - //阻止默认行为 - evt.preventDefault() - this.touchX = evt.touches[0].clientX //整个屏幕实时触摸的 X 坐标 - this.moveX = this.touchX - this.startX //手指移动的距离 - //判断最大值和最小值 - this.newX = this.dotL + this.moveX - if (this.newX < 0) { - this.newX = 0 + if (!this.disabled) { + //阻止默认行为 + evt.preventDefault() + this.touchX = evt.touches[0].clientX //整个屏幕实时触摸的 X 坐标 + this.moveX = this.touchX - this.startX //手指移动的距离 + //判断最大值和最小值 + this.newX = this.dotL + this.moveX + if (this.newX < 0) { + this.newX = 0 + } + if (this.newX >= this.barWidth) { + this.newX = this.barWidth + } + //改变dot的left值 + this.style.setProperty('--dot-move', this.newX + 'px') + //计算比例 + this.proportion = (this.newX / this.barWidth) * 100 + this.pValue = Math.ceil(this.proportion) + '' + this.progress.style.setProperty( + 'width', + (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' + ) } - if (this.newX >= this.barWidth) { - this.newX = this.barWidth - } - //改变dot的left值 - this.style.setProperty('--dot-move', this.newX + 'px') - //计算比例 - this.proportion = (this.newX / this.barWidth) * 100 - this.pValue = Math.ceil(this.proportion) + '' - this.progress.style.setProperty( - 'width', - (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' - ) } private touchEnd(evt: TouchEvent) { return console.log(this.pValue) } -} + //点击sliderBar + // @eventOptions({capture: true}) + private clickBar(evt: TouchEvent) { + if (!this.disabled) { + this.touchX = evt.touches[0].clientX //手指触摸的 x 坐标 + // 黑色覆盖部分 + this.barX = + this.touchX - + this.sliderBar.getBoundingClientRect().left - + this.dot.offsetWidth * 0.5 + this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth + console.log('barx', this.barX, this.barWidth) + if (this.barX < 0) { + this.barX = 0 + } + if (this.barX >= this.barWidth) { + this.barX = this.barWidth + } + this.style.setProperty('--dot-move', this.barX + 'px') + this.proportion = (this.barX / this.barWidth) * 100 + this.pValue = Math.ceil(this.proportion) + '' + this.progress.style.setProperty( + 'width', + (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' + ) + } + } +} declare global { interface HTMLElementTagNameMap { 'star-slider': StarSlider diff --git a/src/test/panels/slider/slider.ts b/src/test/panels/slider/slider.ts index fa301f0..20f815b 100644 --- a/src/test/panels/slider/slider.ts +++ b/src/test/panels/slider/slider.ts @@ -15,15 +15,17 @@ export class PanelSlider extends LitElement { render() { return html`
-

default

+

default - 默认

-

初始化覆盖长度

+

coverWidth - 初始覆盖长度

+

unfilled - 无覆盖

+ +

disabled

- - - + +
` } From a90254a4b8f3b795d1642b5eb43ed68de5bb5641 Mon Sep 17 00:00:00 2001 From: duanzhijiang Date: Sun, 11 Sep 2022 16:57:51 +0800 Subject: [PATCH 2/4] =?UTF-8?q?TASK:=20#slider=E4=B8=ADtick=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=E5=AE=9E=E7=8E=B0=E5=8F=8A=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/slider/README.md | 27 ++++++++++++------- src/components/slider/slider-styles.ts | 23 +++++++++++----- src/components/slider/slider.ts | 36 ++++++++++++++++++++------ src/test/panels/slider/slider.ts | 16 ++++++++---- 4 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/components/slider/README.md b/src/components/slider/README.md index 93e314e..dbebb9a 100644 --- a/src/components/slider/README.md +++ b/src/components/slider/README.md @@ -11,27 +11,36 @@ ``` ``` - -2. 滑块中小球左侧进行填充 --- `filled` +2. `coverWidth` --- 初始填充 ``` - + + ``` -3. 禁用滑块 --- `disabled` +3. `disabled` --- 禁用滑块 ``` + ``` - -4. 分格滑块 --- `Tick` +4. `unfilled` --- 滑块中小球左侧不进行填充 ``` - - + + + ``` -5. 左侧图标|滑块|右侧图标 + +5. `Tick` --- 分格滑块 + +``` + + +``` + +6. 左侧图标|滑块|右侧图标 ``` diff --git a/src/components/slider/slider-styles.ts b/src/components/slider/slider-styles.ts index 68f873d..ff62cbb 100644 --- a/src/components/slider/slider-styles.ts +++ b/src/components/slider/slider-styles.ts @@ -1,8 +1,8 @@ import {css, CSSResult} from 'lit' export const sharedStyles: CSSResult = css` :host { - --cover-width: 100px; - --dot-move: 87px; + --cover-width: 0px; + --dot-move: 0px; } .content { margin: 5px 5px; @@ -24,7 +24,6 @@ export const sharedStyles: CSSResult = css` .progress { position: absolute; width: var(--cover-width); - /*width: 100px;*/ height: 6px; left: 0px; right: 0px; @@ -35,9 +34,9 @@ export const sharedStyles: CSSResult = css` .dot { position: absolute; left: var(--dot-move); - width: 26px; - height: 26px; - top: calc(50% - 26px / 2); + width: 20px; + height: 20px; + top: calc(50% - 20px / 2); background: #544f4f; border-radius: 50%; } @@ -49,10 +48,22 @@ export const sharedStyles: CSSResult = css` :host([disabled]) .progress { background: #c0c0c0; } + :host([disabled]) .step { + background: #c0c0c0; + } :host([disabled]) .dot { background: #d5d5d5; } :host([unfilled]) .progress { background: none; } + .step { + position: absolute; + left: calc(var(--i) * 100%); + top: calc(50% - 10px / 2); + width: 3px; + height: 10px; + background-color: #544f4f; + border-radius: 3px; + } ` diff --git a/src/components/slider/slider.ts b/src/components/slider/slider.ts index a5cce7b..289f423 100644 --- a/src/components/slider/slider.ts +++ b/src/components/slider/slider.ts @@ -1,9 +1,12 @@ -import {html, LitElement, CSSResultArray} from 'lit' +import {html, LitElement, CSSResultArray, PropertyValueMap} from 'lit' import {customElement, property, query} from 'lit/decorators.js' import {sharedStyles} from './slider-styles' -import {state} from 'lit/decorators.js' -export const variants = ['filled', 'tick'] +// export enum VARIANT { +// BASE = 'base', +// TICK = 'tick', +// ICON = 'icon', +// } @customElement('star-slider') export class StarSlider extends LitElement { @@ -17,7 +20,9 @@ export class StarSlider extends LitElement { @query('.progress') progress!: HTMLDivElement @query('.dot') dot!: HTMLDivElement @query('p') p!: HTMLParagraphElement + @property({type: Boolean}) disabled = false + @property({type: Boolean}) tick = false @property({type: Number}) startX = 0 @property({type: Number}) touchX = 0 @property({type: Number}) moveX = 0 @@ -25,8 +30,9 @@ export class StarSlider extends LitElement { @property({type: Number}) barWidth = 0 @property({type: Number}) dotL = 0 @property({type: Number}) proportion = 0 - @property({type: String}) pValue = '' @property({type: Number}) barX = 0 + @property({type: String}) pValue = '' + @property({type: String}) step = '' @property({type: String}) get coverWidth() { return this._coverWidth @@ -39,13 +45,14 @@ export class StarSlider extends LitElement { render() { return html` +
-

${this.pValue}

` } + protected firstUpdated( + _changedProperties: PropertyValueMap | Map + ): void { + if (this.tick) { + var tickStep = 100 / parseInt(this.step) + for (let i = 1; i < tickStep; i++) { + const stepTick = document.createElement('div') + stepTick.style.setProperty('--i', String(i / tickStep)) + stepTick.classList.add('step') + this.sliderBar.appendChild(stepTick) + } + } + } private touchStart(evt: TouchEvent) { if (!this.disabled) { + this.startX = evt.touches[0].clientX //手指点下的初始 X 坐标 this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth //总长度减去小球覆盖的部分 + this.dotL = this.dot.offsetLeft //小球左侧相对于父元素的左边距 - console.log('dotL', this.dotL) - this.startX = evt.touches[0].clientX //手指点下的 X 坐标 } } private touchMove(evt: TouchEvent) { @@ -81,6 +101,7 @@ export class StarSlider extends LitElement { this.style.setProperty('--dot-move', this.newX + 'px') //计算比例 this.proportion = (this.newX / this.barWidth) * 100 + //取整 this.pValue = Math.ceil(this.proportion) + '' this.progress.style.setProperty( 'width', @@ -103,7 +124,6 @@ export class StarSlider extends LitElement { this.sliderBar.getBoundingClientRect().left - this.dot.offsetWidth * 0.5 this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth - console.log('barx', this.barX, this.barWidth) if (this.barX < 0) { this.barX = 0 } diff --git a/src/test/panels/slider/slider.ts b/src/test/panels/slider/slider.ts index 20f815b..053c3cc 100644 --- a/src/test/panels/slider/slider.ts +++ b/src/test/panels/slider/slider.ts @@ -20,12 +20,18 @@ export class PanelSlider extends LitElement {

coverWidth - 初始覆盖长度

-

unfilled - 无覆盖

- -

disabled

- - + + +

unfilled - 无覆盖

+ + +

tick

+ + + + +
` } From 6b4408e0a35f0f92a139e36a09ed19bd2881660c Mon Sep 17 00:00:00 2001 From: duanzhijiang Date: Wed, 14 Sep 2022 15:39:17 +0800 Subject: [PATCH 3/4] =?UTF-8?q?TASK:=20#109540=20=E5=88=97slider=E8=B7=9F?= =?UTF-8?q?=E6=89=8B=E6=8B=96=E5=8A=A8=EF=BC=8C=E8=A1=8Cslider=E9=83=A8?= =?UTF-8?q?=E5=88=86=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/slider/README.md | 10 +- src/components/slider/slider-styles.ts | 45 +++++++- src/components/slider/slider.ts | 145 ++++++++++++++++++++----- src/test/panels/slider/slider.ts | 21 +++- 4 files changed, 184 insertions(+), 37 deletions(-) diff --git a/src/components/slider/README.md b/src/components/slider/README.md index dbebb9a..38dcec7 100644 --- a/src/components/slider/README.md +++ b/src/components/slider/README.md @@ -37,10 +37,16 @@ ``` - + ``` +6. `vertical` --- 垂直slider -6. 左侧图标|滑块|右侧图标 +``` + + + +``` +7. 左侧图标|滑块|右侧图标 ``` diff --git a/src/components/slider/slider-styles.ts b/src/components/slider/slider-styles.ts index ff62cbb..3d5c471 100644 --- a/src/components/slider/slider-styles.ts +++ b/src/components/slider/slider-styles.ts @@ -3,14 +3,35 @@ export const sharedStyles: CSSResult = css` :host { --cover-width: 0px; --dot-move: 0px; + --vWidth: 8px; } .content { - margin: 5px 5px; + height: 2px; + margin: 50px; position: relative; - padding: 50px 50px; - border: 1px solid skyblue; + padding: 8px; + /*border: 1px solid skyblue;*/ border-radius: 5px; } + .v-content { + width: 2px; + margin: 0px 2px; + position: relative; + padding: 200px 10px; + /*border: 1px solid skyblue;*/ + border-radius: 5px; + } + + .v-sliderBar { + position: absolute; + width: var(--vWidth); + height: 100%; + left: calc(50% - 8px / 2); + top: 0px; + background: rgba(0, 0, 0, 0.08); + border-radius: 20px; + } + .sliderBar { position: absolute; width: 100%; @@ -18,8 +39,17 @@ export const sharedStyles: CSSResult = css` left: 0px; right: 0px; top: calc(50% - 6px / 2); - background: rgba(0, 0, 0, 0.06); - border-radius: 5px; + background: rgba(0, 0, 0, 0.08); + border-radius: 8px; + } + .v-progress { + position: absolute; + width: var(--vWidth); + height: var(--cover-width); + left: 0px; + bottom: 0px; + border-radius: 0 0 20px 20px; + background: #404040; } .progress { position: absolute; @@ -29,7 +59,7 @@ export const sharedStyles: CSSResult = css` right: 0px; top: calc(50% - 6px / 2); background: #4d4d4d; - border-radius: 5px; + border-radius: 5px 0 0 5px; } .dot { position: absolute; @@ -48,6 +78,9 @@ export const sharedStyles: CSSResult = css` :host([disabled]) .progress { background: #c0c0c0; } + :host([disabled]) .v-progress { + background: #c0c0c0; + } :host([disabled]) .step { background: #c0c0c0; } diff --git a/src/components/slider/slider.ts b/src/components/slider/slider.ts index 289f423..cb7185e 100644 --- a/src/components/slider/slider.ts +++ b/src/components/slider/slider.ts @@ -2,12 +2,6 @@ import {html, LitElement, CSSResultArray, PropertyValueMap} from 'lit' import {customElement, property, query} from 'lit/decorators.js' import {sharedStyles} from './slider-styles' -// export enum VARIANT { -// BASE = 'base', -// TICK = 'tick', -// ICON = 'icon', -// } - @customElement('star-slider') export class StarSlider extends LitElement { _coverWidth: string = '' @@ -18,20 +12,27 @@ export class StarSlider extends LitElement { @query('.content') content!: HTMLDivElement @query('.sliderBar') sliderBar!: HTMLDivElement @query('.progress') progress!: HTMLDivElement + @query('.v-sliderBar') vSliderBar!: HTMLDivElement + @query('.v-progress') vProgress!: HTMLDivElement @query('.dot') dot!: HTMLDivElement @query('p') p!: HTMLParagraphElement @property({type: Boolean}) disabled = false @property({type: Boolean}) tick = false + @property({type: Boolean}) vertical = false @property({type: Number}) startX = 0 + @property({type: Number}) startY = 0 @property({type: Number}) touchX = 0 + @property({type: Number}) touchY = 0 @property({type: Number}) moveX = 0 + @property({type: Number}) moveY = 0 @property({type: Number}) newX = 0 + @property({type: Number}) newY = 0 @property({type: Number}) barWidth = 0 @property({type: Number}) dotL = 0 @property({type: Number}) proportion = 0 @property({type: Number}) barX = 0 - @property({type: String}) pValue = '' + @property({type: String}) endValue = '' @property({type: String}) step = '' @property({type: String}) get coverWidth() { @@ -44,22 +45,43 @@ export class StarSlider extends LitElement { } render() { - return html` - -
-
-
-
+ if (!this.vertical) { + return html` +
+
+
+
+
-
- ` + ` + } else { + return html` +
+
+
+
+
+ ` + } } protected firstUpdated( _changedProperties: PropertyValueMap | Map @@ -77,9 +99,28 @@ export class StarSlider extends LitElement { private touchStart(evt: TouchEvent) { if (!this.disabled) { - this.startX = evt.touches[0].clientX //手指点下的初始 X 坐标 + this.touchX = evt.touches[0].clientX //手指触摸的 x 坐标 + // 黑色覆盖部分 + this.barX = + this.touchX - + this.sliderBar.getBoundingClientRect().left - + this.dot.offsetWidth * 0.5 + this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth + if (this.barX < 0) { + this.barX = 0 + } + if (this.barX >= this.barWidth) { + this.barX = this.barWidth + } + this.style.setProperty('--dot-move', this.barX + 'px') + this.proportion = (this.barX / this.barWidth) * 100 + this.endValue = Math.ceil(this.proportion) + '' + this.progress.style.setProperty( + 'width', + (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' + ) + this.startX = evt.touches[0].clientX //手指点下的初始 X&Y 坐标 this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth //总长度减去小球覆盖的部分 - this.dotL = this.dot.offsetLeft //小球左侧相对于父元素的左边距 } } @@ -89,20 +130,24 @@ export class StarSlider extends LitElement { evt.preventDefault() this.touchX = evt.touches[0].clientX //整个屏幕实时触摸的 X 坐标 this.moveX = this.touchX - this.startX //手指移动的距离 + // console.log(this.moveX) + //判断最大值和最小值 this.newX = this.dotL + this.moveX if (this.newX < 0) { + // console.log('到0了') this.newX = 0 } if (this.newX >= this.barWidth) { + // console.log('超了') this.newX = this.barWidth } //改变dot的left值 - this.style.setProperty('--dot-move', this.newX + 'px') //计算比例 this.proportion = (this.newX / this.barWidth) * 100 //取整 - this.pValue = Math.ceil(this.proportion) + '' + this.endValue = Math.ceil(this.proportion) + '' + this.style.setProperty('--dot-move', this.newX + 'px') this.progress.style.setProperty( 'width', (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' @@ -110,7 +155,48 @@ export class StarSlider extends LitElement { } } private touchEnd(evt: TouchEvent) { - return console.log(this.pValue) + return console.log(this.endValue) + } + + private touchStartVertical(evt: TouchEvent) { + if (!this.disabled) { + this.startY = evt.touches[0].clientY //手指点下的初始 Y 坐标 + this.barWidth = this.vSliderBar.offsetHeight //总长度 + this.dotL = this.barWidth - this.vProgress.offsetTop //黑条长度 + //按压音量条变宽 + this.vSliderBar.style.setProperty('width', '16px') + this.vProgress.style.setProperty('width', '16px') + } + } + private touchMoveVertical(evt: TouchEvent) { + if (!this.disabled) { + //阻止默认行为 + evt.preventDefault() + this.touchY = evt.touches[0].clientY //整个屏幕实时触摸的 Y 坐标 + this.moveY = this.startY - this.touchY //手指移动的距离 + //判断最大值和最小值 + this.newY = this.dotL + this.moveY + if (this.newY < 0) { + // console.log('到底了') + this.newY = 0 + } + if (this.newY >= this.barWidth) { + // console.log('超了') + this.newY = this.barWidth + } + //计算比例 + this.proportion = (this.newY / this.barWidth) * 100 + //取整 + this.endValue = Math.ceil(this.proportion) + '' + this.vProgress.style.setProperty('height', this.newY + 'px') + } + } + private touchEndVertical(evt: TouchEvent) { + if (!this.disabled) { + this.vProgress.style.setProperty('width', '8px') + this.vSliderBar.style.setProperty('width', '8px') + return console.log(this.endValue) + } } //点击sliderBar @@ -132,11 +218,14 @@ export class StarSlider extends LitElement { } this.style.setProperty('--dot-move', this.barX + 'px') this.proportion = (this.barX / this.barWidth) * 100 - this.pValue = Math.ceil(this.proportion) + '' + this.endValue = Math.ceil(this.proportion) + '' this.progress.style.setProperty( 'width', (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' ) + this.startX = evt.touches[0].clientX //手指点下的初始 X&Y 坐标 + this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth //总长度减去小球覆盖的部分 + this.dotL = this.dot.offsetLeft //小球左侧相对于父元素的左边距 } } } diff --git a/src/test/panels/slider/slider.ts b/src/test/panels/slider/slider.ts index 053c3cc..c9dc110 100644 --- a/src/test/panels/slider/slider.ts +++ b/src/test/panels/slider/slider.ts @@ -1,8 +1,11 @@ import {html, LitElement, css} from 'lit' -import {customElement} from 'lit/decorators.js' +import {customElement, property} from 'lit/decorators.js' +import '../icon/icon' @customElement('panel-slider') export class PanelSlider extends LitElement { + @property({type: String}) icon = '' + static styles = css` div { position: relative; @@ -10,11 +13,27 @@ export class PanelSlider extends LitElement { margin: 50px 50px; border-radius: 5px; } + #a { + position: absolute; + left: 100px; + top: 66px; + } + #b { + position: absolute; + left: 200px; + top: 66px; + } ` render() { return html`
+

vertical

+ + + +

default - 默认

coverWidth - 初始覆盖长度

From 7bf0619903d54f572a82b2989902dc87248bb8e5 Mon Sep 17 00:00:00 2001 From: duanzhijiang Date: Wed, 14 Sep 2022 20:12:43 +0800 Subject: [PATCH 4/4] =?UTF-8?q?TASK:=20#109540=20=E8=A1=8Cslider=E4=B8=ADt?= =?UTF-8?q?ick=E5=B1=9E=E6=80=A7=E7=BB=93=E6=9E=84=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E3=80=81=E8=B7=B3=E6=A0=BC=E8=BF=90=E5=8A=A8?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E8=B7=9F=E6=89=8B=E8=B7=B3=E6=A0=BC=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/slider/README.md | 20 +++- src/components/slider/slider-styles.ts | 40 +++++++- src/components/slider/slider.ts | 130 +++++++++++++------------ src/test/panels/slider/slider.ts | 40 +++++--- 4 files changed, 147 insertions(+), 83 deletions(-) diff --git a/src/components/slider/README.md b/src/components/slider/README.md index 38dcec7..f8c3136 100644 --- a/src/components/slider/README.md +++ b/src/components/slider/README.md @@ -3,6 +3,7 @@ 工作职责: - 滑块空间 +- 滑块拖动后返回value值 ## 类型包括: @@ -33,11 +34,18 @@ ``` -5. `Tick` --- 分格滑块 +5. `Tick` --- 分格滑块(默认是unfilled属性) + min=0,mix=100,按照需求填写step(每一格)的大小
+ example :
+ step="25" 表示把slider分为4块
+ coverWidth="40%" 表示初始小球落在第二格上 + + + ``` - + ``` 6. `vertical` --- 垂直slider @@ -49,5 +57,11 @@ 7. 左侧图标|滑块|右侧图标 ``` - + +

+
``` + +## 后续需解决的问题: +- tick 属性中小球不能完全覆盖step +- vertical 属性变化太快 diff --git a/src/components/slider/slider-styles.ts b/src/components/slider/slider-styles.ts index 3d5c471..ec59347 100644 --- a/src/components/slider/slider-styles.ts +++ b/src/components/slider/slider-styles.ts @@ -25,11 +25,12 @@ export const sharedStyles: CSSResult = css` .v-sliderBar { position: absolute; width: var(--vWidth); - height: 100%; - left: calc(50% - 8px / 2); + height: 80%; + left: calc(50% - var(--vWidth) / 2); top: 0px; background: rgba(0, 0, 0, 0.08); border-radius: 20px; + overflow: hidden; } .sliderBar { @@ -69,6 +70,7 @@ export const sharedStyles: CSSResult = css` top: calc(50% - 20px / 2); background: #544f4f; border-radius: 50%; + z-index: 1; } p { position: absolute; @@ -84,19 +86,47 @@ export const sharedStyles: CSSResult = css` :host([disabled]) .step { background: #c0c0c0; } + :host([tick]) .step { + background: #c0c0c0; + } + :host([tick]) .sliderBar { + background: #c0c0c0; + border-radius: 0 0 0 0; + height: 4px; + } :host([disabled]) .dot { - background: #d5d5d5; + background: #c0c0c0; } :host([unfilled]) .progress { background: none; } + :host([tick]) .progress { + background: none; + } .step { position: absolute; - left: calc(var(--i) * 100%); + left: calc(var(--i) * 99.3%); top: calc(50% - 10px / 2); width: 3px; height: 10px; - background-color: #544f4f; + background-color: #d5d5d5; border-radius: 3px; } + ::slotted(span)::before { + font-size: 27px; + font-family: 'gaia-icons'; + content: attr(data-icon); + text-align: center; + position: relative; + top: 357px; + } + ::slotted(p)::before { + font-size: 27px; + font-family: 'gaia-icons'; + content: attr(data-icon); + text-align: center; + position: relative; + top: 74px; + left: 5px; + } ` diff --git a/src/components/slider/slider.ts b/src/components/slider/slider.ts index cb7185e..5d6ae0c 100644 --- a/src/components/slider/slider.ts +++ b/src/components/slider/slider.ts @@ -47,24 +47,23 @@ export class StarSlider extends LitElement { render() { if (!this.vertical) { return html` +
-
+
` } else { return html` +
-
+
` @@ -86,9 +80,14 @@ export class StarSlider extends LitElement { protected firstUpdated( _changedProperties: PropertyValueMap | Map ): void { + if (this.vertical) { + this.touchStart = this.touchStartVertical + this.touchEnd = this.touchEndVertical + this.touchMove = this.touchMoveVertical + } if (this.tick) { var tickStep = 100 / parseInt(this.step) - for (let i = 1; i < tickStep; i++) { + for (let i = 0; i <= tickStep; i++) { const stepTick = document.createElement('div') stepTick.style.setProperty('--i', String(i / tickStep)) stepTick.classList.add('step') @@ -112,13 +111,30 @@ export class StarSlider extends LitElement { if (this.barX >= this.barWidth) { this.barX = this.barWidth } - this.style.setProperty('--dot-move', this.barX + 'px') this.proportion = (this.barX / this.barWidth) * 100 this.endValue = Math.ceil(this.proportion) + '' - this.progress.style.setProperty( - 'width', - (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' - ) + if (this.tick) { + // tick跳格滑动 + var tickStep = 100 / parseInt(this.step) //分为几格 + for (let i = 0; i <= tickStep; i++) { + if (this.barX > (this.barWidth * (i + 0.5)) / tickStep) { + this.style.setProperty( + '--dot-move', + (this.barWidth * (i + 1)) / tickStep + 'px' + ) + } + if (this.barX == 0) { + this.style.setProperty('--dot-move', 0 + 'px') + } + } + } else { + this.style.setProperty('--dot-move', this.barX + 'px') + this.progress.style.setProperty( + 'width', + (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' + ) + } + // 重新初始化防止滑块增量 this.startX = evt.touches[0].clientX //手指点下的初始 X&Y 坐标 this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth //总长度减去小球覆盖的部分 this.dotL = this.dot.offsetLeft //小球左侧相对于父元素的左边距 @@ -130,32 +146,54 @@ export class StarSlider extends LitElement { evt.preventDefault() this.touchX = evt.touches[0].clientX //整个屏幕实时触摸的 X 坐标 this.moveX = this.touchX - this.startX //手指移动的距离 - // console.log(this.moveX) //判断最大值和最小值 this.newX = this.dotL + this.moveX + if (this.newX < 0) { - // console.log('到0了') this.newX = 0 } if (this.newX >= this.barWidth) { - // console.log('超了') this.newX = this.barWidth } - //改变dot的left值 //计算比例 this.proportion = (this.newX / this.barWidth) * 100 //取整 this.endValue = Math.ceil(this.proportion) + '' - this.style.setProperty('--dot-move', this.newX + 'px') - this.progress.style.setProperty( - 'width', - (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' - ) + if (!this.tick) { + this.style.setProperty('--dot-move', this.newX + 'px') + this.progress.style.setProperty( + 'width', + (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' + ) + } else { + // tick跳格滑动 + var tickStep = 100 / parseInt(this.step) //分为几格 + for (let i = 0; i <= tickStep; i++) { + if (this.newX > (this.barWidth * (i + 0.5)) / tickStep) { + this.style.setProperty( + '--dot-move', + (this.barWidth * (i + 1)) / tickStep + 'px' + ) + this.proportion = + ((this.barWidth * (i + 1)) / tickStep / this.barWidth) * 100 + //取整 + this.endValue = Math.ceil(this.proportion) + '' + } + if (this.newX == 0) { + this.style.setProperty('--dot-move', 0 + 'px') + this.endValue = 0 + '' + } + } + } } } private touchEnd(evt: TouchEvent) { - return console.log(this.endValue) + if (this.tick) { + return console.log(10 * Math.round(parseInt(this.endValue) / 10) + '') + } else { + return console.log(this.endValue) + } } private touchStartVertical(evt: TouchEvent) { @@ -164,8 +202,8 @@ export class StarSlider extends LitElement { this.barWidth = this.vSliderBar.offsetHeight //总长度 this.dotL = this.barWidth - this.vProgress.offsetTop //黑条长度 //按压音量条变宽 - this.vSliderBar.style.setProperty('width', '16px') - this.vProgress.style.setProperty('width', '16px') + this.vSliderBar.style.setProperty('--vWidth', '16px') + this.vProgress.style.setProperty('--vWidth', '16px') } } private touchMoveVertical(evt: TouchEvent) { @@ -193,41 +231,11 @@ export class StarSlider extends LitElement { } private touchEndVertical(evt: TouchEvent) { if (!this.disabled) { - this.vProgress.style.setProperty('width', '8px') - this.vSliderBar.style.setProperty('width', '8px') + this.vProgress.style.setProperty('--vWidth', '8px') + this.vSliderBar.style.setProperty('--vWidth', '8px') return console.log(this.endValue) } } - - //点击sliderBar - // @eventOptions({capture: true}) - private clickBar(evt: TouchEvent) { - if (!this.disabled) { - this.touchX = evt.touches[0].clientX //手指触摸的 x 坐标 - // 黑色覆盖部分 - this.barX = - this.touchX - - this.sliderBar.getBoundingClientRect().left - - this.dot.offsetWidth * 0.5 - this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth - if (this.barX < 0) { - this.barX = 0 - } - if (this.barX >= this.barWidth) { - this.barX = this.barWidth - } - this.style.setProperty('--dot-move', this.barX + 'px') - this.proportion = (this.barX / this.barWidth) * 100 - this.endValue = Math.ceil(this.proportion) + '' - this.progress.style.setProperty( - 'width', - (this.barWidth * Math.ceil(this.proportion)) / 100 + 'px' - ) - this.startX = evt.touches[0].clientX //手指点下的初始 X&Y 坐标 - this.barWidth = this.sliderBar.offsetWidth - this.dot.offsetWidth //总长度减去小球覆盖的部分 - this.dotL = this.dot.offsetLeft //小球左侧相对于父元素的左边距 - } - } } declare global { interface HTMLElementTagNameMap { diff --git a/src/test/panels/slider/slider.ts b/src/test/panels/slider/slider.ts index c9dc110..8933900 100644 --- a/src/test/panels/slider/slider.ts +++ b/src/test/panels/slider/slider.ts @@ -9,19 +9,18 @@ export class PanelSlider extends LitElement { static styles = css` div { position: relative; - border: 1px solid; margin: 50px 50px; border-radius: 5px; } #a { position: absolute; left: 100px; - top: 66px; + top: 45px; } #b { position: absolute; left: 200px; - top: 66px; + top: 45px; } ` @@ -29,16 +28,26 @@ export class PanelSlider extends LitElement { return html`

vertical

- - - - + + + + + + + + +

default - 默认

- + +

+

coverWidth - 初始覆盖长度

- - + +

+
+ +

+

disabled

@@ -46,11 +55,14 @@ export class PanelSlider extends LitElement {

tick

+
step="10"
+
step="20"
- - - +
step="50"
+ +
step="25"
+
` }