我正在为画布绘图创建phonegap / cordova android应用程序。
我用https://github.com/ludei/webview-plus/ webview +替换了CordovaWebView(android股票浏览器webview),以提高Android平台上的绘图性能。更换webview后,在android上绘制速度非常快。
现在我使用下面的demo作为基础
创建撤消功能http://www.createjs.com/Demos/EaselJS/CurveTo
撤消功能正在按预期工作,但撤消性能会随着画布上的更多绘图数据而逐渐降低。这种渐进的性能下降是绝对肯定的,因为我遵循撤消的方法。 在桌面浏览器上性能很好,但在Android手机和平板电脑上撤消需要很长时间。
我的撤消方法:
将每个绘制点存储(推)到点[]数组以及笔划宽度和颜色。这个points []数组存储了一条连续线的所有信息。
然后我在mouseup事件中将所有连续行信息存储(推送)到allPoints数组中。
然后单击撤消时,我从allPoints []数组中弹出(删除)最后一个连续行,然后通过重绘allPoints []数组中的所有点来更新阶段。
随着画布绘制笔划的增加,allPoints []数组大小增加,并且需要更多时间来重绘allPoints。
我已经为我的撤销方法的演示设置了一个小提琴。
http://jsfiddle.net/JTqvJ/188/
var canvas, stage;
var drawingCanvas;
var oldPt;
var oldMidPt;
var title;
var color;
var stroke;
var colors;
var index;
var allPoints = [];
var points = [];
function init() {
canvas = document.getElementById("canvas");
var undoEl = document.getElementById('undo');
undoEl.addEventListener("click",undoDrawing);
index = 0;
colors = ["#828b20"];
//check to see if we are running in a browser with touch support
stage = new createjs.Stage(canvas);
stage.autoClear = false;
stage.enableDOMEvents(true);
createjs.Touch.enable(stage);
createjs.Ticker.setFPS(24);
drawingCanvas = new createjs.Shape();
stage.addEventListener("stagemousedown", handleMouseDown);
stage.addEventListener("stagemouseup", handleMouseUp);
stage.addChild(drawingCanvas);
stage.update();
}
function stop() {
}
function handleMouseDown(event) {
color = colors[(index++) % colors.length];
stroke = 2;
oldPt = new createjs.Point(stage.mouseX, stage.mouseY);
oldMidPt = oldPt.clone();
stage.addEventListener("stagemousemove", handleMouseMove);
}
function handleMouseMove(event) {
var midPt = new createjs.Point(oldPt.x + stage.mouseX >> 1, oldPt.y + stage.mouseY >> 1);
// current point to draw
var point = {
midPt_x: midPt.x,
midPt_y: midPt.y,
oldPt_x: oldPt.x,
oldPt_y: oldPt.y,
oldMidPt_x:oldMidPt.x,
oldMidPt_y: oldMidPt.y,
s_stroke: stroke,
s_color: color,
}
//store this point in points array
points.push(point);
//draw this point
drawLine(point);
oldPt.x = stage.mouseX;
oldPt.y = stage.mouseY;
oldMidPt.x = midPt.x;
oldMidPt.y = midPt.y;
stage.update();
}
function handleMouseUp(event) {
stage.removeEventListener("stagemousemove", handleMouseMove);
allPoints.push(points);
//empty points array for saving new point objects
points = [];
console.log(allPoints);
}
function drawLine(point){
console.log("drawing");
drawingCanvas.graphics.clear().setStrokeStyle(point.s_stroke, 'round', 'round').beginStroke(point.s_color).moveTo(point.midPt_x, point.midPt_y).curveTo(point.oldPt_x, point.oldPt_y, point.oldMidPt_x, point.oldMidPt_y);
};
function reDrawAllLines(){
//clear whole canvas to refresh
stage.clear();
for (var index1 in allPoints) {
for(var index2 in allPoints[index1]){
drawLine(allPoints[index1][index2]);
stage.update();
//alert(allPoints[index1][index2]);
}
}
};
function undoDrawing(){
console.log('undo');
if(allPoints.length > 0){
console.log('pop last one');
//pop/remove last continuous line from allPoints
allPoints.pop();
allPoints.pop();
console.log(allPoints);
//redraw allPoints array to refresh canvas
reDrawAllLines();
}
}
init();
我认为重绘allPoints比将画布绘制快照保存为撤消图像更好,因为它会占用大量内存,但现在重绘allPoints很慢,我的运气不好:(
我在撤消功能方面做错了什么因为画布花了很长时间从allPoints []数组重绘绘图。在10行或更多行后,Android移动设备上的撤销速度很慢。
有人可以用更好的方法帮助我使用厚帆布绘图进行撤消吗?
注意:我的画布是A4页面尺寸,即高度为1123像素,宽度为794像素。
答案 0 :(得分:1)
我还没有在移动设备上测试过大量的形状,但你可以将绘图画布变成一个Container,每行都有自己的Shape,然后在撤消的情况下,你不必重绘任何内容,只需从画布中删除最后一个形状。
答案 1 :(得分:0)
我设法通过画架快速绘制和快速撤消。
现在我已经为每个新行使用了基于对象(形状)的方法,而不是保存每个点。
快速撤消:刚从舞台上移除最后一个形状并调用stage.update()来重绘所有形状。
对于快速绘图:刚刚在我的tick()侦听器或handleMouseMove()中使用currentShape.draw(ctx)替换了stage.update()调用,它就像一个魅力。 currentShape.draw()只绘制调用它的形状,而stage.update()在每个tick()上重绘其所有子形状,使得绘图变慢。
快速撤消和快速绘制的工作小提琴http://jsfiddle.net/MkRCg/134/
var stage;
var isMouseDown;
var currentShape;
var oldMidX, oldMidY, oldX, oldY;
var canvas;
var ctx;
function init() {
stage = new createjs.Stage('canvas');
stage.autoClear = true;
stage.addEventListener("stagemousedown", handleMouseDown);
stage.addEventListener("stagemouseup", handleMouseUp);
createjs.Touch.enable(stage);
stage.update();
createjs.Ticker.addEventListener("tick", tick);
//bind element with id 'undo-drawing' with undoDrawing function
var undoEl = document.getElementById('undo-drawing');
undoEl.addEventListener("click",undoDrawing);
ctx = stage.canvas.getContext('2d');
}
function stop() {
createjs.Ticker.removeEventListener("tick", tick);
}
function tick() {
if (isMouseDown) {
var pt = new createjs.Point(stage.mouseX, stage.mouseY);
var midPoint = new createjs.Point(oldX + pt.x>>1, oldY+pt.y>>1);
currentShape.graphics.moveTo(midPoint.x, midPoint.y);
currentShape.graphics.curveTo(oldX, oldY, oldMidX, oldMidY);
oldX = pt.x;
oldY = pt.y;
oldMidX = midPoint.x;
oldMidY = midPoint.y;
/* Costly redrawing all previous objects too */
//stage.update();
/* only draws currentShape, made drawing fast*/
currentShape.draw(ctx);
}
}
function handleMouseDown() {
isMouseDown = true;
var s = new createjs.Shape();
oldX = stage.mouseX;
oldY = stage.mouseY;
oldMidX = stage.mouseX;
oldMidY = stage.mouseY;
var g = s.graphics;
var stroke = 2;
g.setStrokeStyle(stroke, 'round', 'round');
var color = "#000000";
g.beginStroke(color);
stage.addChild(s);
currentShape = s;
}
function handleMouseUp() {
isMouseDown = false;
//make drawing smooth on each mouse up
stage.update();
// alert();
}
function undoDrawing() {
console.log('undo clicked');
stage.removeChildAt(stage.children.length - 1);
stage.update();
}
init();