纯新手用 vue 1.0 写了个简单的笔记本工具,有个小问题请教大神们

开始用的2.0的脚手架,发现坑好多,忍不了换回1了。
断断续续大概写了半个月吧,大致的功能如下:

  • 基本的增删、编辑笔记

  • 按类别、标题、内容、时间戳进行过滤

  • 按创建时间或标题排序

  • 暂存未确认保存的笔记

  • 支持 markdown 和涂鸦两种记录方式

  • 用 localStorage 存取数据,不手动 clear 的话算是个本地的简易数据库吧

  • 移动端适配(虽然体验不如桌面……不过我也不是设计师,已经尽力了)

然后我的问题来了…桌面端编辑涂鸦完全没问题,但手机上就是不行,canvas 的 context 的 stroke 方法似乎失效了。我已经在控制台里打印了 mouse 和 touch 事件的坐标,麻烦大神们看看是什么原因吧…实在搞不懂了T_T

DEMO 在这里,源码在这里,感谢诸位

涂鸦的方法如下

// 初始化涂鸦编辑器
const initCanvas = canvasEle, colorsEle, controllersEle, imageData => { // 颜色值对象 const colorTable = [ { name: black, regularCode: #222, opagueCode: rgb189, 189, 189, }, { name: green, regularCode: #5cb85c, opagueCode: rgb206, 234, 206, }, { name: yellow, regularCode: #f0ad4e, opagueCode: rgb251, 231, 202, }, { name: red, regularCode: #d9534f, opagueCode: rgb244, 203, 202, }, { name: white, regularCode: #fff, opagueCode: #fff, }, ]; // 初始化 context let ctx = canvasEle.getContext2d; let selectedColor = null; let hasOnGoingStroke = false; let prevStatusStack = []; let futureStatusStack = []; let $canvas = $canvasEle; // 方法:将 imageData 写入一个 Image 对象,画在 canvas 上 const loadImageData = data => { let img = new Image; img.src = data; img.onload = => { clearCanvas; ctx.drawImageimg, 0, 0; }; } // 方法:存储当前的 canvas 内容为 imageData,推入状态栈 const saveImageData = => { let currentStatus = canvasEle.toDataURL; prevStatusStack.unshiftcurrentStatus; }; // 方法:清除画布 const clearCanvas = => { ctx.clearRect0, 0, 260, 260; }; // 若提供了 imageData 参数就画出来 if imageData !== null { loadImageDataimageData; } // 然后无论此时是否已有内容,推入状态栈一次 saveImageData; // 颜色选择器鼠标事件 $colorsEle.childrenli .onclick, function { let $this = $this; const tarColorName = $this.datacolor; selectedColor = colorTable.finditem => { return item.name === tarColorName; }; $this .siblings.current .removeClasscurrent .end .addClasscurrent; } .siblings[data-color=black] .click; // canvas 鼠标事件 $canvas.onmousedown touchstart, evt => { let stX, stY; switch evt.type { case touchstart: stX = evt.targetTouches[0].clientX; stY = evt.targetTouches[0].clientY; break; default: stX = evt.offsetX; stY = evt.offsetY; break; } console.logst, stX, stY; hasOnGoingStroke = true; ctx.strokeStyle = selectedColor.opagueCode; ctx.lineWidth = 5; ctx.lineCap = round; ctx.lineJoin = round; ctx.imageSmoothingEnabled = true; ctx.beginPath; ctx.moveTostX, stY; } .onmousemove touchmove, evt => { if hasOnGoingStroke === true { let mdX, mdY; switch evt.type { case touchmove: mdX = evt.changedTouches[0].clientX; mdY = evt.changedTouches[0].clientY; break; default: mdX = evt.offsetX; mdY = evt.offsetY; break; } console.logmd, mdX, mdY; ctx.lineTomdX, mdY; ctx.stroke; } } .onmouseout mouseup touchend, evt => { if hasOnGoingStroke === true { let edX, edY; switch evt.type { case touchend: edX = evt.changedTouches[0].clientX; edY = evt.changedTouches[0].clientY; break; default: edX = evt.offsetX; edY = evt.offsetY; break; } ctx.strokeStyle = selectedColor.regularCode; ctx.lineToedX, edY; ctx.stroke; console.loged, edX, edY; hasOnGoingStroke = false; saveImageData; } }; // 控制器鼠标事件 $controllersEle .children.undo .onclick, evt => { if prevStatusStack.length !== 0 { loadImageDataprevStatusStack[0]; let currentStep = prevStatusStack.splice0, 1; futureStatusStack.unshiftcurrentStep; } } .end .children.redo .onclick, evt => { if futureStatusStack.length !== 0 { loadImageDatafutureStatusStack[0]; let currentStep = futureStatusStack.splice0, 1; prevStatusStack.unshiftcurrentStep; } } .end .children.clear .onclick, => { clearCanvas; };
};

已经自己解决,原因是

Touch对象的 clientX 和 clientY 是相对于视口的,要取得点击画布的实际位置,要将这两个值减去画布相对于视口的坐标:

 x = evt.touches[0].clientX - $canvas.offset.left; y = evt.touches[0].clientY - $canvas.offset.top; ctx.moveTox, y;

发表评论

电子邮件地址不会被公开。 必填项已用*标注