TASK: #111576 按键解锁组件化完成

This commit is contained in:
duanzhijiang 2022-09-21 19:06:08 +08:00
parent aa1cc92678
commit a53ca1ae9c
6 changed files with 388 additions and 2 deletions

View File

@ -0,0 +1,14 @@
# 数字密码-digicipher
工作职责:
- 由0-9数字组成的数字密码
- 默认密码为 `123456`
- 点击数字反馈,输入成功上滑,输入错误抖动反馈
## 使用
```
<star-digicipher></star-digicipher>
```

View File

@ -0,0 +1,171 @@
import {css, CSSResult} from 'lit'
export const sharedStyles: CSSResult = css`
body {
margin: 0;
padding: 0;
user-select: none;
}
p,
button,
i,
h2,
.cancel,
.delete {
font-family: 'OPPOSans';
margin-top: 0;
color: #292929;
}
span {
position: relative;
width: 12px;
height: 12px;
border-radius: 50%;
display: inline-block;
margin-right: 20px;
background: #000000;
opacity: 0.2;
}
p {
position: absolute;
font-family: 'OPPOSans';
font-style: normal;
font-weight: 400;
color: #292929;
}
#zero {
position: absolute;
left: 44.15%;
top: 70%;
}
button {
position: relative;
width: 70px;
height: 70px;
border-radius: 50%;
border: none;
/*button背景无色*/
background: rgba(0, 0, 0, 0);
display: inline-block;
font-size: 35px;
}
/*按钮点击的效果*/
button::before {
content: '';
display: none;
position: absolute;
top: 2px;
left: 1px;
width: 70px;
height: 70px;
border-radius: 50%;
background-color: #ffffff;
opacity: 0.35;
}
.block::before {
display: block;
}
#slideUp {
position: absolute;
height: 100%;
width: 100%;
}
.topText {
font-size: 20px;
height: 26.5px;
line-height: 26.5px;
width: 80px;
left: calc(50% - 80px / 2 + 3px);
top: calc(50% - 26.5px / 2 - 168.75px);
}
.spanContainer {
position: absolute;
left: 206px;
top: 349.5px;
}
.grid {
position: absolute;
display: grid;
grid-template-areas: '1 2 3 ' '4 5 6' '7 8 9' '. 0 .';
grid-gap: 20px;
margin: 404px 176px;
}
.cancel,
.delete {
position: absolute;
font-family: 'OPPOSans';
font-style: normal;
font-weight: 400;
color: #292929;
width: 36px;
height: 23.5px;
line-height: 23.5px;
font-size: 18px;
}
.cancel {
left: calc(50% - 36px / 2 - 90px);
top: calc(50% - 23.5px / 2 + 231.75px);
}
.delete {
left: calc(50% - 36px / 2 + 90px);
top: calc(50% - 23.5px / 2 + 231.75px);
}
.cancel:hover,
.delete:hover {
cursor: pointer;
}
.cancel:active,
.delete:active {
color: #777;
transition: color 0.5s;
}
/*抖动反馈*/
@keyframes errtips {
10% {
transform: translateY(2px);
}
20% {
transform: translateY(-2px);
}
30% {
transform: translateY(2px);
}
40% {
transform: translateY(2px);
}
50% {
transform: translateY(-2px);
}
60% {
transform: translateY(2px);
}
70% {
transform: translateY(-2px);
}
80% {
transform: translateY(2px);
}
90% {
transform: translateY(-2px);
}
100% {
transform: translateY(0);
}
}
/*密码输入正确后动效*/
@keyframes suctip {
0% {
transform: translateY(0);
}
100% {
transform: translateY(-1000px);
}
}
`

View File

