Merge pull request #41 in YR/star-web-components from feature-component-pattern to master

* commit '7596c5db719cd5dbd282564fd140c502c9d38f9e':
  TASK: #111576  图案密码组件化
This commit is contained in:
汪昌棋 2022-09-26 14:03:59 +08:00
commit c1d7721430
6 changed files with 329 additions and 2 deletions

View File

@ -0,0 +1,32 @@
# 图案密码 pattern-view
工作职责:
- 由九宫圆圈组成的图案密码
- 默认密码为 `012543` (滑动如下图)
```
--- --- ---
| * | **** | * | **** | * |
--- --- ---
*
--- --- ---
| * | **** | * | **** | * |
--- --- ---
--- --- ---
| | | | | |
--- --- ---
```
- 点击数字反馈,输入成功上滑,输入错误抖动反馈
### 默认
```
<star-pattern-view></star-pattern-view>
```
### 距离顶部的位置 `topDir` 默认`217.5px`
```
<star-pattern-view topDir="300px"></star-pattern-view>
<star-pattern-view topDir="-100px"></star-pattern-view>
```

View File

@ -0,0 +1,78 @@
import {css, CSSResult} from 'lit'
export const sharedStyles: CSSResult = css`
.bg {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-image: url(../assets/backgroud.png);
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
background-position: top;
}
.groundGlass {
display: none;
position: relative;
margin: auto;
width: 100%;
height: 100%;
line-height: 100%;
color: #fff;
font-size: 30px;
text-align: center;
overflow: hidden;
z-index: 10;
}
.bg ::before {
content: '';
position: absolute;
top: -100%;
left: -100%;
right: -100%;
bottom: -100%;
background-image: url(../assets/backgroud.png);
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
background-position: top;
filter: blur(10px);
z-index: -2;
}
.bg ::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(217, 217, 217, 0.65);
z-index: -1;
}
/* canvas{
position: absolute;
left: 0;
top: 11%;
right:0;
bottom:0;
margin:auto;
} */
/* #lockCancel {
position: absolute;
width: 50px;
height: 30px;
left: calc(50% - 50px/2);
top: calc(81.5%);
font-family: 'OPPOSans';
font-weight: 900;
font-size: 14px;
line-height: 30px;
color: #292929;
cursor: pointer;
user-select: none;
} */
`

View File

