chore(小程序): 初始化工程仓库

This commit is contained in:
leon_mac
2026-10-18 15:11:44 +08:00
commit e1975a1abf
49 changed files with 10515 additions and 0 deletions
+36
View File
@@ -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>