@ -0,0 +1,152 @@
import {html, LitElement, CSSResultArray} from 'lit'
import {customElement, property, query, queryAll} from 'lit/decorators.js'
import {sharedStyles} from './digicipher-style'
@customElement('star-digicipher')
export class StarLockNumber extends LitElement {
public static override get styles(): CSSResultArray {
return [sharedStyles]
}
@query('#slideUp') slideUp!: HTMLDivElement
@queryAll('button') buttons!: NodeListOf<HTMLButtonElement>
@query('zero') zero!: HTMLButtonElement
@queryAll('span') span!: NodeListOf<HTMLSpanElement>
@query('spanContainer') spanContainer!: HTMLDivElement
@query('#parent') parent!: HTMLDivElement
@query('.delete') _delete!: HTMLParagraphElement
@query('.cancel') cancel!: HTMLParagraphElement
@query('.topText') topText!: HTMLParagraphElement
@query('.screen') screen!: HTMLDivElement
@property({type: Number}) clicks = 0
@property({type: Number}) _number = 0
@property({type: Number}) clickNumber = 0
@property({type: String}) color = ''
@property({type: String}) opacity = ''
@property({type: String}) guess = ''
@property({type: String}) passwd = '123456'
render() {
return html`
<div id="slideUp">
<p class="topText"></p>
<div class="spanContainer">
<span id="sOne"></span>
<span id="sTwo"></span>
<span id="sThree"></span>
<span id="sFour"></span>
<span id="sFive"></span>
<span id="sSix"></span>
</div>
<div
id="parent"
@touchstart=${this.touchStart}
@touchend=${this.touchEnd}
>
<button class="0" id="zero" data-num="0">0</button>
<div class="grid">
<button data-num="1">1</button>
<button data-num="2">2</button>
<button data-num="3">3</button>
<button data-num="4">4</button>
<button data-num="5">5</button>
<button data-num="6">6</button>
<button data-num="7">7</button>
<button data-num="8">8</button>
<button data-num="9">9</button>
</div>
<p class="cancel" id="lockCancel"></p>
<p class="delete"></p>
</div>
</div>
`
}
touchStart(e: TouchEvent) {
e.preventDefault()
// console.log('e.target', (e.target as HTMLElement).dataset.num)
// console.log('click', this.clickNumber)
// 点击数字,圆点变色并输出
if ((e.target as Element).tagName === 'BUTTON') {
this.clickNumber = Number((e.target as HTMLElement).dataset.num)
this.makeZero()
//点击反馈
this.changeNumberBgColor()
if (this.clicks < 6) {
//圆点变化
this.changeBgColor('#333333', this.clicks, 1)
this.clicks += 1
this.guess += (e.target as HTMLElement).dataset.num
console.log('输入后为:', this.guess)
}
//密码错误
if (this.clicks == 6 && this.guess !== this.passwd) {
console.log('密码错误')
// 抖动反馈
for (let i = 0; i < 10; i++) {
this.buttons[i].style.setProperty('animation', 'errtips .5s')
}
//清空密码且删除抖动反馈
for (let i = 0; i < 6; i++) {
this.changeBgColor('#000000', i, 0.2)
}
this.guess = ''
this.clicks = 0
}
} else if ((e.target as Element).className === 'delete') {
if (this.clicks == 0) {
console.log('不可再删除')
} else {
this.clicks -= 1
this.changeBgColor('#000000', this.clicks, 0.2)
this.guess = this.guess.slice(0, -1)
console.log('删除后为:', this.guess)
}
} else if ((e.target as Element).className === 'cancel') {
//点击取消,返回锁屏
console.log('返回锁屏')
// this.makeZero()
for (let i = 0; i < 6; i++) {
this.changeBgColor('#000000', i, 0.2)
}
this.guess = ''
this.clicks = 0
}
if (this.guess === this.passwd) {
for (let j = 0; j < 10; j++) {
this.buttons[j].removeAttribute('style')
}
console.log('密码正确')
// this.slideUp.removeAttribute('style')
for (let i = 0; i < 6; i++) {
this.changeBgColor('#000000', i, 0.2)
}
this.guess = ''
this.clicks = 0
this.slideUp.style.setProperty('animation', 'suctip .6s')
}
}
touchEnd(e: TouchEvent) {
if ((e.target as Element).tagName === 'BUTTON') {
this.removeNumberBgColor()
}
}
changeBgColor(color: string, _number: number, opacity: number) {
this.span[_number].style.backgroundColor = color
this.span[_number].style.opacity = String(opacity)
}
removeNumberBgColor() {
this.buttons[this.clickNumber].classList.remove('block')
}
changeNumberBgColor() {
this.buttons[this.clickNumber].classList.add('block')
}
makeZero() {
//抖动、滑动属性清零
this.slideUp.removeAttribute('style')
for (let j = 0; j < 10; j++) {
this.buttons[j].removeAttribute('style')
}
}
}

View File

@ -16,6 +16,9 @@ import './components/picker/picker'
import './components/overflowmenu/overflowmenu' import './components/overflowmenu/overflowmenu'
import './components/slider/slider' import './components/slider/slider'
import './components/prompt/prompt' import './components/prompt/prompt'
import './components/prompt/prompt'
import './components/digicipher/digicipher'
import './components/pattern-view/pattern-view'
@customElement('settings-app') @customElement('settings-app')
export class SettingsApp extends LitElement { export class SettingsApp extends LitElement {

View File

@ -0,0 +1,28 @@
import {html, LitElement, css} from 'lit'
import {customElement, property} from 'lit/decorators.js'
import '../icon/icon'
@customElement('panel-digicipher')
export class PanelDigicipher extends LitElement {
static styles = css`
.screen {
position: absolute;
height: 100%;
width: 100%;
background-color: rgb(124, 194, 235);
}
`
render() {
return html`
<div class="screen">
<star-digicipher></star-digicipher>
</div>
`
}
}
declare global {
interface HTMLElementTagNameMap {
'panel-digicipher': PanelDigicipher
}
}

View File

@ -20,6 +20,8 @@ import './confirm/confirm'
import './overflowmenu/overflowmenu' import './overflowmenu/overflowmenu'
import './switch/switch' import './switch/switch'
import './slider/slider' import './slider/slider'
import './digicipher/digicipher'
import './pattern-view/pattern-view'
import './container/homescreen-container' import './container/homescreen-container'
import './toast/toast' import './toast/toast'
import './picker/picker' import './picker/picker'
@ -116,7 +118,7 @@ export class PanelRoot extends LitElement {
type=${LiType.ICON_LABEL} type=${LiType.ICON_LABEL}
label="开关" label="开关"
icon="switch" icon="switch"
iconcolor="black" iconcolor="#EB7347"
href="#switch" href="#switch"
></star-li> ></star-li>
<hr /> <hr />
@ -124,10 +126,26 @@ export class PanelRoot extends LitElement {
type=${LiType.ICON_LABEL} type=${LiType.ICON_LABEL}
label="滑动条" label="滑动条"
icon="scene" icon="scene"
iconcolor="brown" iconcolor="#EB7347"
href="#slider" href="#slider"
></star-li> ></star-li>
<hr /> <hr />
<star-li
type=${LiType.ICON_LABEL}
label="Digicipher"
icon="lock"
iconcolor="#EB7347"
href="#digicipher"
></star-li>
<hr />
<star-li
type=${LiType.ICON_LABEL}
label="PatternView"
icon="lock"
iconcolor="#EB7347"
href="#pattern-view"
></star-li>
<hr />
<star-li <star-li
type=${LiType.ICON_LABEL} type=${LiType.ICON_LABEL}
label="按钮" label="按钮"