chore(小程序): 初始化工程仓库
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { computed,getCurrentInstance,nextTick,onMounted,watch } from 'vue'
|
||||
import { cellAtPoint } from '../core/canvas'
|
||||
import type { Pattern } from '../core/types'
|
||||
let props=withDefaults(defineProps<{pattern:Pattern;size?:number;highlight?:string;grid?:boolean;completed?:number[]}>(),{size:160,highlight:'',grid:false,completed:()=>[]})
|
||||
let emit=defineEmits<{cell:[index:number]}>()
|
||||
let instance=getCurrentInstance(); let id='p'+instance?.uid
|
||||
let height=computed(()=>Math.round(props.size*props.pattern.height/props.pattern.width))
|
||||
async function draw(){await nextTick(); let p=props.pattern;let ctx=uni.createCanvasContext(id,instance);let s=props.size/p.width
|
||||
ctx.clearRect(0,0,props.size,height.value);ctx.setFillStyle('#f0efe5');ctx.fillRect(0,0,props.size,height.value)
|
||||
let palette=new Map(p.colors.map(c=>[c.code,c.hex]));let done=new Set(props.completed)
|
||||
p.cells.forEach((c,i)=>{if(!c)return;ctx.setGlobalAlpha(props.highlight&&c!==props.highlight? .15:1);ctx.setFillStyle(palette.get(c)||'#777');let x=i%p.width*s,y=Math.floor(i/p.width)*s;ctx.fillRect(x,y,s,s);ctx.setGlobalAlpha(1)
|
||||
if(props.grid&&s>=24){ctx.setFillStyle('#fff');ctx.fillRect(x+1,y+1,s-2,11);ctx.setFillStyle('#253d32');ctx.setFontSize(8);ctx.fillText(c,x+2,y+9)}
|
||||
if(done.has(i)){ctx.setFillStyle('rgba(255,255,255,0.67)');ctx.fillRect(x,y,s,s);ctx.setFillStyle('#265b49');ctx.setFontSize(Math.max(9,s*.6));ctx.fillText('✓',x+s*.15,y+s*.8)}
|
||||
});
|
||||
if(props.grid){
|
||||
ctx.setStrokeStyle('rgba(100,119,98,0.24)');ctx.setLineWidth(.5);ctx.beginPath()
|
||||
for(let column=0;column<=p.width;column++){ctx.moveTo(column*s,0);ctx.lineTo(column*s,height.value)}
|
||||
for(let row=0;row<=p.height;row++){ctx.moveTo(0,row*s);ctx.lineTo(props.size,row*s)}
|
||||
ctx.stroke()
|
||||
}
|
||||
ctx.draw()
|
||||
}
|
||||
function tap(e:any){
|
||||
let touch=e.changedTouches?.[0]||e.touches?.[0]
|
||||
let x=touch?.clientX??e.detail?.x,y=touch?.clientY??e.detail?.y
|
||||
// 事件坐标属于视口,必须扣除画布在滚动容器中的实际偏移。
|
||||
uni.createSelectorQuery().in(instance?.proxy).select('#'+id).boundingClientRect((value:any)=>{
|
||||
if(!value)return
|
||||
let cell=cellAtPoint(x,y,value,props.pattern.width,props.pattern.height)
|
||||
if(cell!==null)emit('cell',cell)
|
||||
}).exec()
|
||||
}
|
||||
onMounted(draw);watch(()=>[props.pattern,props.size,props.highlight,props.completed],draw,{deep:true})
|
||||
</script>
|
||||
<template><canvas :id="id" :canvas-id="id" :style="{width:size+'px',height:height+'px'}" :aria-label="pattern.title+','+pattern.width+'乘'+pattern.height+'格'" @tap="tap" /></template>
|
||||
Reference in New Issue
Block a user