javascript - 是否可以使用 JavaScript 从 Canvas 上获取笔画?

标签 javascript canvas

我正在使用这个绘图应用程序:http://intridea.github.io/sketch.js/

我正在尝试通过以下方式获取笔划“内容”: var ctx = color_sketch.getContext("2d");

我正在寻找能让我捕获和重绘 Canvas 上下文的东西。像这样:

var ctx=c.getContext("2d");
ctx.beginPath();
ctx.moveTo(20,20);
// ... lots of lineTo's etc ...
ctx.lineTo(70,100);
ctx.strokeStyle="red";
ctx.stroke();

最佳答案

您可以创建一个自定义包装器,并调用其 api 将绘图操作存储在数组中,完成后,使用其 api 在 Canvas 上进行描边。

如果您还打算包装其他绘图操作,例如arcTo, bezierCurveTo, rect ...,则包装器将变得比代码片段更复杂。但想法仍然是一样的:将操作保存到特定格式的存储中,然后当您要在 Canvas 上绘制它们时,使用 ctx 操作来重播这些操作。

var StokeStore = function() {
  this.store = [];
  this.current = [];
}

StokeStore.prototype.moveTo = function(x, y) {
  if (this.current.length !== 0) {
    this.store.push(this.current);
    this.current = [];
  }
  this.current.push({x: x, y: y});
};

StokeStore.prototype.lineTo = function(x, y) {
  this.current.push({x: x, y: y});
};

StokeStore.prototype.stroke = function(ctx, style) {
  
  ctx.beginPath();
  ctx.strokeStyle = style ? style : 'black';
  this.store.forEach(function(line) {
    this._stroke(line);
  }, this);
  this._stroke(this.current);
  ctx.stroke();
};

StokeStore.prototype._stroke = function(line) {
    var length = line.length;
    if (length < 2) {
       return;
    }
    ctx.moveTo(line[0].x, line[0].y);
    var index, pt;
    for (index = 1; index < length; ++index) {
      pt = line[index];
      ctx.lineTo(pt.x, pt.y);
    }
};

var canvas = document.getElementById('test');
var ctx = canvas.getContext('2d');

var print = document.getElementById('print');
var clear = document.getElementById('clear');

var exampleStroke = new StokeStore();
exampleStroke.moveTo(50, 50);
exampleStroke.lineTo(70, 70);
exampleStroke.lineTo(200, 50);
exampleStroke.lineTo(200, 190);
exampleStroke.moveTo(30, 90);
exampleStroke.lineTo(0, 290);
exampleStroke.lineTo(290, 40);
exampleStroke.lineTo(150, 150);

var randomColor = ['red', 'cyan', 'black', 'purple'];

print.addEventListener('click', function() {
  var rnd = Math.floor(Math.random() * randomColor.length);
  var style = randomColor[rnd];
  exampleStroke.stroke(ctx, style);
});

clear.addEventListener('click', function() {
 canvas.width = canvas.width;
});
<canvas id="test" width="300" height="300"></canvas>
<button id="print">print</button>
<button id="clear">clear</button>

更新至markE评论:

我不擅长修改jQuery插件,但好像sketch.js确实提供了一个存储本身,当你调用它的api时,它设置 data-sketch属性来存储其创建的实例,因此您可以尝试与该实例进行交互,例如重绘或其他。

此外,它使用类似的格式来存储草图历史记录,如果我们使用 var sketch = $(CANVAS).data('sketch')要获取实例,我们可以使用 sketch.actions得到所有笔划,每个笔划都有一个arrayevents ,它存储具有属性 x, y, eventType 的对象,因此,如果您愿意,您可以从中检索笔画,也可以将自己的笔画放入历史记录中。喜欢:

sketch.actions.push({
    color: //stroke color,
    size: // stroke size,
    tool: // marker will draw, while eraser will erase to white,
    events: [
      {x:xval, y:yval, event:evType},....
    ]
});

jsfiddle或下面的片段。

$(function() {
    var $cv = $('#test');
    var cv = $cv.get(0);
    $('#test').sketch();
    var sketch = $cv.data('sketch');
  
    $('#clear').click(function() {
        cv.width = cv.width;
    });
  
    $('#redraw').click(function() {
        sketch.redraw();
    });
    
    $('#strokes').click(function() {
        var $display = $('#display').empty();
		sketch.actions.forEach(function(strk, idx) {
            if (!strk.events) {
            	return;
            }
        	var $div = $('<div>').addClass('stroke');
            $('<div>').text('Stroke #' + idx).appendTo($div);
            strk.events.forEach(function(pt, idx) {
                $("<p>").text(idx + ': (' + pt.x + ',' + pt.y + ')'  ).appendTo($div);
            });
            $div.appendTo($display);
        });
    });
  });
#test {
  border: solid 1px gray;
}

.stroke {
    border: solid 1px blue;
     float : left;
    padding: 10px;
    margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/intridea/sketch.js/master/lib/sketch.min.js"></script>

<canvas id="test" width="500" height="500;"></canvas>
  
<button id="clear">clear</button>
<button id="redraw">redraw</button>
<button id="strokes">print strokes</button>
<div id="display"></div>

关于javascript - 是否可以使用 JavaScript 从 Canvas 上获取笔画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33121078/

相关文章:

javascript - 我们如何从 URL 读取文件并将其逐行插入到 MongoDB 中?

javascript - Mathjax 打破\mathcal 和下标

javascript - 如何在 Node.js 的 Express.js 中获取多个变量?

javascript - 在从 url 加载到图像对象时按特定顺序将图像绘制到 Canvas

JavaScript 拖动绘制的 Canvas 元素

javascript - 将谷歌地图插件设为黑色/白色或使用棕褐色滤镜

javascript - 网页宽度与屏幕宽度不匹配

javascript - 在 Canvas (HTML5) 上绘制好看的(如在 Flash 中)线条 - 可能吗?

javascript - HTML5 Canvas 跟随鼠标效果jquery

javascript - 是否可以使用 emscripten 从 C++ 和 Javascript 打印字符串?