当前位置:网站首页 > C++编程 > 正文

canvas画笔功能的实现

一,基础的实现

我自己封装了个canvas的库,这部分可以不看,主要看实现画笔的思路吧.

 <canvas canvas-id="poster-canvas" class="poster-canvas" style="border: 1px solid #ccc;" :style="{ width: canvasW + 'px', height: canvasH + 'px' }" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" ></canvas> 

先拿到canas对象:

this.canvas = new biuCanvas.Canvas('poster-canvas',this) 

因为有画笔工具,有折线工具,所以我需要两个状态:

drawType:'line',//画笔绘图类型 positions:[]//点坐标集合 

画笔开始绘制的代码如下:

touchstart(e){ 
    let point={ 
   } switch (this.drawType){ 
    case 'polyline': //折线 case 'line': point.x=e.changedTouches[0].x point.y=e.changedTouches[0].y this.positions.push(point) break; default: break; } }, touchmove(e){ 
    let point={ 
   } switch (this.drawType){ 
    case 'line': point.x=e.changedTouches[0].x point.y=e.changedTouches[0].y this.positions.push(point) if(this.positions.length>1){ 
    // 画笔绘制 let paintBrush = new biuCanvas.PaintBrush(JSON.parse(JSON.stringify(this.positions))) // 将折线添加到画布中 this.canvas.add(paintBrush) } break; default: break; } }, touchend(e){ 
    switch (this.drawType){ 
    case 'polyline': //折线 break; case 'line': this.positions=[] break; default: break; } } 

封装的画笔绘制:

biuCanvas.PaintBrush=class { 
    constructor(arr) { 
    this.arr=arr } render(canvas) { 
    let ctx=canvas.context ctx.beginPath() for(let i=0;i<this.arr.length;i++){ 
    if(i==0){ 
    ctx.moveTo(this.arr[i].x, this.arr[i].y) }else{ 
    ctx.lineTo(this.arr[i].x, this.arr[i].y) } } ctx.stroke() } } 

对canvas的封装,这里是我自己写的,主要实现就是在this.canvas.add(paintBrush)的时候,能够执行paintBrush的render,从而绘制图案罢了.

biuCanvas.Canvas = class { 
    constructor(canvasId,_this,options={ 
   }) { 
    this.canvasId = canvasId; this.context = uni.createCanvasContext(canvasId, _this); this.width = options.width || 300; this.height = options.height || 400; this.objects = []; } add(object) { 
    //在每次add的时候,应该修改currenStatus,然后object['pathStatus']保存这个status this.drawStatus.setCurrentStatus(object.options) //在初始化的时候,会给该Canvas实例对象新增属性drawStatus来记录当前绘图状态管理器,现在每次新增图案需要存储当前绘图状态 object['pathStatus']=JSON.parse(JSON.stringify(this.drawStatus.currentStatus)) //对于一次绘制:如折线,每多次点击,都是一次绘制,不能用push,而是应该用覆盖 if((object instanceof biuCanvas.Polyline||object instanceof biuCanvas.PaintBrush) && object.arr && object.arr.length>2){ 
    this.objects.pop(); } this.objects.push(object); this.render(); } render() { 
    for (let i = 0; i < this.objects.length; i++) { 
    this.drawStatus.setStatus(this.objects[i]['pathStatus'],this.context) this.objects[i].render(this); } this.context.draw() } } 

二,用更少的点画线

distance(e,points){ 
    const { 
   x:pointX,y:pointY}=e.changedTouches[0] const { 
   x:lastX,y:lastY}=points[points.length-1] const dis=(lastY-pointY)*(lastY-pointY)+(lastX-pointX)*(lastX-pointX) if(dis>300){ 
    return true }else{ 
    return false } } 

更改tochmove方法:

touchmove(e){ 
    let point={ 
   } switch (this.drawType){ 
    case 'line': if(this.distance(e,this.positions)){ 
    point.x=e.changedTouches[0].x point.y=e.changedTouches[0].y this.positions.push(point) if(this.positions.length>1){ 
    // 画笔绘制 let paintBrush = new biuCanvas.PaintBrush(JSON.parse(JSON.stringify(this.positions))) // 将折线添加到画布中 this.canvas.add(paintBrush) } } break; default: break; } }, 

这样就能用更少的点绘制了.

三,优化成曲线过渡

现在的线段,其实是一段段小的折线,并不美观,我需要的是曲线的连接,这里我采用的是二次贝塞尔曲线连接.

对于abcd四个点 bc之间先计算出中点b1 然后b作为控制点,b1作为终点 以此类推 

在这里插入图片描述
实现的代码主要是:

let ctx=canvas.context ctx.beginPath() for(let i=0;i<this.arr.length;i++){ 
    const { 
    x: endX, y: endY } = this.arr[i] if(i==0){ 
    ctx.moveTo(endX, endY) }else{ 
    const { 
    x: centerX, y: centerY } = this.arr[i - 1]//作为贝塞尔曲线的控制点 const lastX = (endX + centerX) / 2 const lastY = (endY + centerY) / 2//最后两点的中点作为贝塞尔曲线的终点 ctx.quadraticCurveTo(centerX, centerY, lastX, lastY) } } ctx.stroke() 
到此这篇canvas画笔功能的实现的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • mac电脑下安装和启动nginx2024-12-01 10:27:04
  • Mac IDEA快捷键精华版2024-12-01 10:27:04
  • Mac 下配置 Vim vundle 代码补全 YouCompleteMe 等2024-12-01 10:27:04
  • centos7安装gitlab-ce社区版全过程,详细到爆炸2024-12-01 10:27:04
  • centos安装通过yum安装jenkins2024-12-01 10:27:04
  • 《第一行代码》 第二章:探究活动Activity2024-12-01 10:27:04
  • uni-clould常用笔记2024-12-01 10:27:04
  • mac book安装nvm2024-12-01 10:27:04
  • webpack5配置代码分包2024-12-01 10:27:04
  • webpack5代码分离2024-12-01 10:27:04
  • 全屏图片