TASK: #105604-add indicator-page-deformation component.

This commit is contained in:
wangchangqi 2022-09-27 16:42:02 +08:00
parent bb6692cd37
commit a5e3253454
8 changed files with 340 additions and 43 deletions

View File

@ -71,7 +71,7 @@ export class StarLockNumber extends LitElement {
`
}
timer() {
this.time = setInterval(() => {
this.time = window.setInterval(() => {
if (--this.second <= 0) {
clearInterval(this.time)
this.second = 120

View File

@ -8,9 +8,9 @@
### 属性
- `src`: 要高斯模糊的图片URL
- `src`: 要高斯模糊的图片 URL
- `sigma`: 高斯模糊程度系数,除了第一次传值时不会有模糊渐变,之后传值时图片模糊会呈渐变,如若不需要动画则调用方法 `showImmediately` 并传值
- `threshold`: 当 `sigma` 大于该值时组件采用模糊算法否则采用降低分辨率的方法模糊图片默认值为1
- `threshold`: 当 `sigma` 大于该值时,组件采用模糊算法,否则采用降低分辨率的方法模糊图片,默认值为 1
- `during`: 模糊渐变的最长时间,单位为 `ms`,默认值为 500
- `bezier`: 模糊渐变的贝塞尔系数,接受参数为一个有四个数字元素的数组,默认值为 `[0.19, 1, 0.22, 1]`
@ -18,45 +18,44 @@
注意,请不要使用跨域图片资源,否则无法转化为 `ImageData` 进行模糊计算
```html
<gauss-canvas src="./test.png" sigma="1"></gauss-canvas>
```
```js
import "@star-web-element/gauss"
const canvas = document.querySelector('gauss-canvas');
import '@star-web-element/gauss'
const canvas = document.querySelector('gauss-canvas')
canvas.addEventListener('click', () => {
// 会有模糊渐变
canvas.sigma ^= 10
// 会有模糊渐变
canvas.sigma ^= 10
})
canvas.addEventListener('mousedown', handleEvent);
canvas.addEventListener('mousemove', handleEvent);
canvas.addEventListener('mouseup', handleEvent);
canvas.addEventListener('mousedown', handleEvent)
canvas.addEventListener('mousemove', handleEvent)
canvas.addEventListener('mouseup', handleEvent)
let mouseData = {
start: 0,
moveDistance: 0,
start: 0,
moveDistance: 0,
}
function handleEvent(evt) {
switch (evt.type) {
case 'mousedown':
mouseData.start = evt.clientY;
break;
case ' mousemove':
if (mouseData.start) {
mouseData.moveDistance = evt.clientY - mouseData.start;
const conHeight = canvas.parentElement.offsetHeight;
const targetSigma = (mouseData.moveDistance / conHeight) * 10;
// 不会有模糊渐变
canvas.showImmediately(targetSigma);
}
break;
case 'mouseup':
mouseData.start = mouseData.moveDistance = 0;
break;
}
switch (evt.type) {
case 'mousedown':
mouseData.start = evt.clientY
break
case ' mousemove':
if (mouseData.start) {
mouseData.moveDistance = evt.clientY - mouseData.start
const conHeight = canvas.parentElement.offsetHeight
const targetSigma = (mouseData.moveDistance / conHeight) * 10
// 不会有模糊渐变
canvas.showImmediately(targetSigma)
}
break
case 'mouseup':
mouseData.start = mouseData.moveDistance = 0
break
}
}
```

View File

@ -0,0 +1,134 @@
import {html, css, LitElement, PropertyValueMap, svg} from 'lit'
import {customElement, property, state} from 'lit/decorators.js'
@customElement('indicator-page-deformation')
export class IndicatorPageDeformation extends LitElement {
@property({type: Number, reflect: true}) total = 1
@property({type: Number, reflect: true}) index = 1
@property({type: Boolean, reflect: true}) edit = false
@property({type: Boolean, reflect: true}) column = false
#firstRender = true
@state() width = 22 + (this.total - 1) * (4 * 2 + 8)
@state() viewBox = `0 0 ${this.width} ${4 * 2}`
@state() rectBeginX = (this.index - 1) * (4 * 2 + 8)
protected shouldUpdate(_changedProperties: PropertyValueMap<this>): boolean {
let isShouldUpdate = true
if (this.total < 1) {
console.warn(
'indicator total setted a error num: ',
this.total,
' will be resetted 1'
)
this.total = 1
isShouldUpdate = false
} else if (this.total > 15) {
console.warn(
'indicator total setted a error num: ',
this.total,
' will be resetted 15'
)
this.total = 15
isShouldUpdate = false
}
if (this.index < 1) {
console.warn(
'indicator index setted a error num: ',
this.index,
' will be resetted 1'
)
this.index = 1
isShouldUpdate = false
} else if (this.index > this.total) {
console.warn(
'indicator index setted a error num: ',
this.index,
' will be resetted',
this.total
)
this.index = this.total
isShouldUpdate = false
}
if (this.#firstRender === true) {
this.#firstRender = false
return true
}
return isShouldUpdate
}
/**
*
*
* 4---8---224---8---4
*/
render() {
const all = []
let hasRectFlag = false
for (let i = 1; i <= this.total; i++) {
if (i == this.index) {
all.push(
svg`<rect x=${this.rectBeginX} y=0 rx=4 ry=4 width=22 height=8 />`
)
hasRectFlag = true
} else {
let cx = 0
if (all.length == 0) cx = 4
else if (hasRectFlag) cx = 30 + (all.length - 1) * 16 + 4
else cx = all.length * 16 + 4
all.push(svg`<circle cx=${cx} cy=4 r=4 />`)
}
}
return html`
<svg viewBox=${this.viewBox} xmlns="http://www.w3.org/2000/svg">
${all}
</svg>
`
}
static styles = css`
:host {
display: flex;
width: 100%;
margin: auto;
max-height: 50px;
}
:host([column]) {
display: inline-flex;
width: auto;
}
svg {
flex: 1;
}
svg rect,
:host(.light) svg rect {
fill: #ffffff;
fill-opacity: 0.85;
}
svg circle,
:host(.light) svg circle {
fill: #ffffff;
fill-opacity: 0.4;
}
:host(.dark) svg rect {
fill: #1b1b1b;
fill-opacity: 0.7;
}
:host(.dark) svg circle {
fill: #1b1b1b;
fill-opacity: 0.3;
}
`
}
declare global {
interface HTMLElementTagNameMap {
'indicator-page-deformation': IndicatorPageDeformation
}
}

View File

@ -0,0 +1,13 @@
# 指示器
## 页面指示器
### 页面圆点指示器
基本类型
### 页面横条指示器
圆点+横条,由 svg 组成。
TODO: 添加可形变动画。

View File

@ -0,0 +1,140 @@
import {html, css, LitElement, CSSResultArray} from 'lit'
import {customElement, state} from 'lit/decorators.js'
import {sharedStyles} from '../shared-styles'
import '../../../components/indicator/indicator-page-deformation'
@customElement('panel-deformation-indicator')
export class PanelDeformationIndicator extends LitElement {
@state() total = 1
@state() index = 1
@state() edit = false
updated() {
this.total = this.total < 1 ? 1 : this.total > 15 ? 15 : this.total
this.index =
this.index < 1 ? 1 : this.index > this.total ? this.total : this.index
}
handleEvent(evt: Event) {
switch (evt.type) {
case 'click':
evt.preventDefault() // iOS上不禁止按钮默认行为将会双击按钮强制放缩屏幕
switch ((evt.target as HTMLButtonElement).dataset.action) {
case 'total++':
this.total++
break
case 'total--':
this.total--
break
case 'index++':
this.index++
break
case 'index--':
this.index--
break
case 'toggle-edit':
this.edit = !this.edit
break
}
}
}
render() {
return html`
<h3></h3>
<indicator-page-deformation
total="1"
index="1"
></indicator-page-deformation>
<indicator-page-deformation
class="dark"
total="1"
index="1"
></indicator-page-deformation>
<indicator-page-deformation
total="3"
index="-1"
edit
></indicator-page-deformation>
<indicator-page-deformation
class="dark"
total="3"
index="-1"
edit
></indicator-page-deformation>
<indicator-page-deformation
total="5"
index="2"
></indicator-page-deformation>
<indicator-page-deformation
class="dark"
total="5"
index="2"
></indicator-page-deformation>
<indicator-page-deformation
total="15"
index="2"
></indicator-page-deformation>
<indicator-page-deformation
class="dark"
total="15"
index="2"
></indicator-page-deformation>
<!-- todo -->
<!-- <h3></h3>
<indicator-page-deformation total="3" index="1" edit></indicator-page-deformation>
<indicator-page-deformation total="5" index="2" edit></indicator-page-deformation>
<indicator-page-deformation total="15" index="2" edit></indicator-page-deformation> -->
<h3></h3>
<div>
<div>
<button data-action="total++" @click=${this}>total++</button>
<button data-action="total--" @click=${this}>total--</button>
<button data-action="index++" @click=${this}>index++</button>
<button data-action="index--" @click=${this}>index--</button>
<button data-action="toggle-edit" @click=${this}>toggle edit</button>
</div>
</div>
<indicator-page-deformation
total=${this.total}
index=${this.index}
?edit=${this.edit}
></indicator-page-deformation>
<indicator-page-deformation
class="dark"
total=${this.total}
index=${this.index}
?edit=${this.edit}
></indicator-page-deformation>
`
}
public static override get styles(): CSSResultArray {
return [
sharedStyles,
css`
h3 {
text-align: center;
}
div {
display: flex;
margin: auto;
flex-wrap: wrap;
}
button {
margin: auto;
}
indicator-page-deformation {
height: 10px;
margin: 20px 0;
}
`,
]
}
}
declare global {
interface HTMLElementTagNameMap {
'panel-deformation-indicator': PanelDeformationIndicator
}
}

View File

@ -3,8 +3,8 @@ import {customElement, state} from 'lit/decorators.js'
import {sharedStyles} from '../shared-styles'
import '../../../components/indicator/indicator-page-point'
@customElement('panel-indicators')
export class PanelIndicators extends LitElement {
@customElement('panel-point-indicator')
export class PanelPointIndicator extends LitElement {
@state() total = 1
@state() index = 1
@state() edit = false
@ -123,6 +123,6 @@ export class PanelIndicators extends LitElement {
declare global {
interface HTMLElementTagNameMap {
'panel-indicators': PanelIndicators
'panel-point-indicator': PanelPointIndicator
}
}

View File

@ -11,8 +11,9 @@ import './icon/icon'
import './general/general'
import './gesture/gesture'
import './card/card'
import './indicators/indicators'
import './indicators/deformation-indicator'
import './indicators/home-indicator'
import './indicators/point-indicator'
import './blur/use-blur'
import './gauss_canvas/gauss-blur'
import './button/button'
@ -243,14 +244,6 @@ export class PanelRoot extends LitElement {
href="#confirm"
></star-li>
<hr />
<star-li
type=${LiType.ICON_LABEL}
label="页面圆点指示器"
icon="accessibility"
iconcolor="blue"
href="#indicators"
></star-li>
<hr />
<star-li
type=${LiType.ICON_LABEL}
label="毛玻璃"
@ -327,6 +320,24 @@ export class PanelRoot extends LitElement {
></star-li>
</star-ul>
<star-ul type=${UlType.ONLY_HEADER} title="指示器">
<star-li
type=${LiType.ICON_LABEL}
label="页面圆点指示器"
icon="accessibility"
iconcolor="blue"
href="#point-indicator"
></star-li>
<hr />
<star-li
type=${LiType.ICON_LABEL}
label="页面横条指示器"
icon="accessibility"
iconcolor="blue"
href="#deformation-indicator"
></star-li>
</star-ul>
<star-ul type=${UlType.BASE}>
<star-li
type=${LiType.ONLY_EDIT}

View File

@ -9,7 +9,7 @@ import '../icon/icon'
import '../about/about'
import '../icon/icon'
import '../general/general'
import '../indicators/indicators'
import '../indicators/deformation-indicator'
import '../blur/use-blur'
@customElement('panel-switch')