如何约束<画布>
How can I constrain drawing on the <canvas>?
我想创建一个移动网页,其中一个形状出现在屏幕上,用户只能用手指在形状的轮廓上进行跟踪,然后会出现一个新的形状。这个库有几个很好的例子来说明我想要做什么,只是有更多的形状。我已经在这里和这里找到了几个在画布上用触摸设备画画的好例子。我不知道的是如何约束这条线,所以你只能在带有一条连续线的路径上绘制。是否有内置的东西可以让我指定您可以绘制的唯一路径,或者我必须手动编写该逻辑?
我们可以将问题分为两部分:
1) 知道用户是否在路径上
2) 知道用户是否访问了所有路径部分。
对于1),我们可以使用isPointInPath context2D方法来知道鼠标/触摸点(x,y)是否在曲线上。这里的约束是必须构建一个闭合曲面,这意味着由fill()绘制的曲面,而不是用stroke()构建的曲面。所以,如果你在画粗线,你必须做一些小数学运算,用moveTo+lineTo+fill来构建相应的数字。
对于2):为你的形状建立一个"检查点"列表。例如,一个圆可能有8个控制点。然后决定用户将"激活"检查点的距离。现在的算法是,在伪代码中:
mouseDown => check()
mouseMove => if mouse is down, check()
checkPointList = [ [ 10, 40, false ] , [ centerX, centerY, isChecked], ... ] ;
checked = 0;
function check() {
clear screen
draw the path
if (mouse down and mouse point on path) {
for ( checkPoint in CheckPointList) {
if (checkPoint near enough of mouse) {
checkPoint[3]=true;
checked++;
}
}
if (checked == checkPointList.length) ==>>> User DID draw all the shape.
} else
clear the flags of the checkPointList;
checked=0;
}
我在这里做了一个moooost简单的演示,它放弃了工作。控制点在禁用时显示为红色,在激活时显示为绿色:
http://jsbin.com/wekaxiguwiyo/1/edit?js,输出
// boilerplate
var cv = document.getElementById('cv');
var ctx = cv.getContext('2d');
function draw() {
ctx.clearRect(0,0,300,300);
drawShape();
drawCP();
}
// Shape
function drawShape() {
ctx.beginPath();
ctx.moveTo(30,5);
ctx.lineTo(80,5);
ctx.lineTo(80, 300);
ctx.lineTo(30,300);
ctx.closePath();
ctx.lineWidth= 16;
ctx.fillStyle='#000';
ctx.fill();
}
// Control points
var points = [ [50, 50, false], [50,120, false], [50, 190, false],[50,260, false ] ];
var pointsCount = 0;
function drawCP() {
for (var i=0; i<points.length; i++) {
var p = points[i];
ctx.fillStyle=p[2]?'#0F0':'#F00';
ctx.fillRect(p[0]-1, p[1]-1, 2, 2);
}
}
function resetCP() {
for (var i=0; i<points.length; i++) {
points[i][2]=false;
}
pointsCount=0;
}
function testCP(x,y) {
var d=30;
d=sq(d);
for (var i=0; i<points.length; i++) {
if (sq(points[i][0]-x)+sq(points[i][1]-y)<d) {
if (!points[i][2]) pointsCount++;
points[i][2]=true
};
}
}
function sq(x) { return x*x; }
//
draw();
// most simple event handling
addEventListener('mousemove', mouseMove);
var r = cv.getBoundingClientRect();
function mouseMove(e) {
var x = e.pageX-r.left;
var y = e.pageY-r.top;
draw();
ctx.fillStyle='#000';
if (ctx.isPointInPath(x,y)) {
ctx.fillStyle='#F00';
testCP(x,y);
} else {
resetCP();
}
ctx.fillRect(x-3,y-3,6,6);
var pathDrawn = (pointsCount == points.length);
if (pathDrawn) ctx.fillText('Shape drawn!!', 150, 150);
}
相关文章:
- 在<页眉>标签
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 如何更改<svg>标记为<img>用js标记
- Ckeditor-plugin:插入虚假元素add不情愿<p>标签前后
- 画布数据到图像
- 做<img>或者<画布>保存对原始(大)dataUrl对象的引用
- 如何在使用<画布>标签
- JavaScript-动画形状在HTML5<画布>
- 我的<画布>加载特定PDE文件时调整大小
- 如何发送HTML<画布>数据到服务器
- 有没有一种方法可以覆盖<画布>通过全屏HTML5<视频>
- 从html5<创建视频流;画布>
- <画布>:从内存中删除2d上下文,而不从内存中移除webgl上下文
- 如何绘制现有<img>到画布
- 如何约束<画布>
- 如何调整html<画布>动态使用Javascript
- 使用<画布>对于大型'地图'
- 我应该如何使用`<画布>`
- 使用<画布>和javascript
- JavaScript<画布>绘制缩放图像