




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第微信小程序實現(xiàn)手寫板本文實例為大家分享了微信小程序實現(xiàn)手寫板的具體代碼,供大家參考,具體內容如下
!--wxml--
view
view
view
textwx:if="{{!tempFilePath}}"尚未簽名,請點擊“簽名”開始簽字/text
imagewx:if="{{tempFilePath}}"src="{{tempFilePath}}"/image
/view
viewbindtap="autograph"
van-iconname="edit"/簽名
/view
/view
/view
containershow="{{show}}"position="center"bind:clickoverlay="closeSheet"bind:afterleave="closeSheet"
view
view
imagecatchtap="selectColorEvent"src="{{selectColor==='black''/file_images/article/202507/20257875050855.png':'/file_images/article/202507/20257875216713.png'}}"class="{{selectColor==='black''color_select':''}}black-select"data-color="black"data-color-value="#1A1A1A"/image
imagecatchtap="selectColorEvent"src="{{selectColor==='red''/file_images/article/202507/20257875248330.png':'/file_images/article/202507/20257875312284.png'}}"class="{{selectColor==='red''color_select':''}}red-select"data-color="red"data-color-value="#ca262a"/image
buttoncatchtap="retDraw"重寫/button
buttoncatchtap="saveCanvasAsImg"完成/button
/view
view
canvasdisable-scroll="true"bindtouchstart="uploadScaleStart"bindtouchmove="uploadScaleMove"bindtouchend="uploadScaleEnd"bindtap="mouseDown"canvas-id="handWriting"
/canvas
/view
view
view手寫板/view
/view
/view
/container
js:
//index.js
varQQMapWX=require('../../utils/qqmap-wx-jssdk.js');
varqqmapsdk=newQQMapWX({
key:'H2RBZ-MGCC3-N4G3I-YCX6A-IKB5J-WIBTW'//必填
Page({
data:{
show:false,
canvasName:'handWriting',
ctx:'',
canvasWidth:0,
canvasHeight:0,
transparent:1,//透明度
selectColor:'black',
lineColor:'#1A1A1A',//顏色
lineSize:1.5,
//筆記倍數(shù)
lineMin:0.5,
//最小筆畫半徑
lineMax:4,
//最大筆畫半徑
pressure:1,
//默認壓力
smoothness:60,
//順滑度,用60的距離來計算速度
currentPoint:{},
currentLine:[],
//當前線條
firstTouch:true,//第一次觸發(fā)
radius:1,//畫圓的半徑
cutArea:{top:0,right:0,bottom:0,left:0},//裁剪區(qū)域
bethelPoint:[],
//保存所有線條生成的貝塞爾點;
lastPoint:0,
chirography:[],//筆跡
currentChirography:{},//當前筆跡
linePrack:[]//劃線軌跡,生成線條的實際點
onLoad(){
letcanvasName=this.data.canvasName
letctx=wx.createCanvasContext(canvasName)
this.setData({
ctx:ctx
})
varquery=wx.createSelectorQuery();
query.select('.handCenter').boundingClientRect(rect={
this.setData({
canvasWidth:rect.width,
canvasHeight:rect.height
})
}).exec();
//筆跡開始
uploadScaleStart(e){
if(e.type!='touchstart')returnfalse;
letctx=this.data.ctx;
ctx.setFillStyle(this.data.lineColor);
//初始線條設置顏色
ctx.setGlobalAlpha(this.data.transparent);
//設置半透明
letcurrentPoint={
x:e.touches[0].x,
y:e.touches[0].y
}
letcurrentLine=this.data.currentLine;
currentLine.unshift({
time:newDate().getTime(),
dis:0,
x:currentPoint.x,
y:currentPoint.y
})
this.setData({
currentPoint,
//currentLine
})
if(this.data.firstTouch){
this.setData({
cutArea:{top:currentPoint.y,right:currentPoint.x,bottom:currentPoint.y,left:currentPoint.x},
firstTouch:false
})
}
this.pointToLine(currentLine);
//筆跡移動
uploadScaleMove(e){
if(e.type!='touchmove')returnfalse;
if(e.cancelable){
//判斷默認行為是否已經(jīng)被禁用
if(!e.defaultPrevented){
e.preventDefault();
}
}
letpoint={
x:e.touches[0].x,
y:e.touches[0].y
}
//測試裁剪
if(point.ythis.data.cutArea.top){
this.data.cutArea.top=point.y;
}
if(point.y0)this.data.cutArea.top=0;
if(point.xthis.data.cutArea.right){
this.data.cutArea.right=point.x;
}
if(this.data.canvasWidth-point.x=0){
this.data.cutArea.right=this.data.canvasWidth;
}
if(point.ythis.data.cutArea.bottom){
this.data.cutArea.bottom=point.y;
}
if(this.data.canvasHeight-point.y=0){
this.data.cutArea.bottom=this.data.canvasHeight;
}
if(point.xthis.data.cutArea.left){
this.data.cutArea.left=point.x;
}
if(point.x0)this.data.cutArea.left=0;
this.setData({
lastPoint:this.data.currentPoint,
currentPoint:point
})
letcurrentLine=this.data.currentLine
currentLine.unshift({
time:newDate().getTime(),
dis:this.distance(this.data.currentPoint,this.data.lastPoint),
x:point.x,
y:point.y
})
//this.setData({
//
currentLine
//})
this.pointToLine(currentLine);
},//筆跡結束
uploadScaleEnd(e){
if(e.type!='touchend')return0;
letpoint={
x:e.changedTouches[0].x,
y:e.changedTouches[0].y
}
this.setData({
lastPoint:this.data.currentPoint,
currentPoint:point
})
letcurrentLine=this.data.currentLine
currentLine.unshift({
time:newDate().getTime(),
dis:this.distance(this.data.currentPoint,this.data.lastPoint),
x:point.x,
y:point.y
})
//this.setData({
//
currentLine
//})
if(currentLine.length2){
varinfo=(currentLine[0].time-currentLine[currentLine.length-1].time)/currentLine.length;
//$("#info").text(info.toFixed(2));
}
//一筆結束,保存筆跡的坐標點,清空,當前筆跡
//增加判斷是否在手寫區(qū)域;
this.pointToLine(currentLine);
varcurrentChirography={
lineSize:this.data.lineSize,
lineColor:this.data.lineColor
};
varchirography=this.data.chirography
chirography.unshift(currentChirography);
this.setData({
chirography
})
varlinePrack=this.data.linePrack
linePrack.unshift(this.data.currentLine);
this.setData({
linePrack,
currentLine:[]
})
},retDraw(){
this.data.ctx.clearRect(0,0,700,730)
this.data.ctx.draw()
//畫兩點之間的線條;參數(shù)為:line,會繪制最近的開始的兩個點;
pointToLine(line){
this.calcBethelLine(line);
return;
//計算插值的方式;
calcBethelLine(line){
if(line.length=1){
line[0].r=this.data.radius;
return;
}
letx0,x1,x2,y0,y1,y2,r0,r1,r2,len,lastRadius,dis=0,time=0,curveValue=0.5;
if(line.length=2){
x0=line[1].x
y0=line[1].y
x2=line[1].x+(line[0].x-line[1].x)*curveValue;
y2=line[1].y+(line[0].y-line[1].y)*curveValue;
//x2=line[1].x;
//y2=line[1].y;
x1=x0+(x2-x0)*curveValue;
y1=y0+(y2-y0)*curveValue;;
}else{
x0=line[2].x+(line[1].x-line[2].x)*curveValue;
y0=line[2].y+(line[1].y-line[2].y)*curveValue;
x1=line[1].x;
y1=line[1].y;
x2=x1+(line[0].x-x1)*curveValue;
y2=y1+(line[0].y-y1)*curveValue;
}
//從計算公式看,三個點分別是(x0,y0),(x1,y1),(x2,y2);(x1,y1)這個是控制點,控制點不會落在曲線上;實際上,這個點還會手寫獲取的實際點,卻落在曲線上
len=this.distance({x:x2,y:y2},{x:x0,y:y0});
lastRadius=this.data.radius;
for(letn=0;nline.length-1;n++){
dis+=line[n].dis;
time+=line[n].time-line[n+1].time;
if(disthis.data.smoothness)break;
}
this.setData({
radius:Math.min(time/len*this.data.pressure+this.data.lineMin,this.data.lineMax)*this.data.lineSize
});
line[0].r=this.data.radius;
//計算筆跡半徑;
if(line.length=2){
r0=(lastRadius+this.data.radius)/2;
r1=r0;
r2=r1;
//return;
}else{
r0=(line[2].r+line[1].r)/2;
r1=line[1].r;
r2=(line[1].r+line[0].r)/2;
}
letn=5;
letpoint=[];
for(leti=0;ii++){
lett=i/(n-1);
letx=(1-t)*(1-t)*x0+2*t*(1-t)*x1+t*t*x2;
lety=(1-t)*(1-t)*y0+2*t*(1-t)*y1+t*t*y2;
letr=lastRadius+(this.data.radius-lastRadius)/n*i;
point.push({x:x,y:y,r:r});
if(point.length==3){
leta=this.ctaCalc(point[0].x,point[0].y,point[0].r,point[1].x,point[1].y,point[1].r,point[2].x,point[2].y,point[2].r);
a[0].color=this.data.lineColor;
//letbethelPoint=this.data.bethelPoint;
//console.log(a)
//console.log(this.data.bethelPoint)
//bethelPoint=bethelPoint.push(a);
this.bethelDraw(a,1);
point=[{x:x,y:y,r:r}];
}
}
this.setData({
currentLine:line
})
//求兩點之間距離
distance(a,b){
letx=b.x-a.x;
lety=b.y-a.y;
returnMath.sqrt(x*x+y*y);
ctaCalc(x0,y0,r0,x1,y1,r1,x2,y2,r2){
leta=[],vx01,vy01,norm,n_x0,n_y0,vx21,vy21,n_x2,n_y2;
vx01=x1-x0;
vy01=y1-y0;
norm=Math.sqrt(vx01*vx01+vy01*vy01+0.0001)*2;
vx01=vx01/norm*r0;
vy01=vy01/norm*r0;
n_x0=vy01;
n_y0=-vx01;
vx21=x1-x2;
vy21=y1-y2;
norm=Math.sqrt(vx21*vx21+vy21*vy21+0.0001)*2;
vx21=vx21/norm*r2;
vy21=vy21/norm*r2;
n_x2=-vy21;
n_y2=vx21;
a.push({mx:x0+n_x0,my:y0+n_y0,color:"#1A1A1A"});
a.push({c1x:x1+n_x0,c1y:y1+n_y0,c2x:x1+n_x2,c2y:y1+n_y2,ex:x2+n_x2,ey:y2+n_y2});
a.push({c1x:x2+n_x2-vx21,c1y:y2+n_y2-vy21,c2x:x2-n_x2-vx21,c2y:y2-n_y2-vy21,ex:x2-n_x2,ey:y2-n_y2});
a.push({c1x:x1-n_x2,c1y:y1-n_y2,c2x:x1-n_x0,c2y:y1-n_y0,ex:x0-n_x0,ey:y0-n_y0});
a.push({c1x:x0-n_x0-vx01,c1y:y0-n_y0-vy01,c2x:x0+n_x0-vx01,c2y:y0+n_y0-vy01,ex:x0+n_x0,ey:y0+n_y0});
a[0].mx=a[0].mx.toFixed(1);
a[0].mx=parseFloat(a[0].mx);
a[0].my=a[0].my.toFixed(1);
a[0].my=parseFloat(a[0].my);
for(leti=1;ia.length;i++){
a[i].c1x=a[i].c1x.toFixed(1);
a[i].c1x=parseFloat(a[i].c1x);
a[i].c1y=a[i].c1y.toFixed(1);
a[i].c1y=parseFloat(a[i].c1y);
a[i].c2x=a[i].c2x.toFixed(1);
a[i].c2x=parseFloat(a[i].c2x);
a[i].c2y=a[i].c2y.toFixed(1);
a[i].c2y=parseFloat(a[i].c2y);
a[i].ex=a[i].ex.toFixed(1);
a[i].ex=parseFloat(a[i].ex);
a[i].ey=a[i].ey.toFixed(1);
a[i].ey=parseFloat(a[i].ey);
}
returna;
bethelDraw(point,is_fill,color){
letctx=this.data.ctx;
ctx.beginPath();
ctx.moveTo(point[0].mx,point[0].my);
if(undefined!=color){
ctx.setFillStyle(color);
ctx.setStrokeStyle(color);
}else{
ctx.setFillStyle(point[0].color);
ctx.setStrokeStyle(point[0].color);
}
for(leti=1;ipoint.length;i++){
ctx.bezierCurveTo(point[i].c1x,point[i].c1y,point[i].c2x,point[i].c2y,point[i].ex,point[i].ey);
}
ctx.stroke();
if(undefined!=is_fill){
ctx.fill();//填充圖形(后繪制的圖形會覆蓋前面的圖形,繪制時注意先后順序)
}
ctx.draw(true)
selectColorEvent(event){
console.log(event)
varcolor=event.currentTarget.dataset.colorValue;
varcolorSelected=event.currentTarget.dataset.color;
this.setData({
selectColor:colorSelected,
lineColor:color
})
//保存到相冊
saveCanvasAsImg(){
var_this=this;
wx.canvasToTempFilePath({
canvasId:'handWriting',
fileType:'png',
destWidth:600,
destHeight:300,
quality:1,//圖片質量
success(res){
console.log(res.tempFilePath,'canvas生成圖片地址');
_this.setData({show:false,tempFilePath:res.tempFilePath});
}
})
,autograph:function(e){
this.setData({show:true})
,closeSheet:function(e){
this.setData({show:false})
})
/*wxss*/
.wrapper{
width:100%;
height:95vh;
margin:30rpx0;
overflow:hidden;
display:flex;
align-content:center;
flex-direction:row;
justify-cont
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 電鏟初級工練習題(附參考答案)
- 2025員工拒絕簽訂勞動合同企業(yè)應對策略全解析
- 商業(yè)信息咨詢和輔導服務協(xié)議規(guī)定事項
- 智能硬件產(chǎn)品設計與制造合同協(xié)議
- 知識產(chǎn)權轉讓合同協(xié)議書要求專業(yè)版
- 設備采購合同協(xié)議條款
- 經(jīng)濟師專業(yè)試題及答案
- 2025湖南省低空經(jīng)濟發(fā)展集團有限公司招聘12人(第二次)筆試參考題庫附帶答案詳解
- 2025江西南昌市信陽鼎信產(chǎn)業(yè)投資集團有限公司及所屬二級公司招聘24人筆試參考題庫附帶答案詳解
- 2025廣西旅發(fā)大健康產(chǎn)業(yè)集團有限公司招聘278人筆試參考題庫附帶答案詳解
- 2025年中考數(shù)學總復習《四邊形的證明題》專項測試卷(附答案)
- 踝關節(jié)骨折中醫(yī)護理方案
- 關于比的知識圖文
- 家具鑒賞知到智慧樹章節(jié)測試課后答案2024年秋東北林業(yè)大學
- 統(tǒng)編版語文七年級下第18課《井岡翠竹》公開課一等獎創(chuàng)新教學設計
- 《高等教育心理學》講義
- 2025年汽車轉向橋總成行業(yè)深度研究分析報告
- 《招生話術技巧》課件
- 山西地質集團招聘筆試真題2024
- 《微格教學》課件
- 【MOOC】人工智能導論-福建師范大學 中國大學慕課MOOC答案
評論
0/150
提交評論