微信小程序實現(xiàn)手寫板_第1頁
微信小程序實現(xiàn)手寫板_第2頁
微信小程序實現(xiàn)手寫板_第3頁
微信小程序實現(xiàn)手寫板_第4頁
微信小程序實現(xiàn)手寫板_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第微信小程序實現(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. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論