JavaScript HTML 图形(带顶点)
JavaScript HTML graphics (with vertices)
除了矩形和圆形之外,还有什么方法可以使用 JavaScript 在 HTML 中创建基本的二维形状吗?
例如,假设我们有一个 <canvas></canvas>
(因为任何其他元素无法按照我尝试的方式修改,或者?)元素,其中 width:100px
、height:300px
和 background:black
。
我怎样才能将它的右上角(右上角顶点)移动到不同的位置来创建一个不同的形状而不是一个矩形?
发件人:
point one: x: 0px / y: 0px
point two: x: 100px / y: 0px
point three: x: 100px / y: 300px
point four: x: 0px / y: 300px
收件人:
point one: x: 0px / y: 0px
point two: x: 120px / y: -20px
point three: x: 100px / y: 300px
point four: x: 0 / y:300px
(point two
是改的那个)
HTML 是否有任何 JavaScript 图形库可以使这项任务变得简单?沿着 drawable.vertices[1].move(20, -20)
的路线将第二个顶点在 x 上移动 20px,在 y 上移动 -20px。
你看过pixi.js了吗? (http://www.pixijs.com/) it is a 2d library which utilizes WebGL but falls back to canvas if WebGL is not supported by the browser. If you want to go to 3d libraries also look into Three.js (http://threejs.org/)
另一个专门针对 canvas 的相当流行的图形库是 Raphael 库 (http://raphaeljs.com/)
更新:
在偏移量为 100px 且尺寸为 300x300px 的元素中用 Raphael 初始化一个 canvas。请注意,我在这里依赖 JQuery 来获取 "mycanvas" 元素。
var paper = Raphael($("#mycanvas"), 100, 300,300);
要绘制任意多边形,您需要使用 Raphael "paper" 对象上的路径函数,传入 svg 路径字符串(如果您有兴趣阅读更多关于 SVG 路径标准的信息,您可以找到这里有一些信息:http://www.w3.org/TR/SVG/paths.html#PathData)
paper.path("M150,0L200,100L100,100Z").attr("fill","#F00");
路径末端的属性用红色填充多边形。
在两行中,我使用 SVG 路径生成了一个红色三角形。我认为您不会得到比这更轻的重量。
现在根据您最后的评论,您希望它是交互式的。这不会像您想的那么简单。
您要实现的目标的粗略方法将要求您:
1) 保留要转换为 SVG 字符串的顶点数组。
2) 您将不得不跟踪 canvas 上的鼠标按下事件。每次发现鼠标按下事件时,您都必须检查它是否在顶点列表中的顶点上,明智的做法是为错误添加一个 epsilon,这样用户就不必准确地单击一个像素,而是在靠近顶点的区域中。您可以使用装箱方法为您提供围绕顶点的某种方框 epsilon。创建对您按下鼠标的顶点的引用。
3) 在鼠标移动事件上,同时鼠标按钮也按下,并且有一个活动顶点你想根据鼠标坐标修改该顶点的位置。
4) 在鼠标弹起事件中,根据多边形中的顶点数量,您可以使用 paper.clear() 清除纸张并通过生成新的 SVG 路径重绘路径顶点列表中的字符串并使用 paper.path(...) 添加新的 SVG 字符串。
这是我创建的用于为您绘制三角形多边形的 plnkr 的 link:http://plnkr.co/edit/AK5zO1ZqBTerMf9AzS88?p=preview
最终奖金更新:
所以我决定在 plnkr 中为您做这件事,这样您就可以了解如何操纵路径并强制重绘。本质上 javascript 绘制两条路径,一条用于三角形,一条用于每个三角形顶点末端的蓝点。我在控件路径元素的拖动中注册了两个委托函数,以便它们中的每一个都可以更新它们的 X 和 Y 值以及相应的三角形顶点。看看 plnkr,如果有什么不合理的地方请告诉我。
http://plnkr.co/edit/o5QHap7NV1SYIbsS76f5
尽情享受吧! :)
我在 gamecanvas 中做了一些多边形的东西。我制作了一些函数来生成相对于相机/玩家位置定位的任意多边形,这可能是相关的或有帮助的(来自我的 open sauce javascript 学习项目 Umo Space)。这里的关键要点是你选择一种颜色
context.fillstyle = "red";//then
context.beginpath(); //to start the polygon, then use
context.moveto(x,y); //to pick a starting vertex (x and y are numbers), and
context.lineto(x,y);// to select more vertices from there (at least 3 points to a polygon). You don't need to return to the first vertex at the end, just use
context.fill(); //and it will automagically close the polygon and fill it with the color.
function drawpolarpoly(px,py,thetalist, radiuslist, size, color, dir){
//requires, does not verify, that thetalist.length==radiuslist.length, thetalist.length>2, color be valid
var fx = px + Math.cos(dir+thetalist[0])*size*radiuslist[0];
var fy = py + Math.sin(dir+thetalist[0])*size*radiuslist[0];
context.fillStyle = color; //Now actual drawing of the things
context.beginPath();
context.moveTo(fx, fy);
i = thetalist.length;
while(i>0){
i=i-1;
var ix = px + Math.cos(dir+thetalist[i])*size*radiuslist[i];
var iy = py + Math.sin(dir+thetalist[i])*size*radiuslist[i];
context.lineTo(ix, iy);
}
context.fill();
}
function draworthopoly(px,py, xlist, ylist, size, color, dir){//Not really useful, because this
var fx = px + xlist[0]*size; //needs to be transformed to polar coords to rotate it anyways
var fy = py + ylist[0]*size;
context.fillStyle = color; //Now actual drawing of the things
context.beginPath();
context.moveTo(fx, fy);
i = xlist.length;
while(i>0){
i=i-1;
var ix = px + xlist[i]*size;
var iy = py + ylist[i]*size;
context.lineTo(ix, iy);
}
context.fill();
}
除了矩形和圆形之外,还有什么方法可以使用 JavaScript 在 HTML 中创建基本的二维形状吗?
例如,假设我们有一个 <canvas></canvas>
(因为任何其他元素无法按照我尝试的方式修改,或者?)元素,其中 width:100px
、height:300px
和 background:black
。
我怎样才能将它的右上角(右上角顶点)移动到不同的位置来创建一个不同的形状而不是一个矩形?
发件人:
point one: x: 0px / y: 0px
point two: x: 100px / y: 0px
point three: x: 100px / y: 300px
point four: x: 0px / y: 300px
收件人:
point one: x: 0px / y: 0px
point two: x: 120px / y: -20px
point three: x: 100px / y: 300px
point four: x: 0 / y:300px
(point two
是改的那个)
HTML 是否有任何 JavaScript 图形库可以使这项任务变得简单?沿着 drawable.vertices[1].move(20, -20)
的路线将第二个顶点在 x 上移动 20px,在 y 上移动 -20px。
你看过pixi.js了吗? (http://www.pixijs.com/) it is a 2d library which utilizes WebGL but falls back to canvas if WebGL is not supported by the browser. If you want to go to 3d libraries also look into Three.js (http://threejs.org/)
另一个专门针对 canvas 的相当流行的图形库是 Raphael 库 (http://raphaeljs.com/)
更新:
在偏移量为 100px 且尺寸为 300x300px 的元素中用 Raphael 初始化一个 canvas。请注意,我在这里依赖 JQuery 来获取 "mycanvas" 元素。
var paper = Raphael($("#mycanvas"), 100, 300,300);
要绘制任意多边形,您需要使用 Raphael "paper" 对象上的路径函数,传入 svg 路径字符串(如果您有兴趣阅读更多关于 SVG 路径标准的信息,您可以找到这里有一些信息:http://www.w3.org/TR/SVG/paths.html#PathData)
paper.path("M150,0L200,100L100,100Z").attr("fill","#F00");
路径末端的属性用红色填充多边形。
在两行中,我使用 SVG 路径生成了一个红色三角形。我认为您不会得到比这更轻的重量。
现在根据您最后的评论,您希望它是交互式的。这不会像您想的那么简单。
您要实现的目标的粗略方法将要求您:
1) 保留要转换为 SVG 字符串的顶点数组。
2) 您将不得不跟踪 canvas 上的鼠标按下事件。每次发现鼠标按下事件时,您都必须检查它是否在顶点列表中的顶点上,明智的做法是为错误添加一个 epsilon,这样用户就不必准确地单击一个像素,而是在靠近顶点的区域中。您可以使用装箱方法为您提供围绕顶点的某种方框 epsilon。创建对您按下鼠标的顶点的引用。
3) 在鼠标移动事件上,同时鼠标按钮也按下,并且有一个活动顶点你想根据鼠标坐标修改该顶点的位置。
4) 在鼠标弹起事件中,根据多边形中的顶点数量,您可以使用 paper.clear() 清除纸张并通过生成新的 SVG 路径重绘路径顶点列表中的字符串并使用 paper.path(...) 添加新的 SVG 字符串。
这是我创建的用于为您绘制三角形多边形的 plnkr 的 link:http://plnkr.co/edit/AK5zO1ZqBTerMf9AzS88?p=preview
最终奖金更新:
所以我决定在 plnkr 中为您做这件事,这样您就可以了解如何操纵路径并强制重绘。本质上 javascript 绘制两条路径,一条用于三角形,一条用于每个三角形顶点末端的蓝点。我在控件路径元素的拖动中注册了两个委托函数,以便它们中的每一个都可以更新它们的 X 和 Y 值以及相应的三角形顶点。看看 plnkr,如果有什么不合理的地方请告诉我。
http://plnkr.co/edit/o5QHap7NV1SYIbsS76f5
尽情享受吧! :)
我在 gamecanvas 中做了一些多边形的东西。我制作了一些函数来生成相对于相机/玩家位置定位的任意多边形,这可能是相关的或有帮助的(来自我的 open sauce javascript 学习项目 Umo Space)。这里的关键要点是你选择一种颜色
context.fillstyle = "red";//then
context.beginpath(); //to start the polygon, then use
context.moveto(x,y); //to pick a starting vertex (x and y are numbers), and
context.lineto(x,y);// to select more vertices from there (at least 3 points to a polygon). You don't need to return to the first vertex at the end, just use
context.fill(); //and it will automagically close the polygon and fill it with the color.
function drawpolarpoly(px,py,thetalist, radiuslist, size, color, dir){
//requires, does not verify, that thetalist.length==radiuslist.length, thetalist.length>2, color be valid
var fx = px + Math.cos(dir+thetalist[0])*size*radiuslist[0];
var fy = py + Math.sin(dir+thetalist[0])*size*radiuslist[0];
context.fillStyle = color; //Now actual drawing of the things
context.beginPath();
context.moveTo(fx, fy);
i = thetalist.length;
while(i>0){
i=i-1;
var ix = px + Math.cos(dir+thetalist[i])*size*radiuslist[i];
var iy = py + Math.sin(dir+thetalist[i])*size*radiuslist[i];
context.lineTo(ix, iy);
}
context.fill();
}
function draworthopoly(px,py, xlist, ylist, size, color, dir){//Not really useful, because this
var fx = px + xlist[0]*size; //needs to be transformed to polar coords to rotate it anyways
var fy = py + ylist[0]*size;
context.fillStyle = color; //Now actual drawing of the things
context.beginPath();
context.moveTo(fx, fy);
i = xlist.length;
while(i>0){
i=i-1;
var ix = px + xlist[i]*size;
var iy = py + ylist[i]*size;
context.lineTo(ix, iy);
}
context.fill();
}