@ -0,0 +1,190 @@
import {html, LitElement, css, PropertyValueMap} from 'lit'
import {customElement, property, query} from 'lit/decorators.js'
// import {sharedStyles} from './pattern-view-style'
@customElement('star-pattern-view')
export class StarPatternView extends LitElement {
_topDir: string = ''
_getRed: boolean = false
static styles = css`
:host {
--top-dir: 217.5px;
}
canvas {
margin-top: var(--top-dir);
}
`
// public static override get styles(): CSSResultArray {
// return [sharedStyles]
// }
@query('canvas') canvas!: HTMLCanvasElement
@property({attribute: false}) cxt!: CanvasRenderingContext2D
@property({type: Boolean})
get getRed() {
return this._getRed
}
set getRed(value) {
if (this._getRed !== value) {
this._getRed = value
this.Draw()
}
}
@property({type: Number}) top = 0
@property({type: Number}) R = 35
@property({type: Number}) X = 0
@property({type: Number}) Y = 0
@property({type: Number}) canvasWidth = document.body.offsetWidth
@property({type: Number}) canvasHeight = document.body.offsetWidth
@property({type: Number}) OffsetX = document.body.offsetWidth / 3.5
@property({type: Number}) OffsetY = document.body.offsetWidth / 3.5
@property({type: Array}) circleArr: {X: number; Y: number}[] = []
@property({type: Array}) pwdArr: number[] = []
@property({type: Array}) passwdArr = [0, 1, 2, 5, 4, 3]
@property({type: String})
get topDir() {
return this._topDir
}
set topDir(value: string) {
this.style.setProperty('--top-dir', value)
this._topDir = value
this.top = parseInt(this._topDir)
}
render() {
return html`
<!-- <div style="height:200px;background-color:red"></div> -->
<canvas
id="canvas"
@touchstart=${this.touchStart}
@touchmove=${this.touchMove}
@touchend=${this.touchEnd}
></canvas>
`
}
protected firstUpdated(
_changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>
): void {
this.top = this.top ? this.top : 217.5
//canvas的高度和宽度都是
this.canvas.width = this.canvasWidth
this.canvas.height = this.canvasHeight
//getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。
this.cxt = this.canvas.getContext('2d')!
this.X = (this.canvasWidth - 2 * this.OffsetX - this.R * 2 * 3) / 2
this.Y = (this.canvasHeight - 2 * this.OffsetY - this.R * 2 * 3) / 2
this.createCirclePoint(this.X, this.Y)
this.Draw()
}
createCirclePoint(diffX: number, diffY: number) {
for (var row = 0; row < 3; row++) {
for (var col = 0; col < 3; col++) {
// 计算圆心坐标
var Point = {
X: this.OffsetX + col * diffX + (col * 2 + 1) * this.R,
Y: this.OffsetY + row * diffY + (row * 2 + 1) * this.R,
}
this.circleArr.push(Point)
}
}
}
Draw(touchPoint?: {X: any; Y: any}) {
if (this.pwdArr.length > 1) {
this.cxt.beginPath()
for (var i = 0; i < this.pwdArr.length; i++) {
var pointIndex = this.pwdArr[i]
this.cxt.lineTo(
this.circleArr[pointIndex].X,
this.circleArr[pointIndex].Y
)
}
//锁屏线
this.cxt.lineWidth = 2
this.cxt.strokeStyle = this.getRed ? '#FF4040' : '#333333'
this.cxt.stroke()
this.cxt.closePath()
if (touchPoint != null) {
var lastPointIndex = this.pwdArr[this.pwdArr.length - 1]
var lastPoint = this.circleArr[lastPointIndex]
this.cxt.beginPath()
this.cxt.moveTo(lastPoint.X, lastPoint.Y)
this.cxt.lineTo(touchPoint.X, touchPoint.Y)
this.cxt.stroke()
this.cxt.closePath()
}
}
for (var i = 0; i < this.circleArr.length; i++) {
var Point = this.circleArr[i]
//大圆
this.cxt.fillStyle = 'rgb(51,51,51,0.08)'
this.cxt.beginPath()
this.cxt.arc(Point.X, Point.Y, this.R, 0, Math.PI * 2, true)
this.cxt.closePath()
this.cxt.fill()
//小圆
this.cxt.fillStyle = 'rgb(51,51,51,0.2)'
this.cxt.beginPath()
this.cxt.arc(Point.X, Point.Y, this.R - 26, 0, Math.PI * 2, true)
this.cxt.closePath()
this.cxt.fill()
//滑动后小圆的颜色
if (this.pwdArr.indexOf(i) >= 0) {
this.cxt.fillStyle = this.getRed ? '#FF4040' : '#333333'
this.cxt.beginPath()
this.cxt.arc(Point.X, Point.Y, this.R - 26, 0, Math.PI * 2, true)
this.cxt.closePath()
this.cxt.fill()
}
}
}
getSelectPwd(touches: any, pwdArr: number[]) {
for (var i = 0; i < this.circleArr.length; i++) {
var currentPoint = this.circleArr[i]
var xdiff = Math.abs(currentPoint.X - touches.pageX)
/******** this.top = canvas向下移动的距离 **********/
var ydiff = Math.abs(currentPoint.Y - touches.pageY + this.top)
var dir = Math.pow(xdiff * xdiff + ydiff * ydiff, 0.5)
if (dir > this.R || pwdArr.indexOf(i) >= 0) continue
pwdArr.push(i)
break
}
}
touchStart(e: TouchEvent) {
this.getRed = false
this.getSelectPwd(e.touches[0], this.pwdArr)
}
touchMove(e: TouchEvent) {
e.preventDefault()
var touches = e.touches[0]
this.getSelectPwd(touches, this.pwdArr)
// 清除画布,0,0代表从什么位置开始,canvasWidth,canvasHeight代表清除的宽度和高度
this.cxt = this.canvas.getContext('2d')!
this.cxt.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
/*this.top = 手指拖动时,线条的起始位置。 */
this.Draw({
X: touches.pageX,
Y: touches.pageY - this.top,
})
}
touchEnd(e: TouchEvent) {
this.cxt.clearRect(0, 0, this.canvasWidth, this.canvasHeight)
this.Draw()
// if (this.pwdArr.toString() == this.passwdArr.toString()) {
// console.log('密码正确', this.passwdArr.toString())
// } else {
// console.log('密码错误', this.pwdArr.toString())
// this.Draw(null)
// }
this.getRed = true
this.pwdArr = []
this.dispatchEvent(
new TouchEvent('end', {
composed: true,
})
)
return this.passwdArr
}
}

View File

@ -19,7 +19,7 @@ import './components/slider/slider'
import './components/notification/notification'
import './components/prompt/prompt'
import './components/digicipher/digicipher'
// import './components/pattern-view/pattern-view'
import './components/pattern-view/pattern-view'
import './components/overlay/active-overlay'
@customElement('settings-app')

View File

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

View File

@ -23,7 +23,7 @@ import './overflowmenu/overflowmenu'
import './switch/switch'
import './slider/slider'
import './digicipher/digicipher'
// import './pattern-view/pattern-view'
import './pattern-view/pattern-view'
import './container/homescreen-container'
import './toast/toast'
import './picker/picker'