我需要在画布上绘制六边形,但每条边需要是不同的颜色。
我无法绘制边缘,因为我还需要一个半径和旋转值。
var canvas = document.querySelector("canvas");
var ctx = canvas.getContext("2d");
function circle(x, y, r, fill) {
ctx.beginPath()
ctx.arc(x, y, r, 0, Math.PI*2)
if (fill) {
ctx.fill();
} else {
ctx.stroke();
}
}
function poly(edges, radius, fill, startAngle) {
if (typeof startAngle === "undefined") {
var startAngle = -90;
}
var angle = 360/edges;
ctx.beginPath();
for (var i = 0; i <= edges; i++) {
var a = ((angle*i)+startAngle)*(Math.PI/180);
var x = 180 + radius * Math.cos(a);
var y = 180 + radius * Math.sin(a);
ctx.lineTo(x, y);
}
if (fill) {
ctx.fill();
} else {
ctx.stroke();
}
}
var Game = {
"rotation": 0,
"r": 0
};
function Draw() {
ctx.save();
ctx.clearRect(0, 0, 360, 360);
ctx.lineWidth = 100;
circle(180, 180, 180+(ctx.lineWidth/2));
ctx.lineWidth = 1;
poly(6, 30, false, Game.r-90);
if (Game.r != Game.rotation) {
if (Game.r < Game.rotation) {
Game.r += 10;
} else if (Game.r > Game.rotation) {
Game.r -= 10;
}
}
window.requestAnimationFrame(Draw);
ctx.restore();
}
Draw();
document.onkeydown = function(e) {
switch (e.which) {
case 39: // Right Arrow
Game.rotation += (360/6);
break;
case 37: // Left Arrow
Game.rotation -= (360/6);
break;
}
}
&#13;
<canvas width="360" height="360"></canvas>
&#13;
答案 0 :(得分:1)
跟踪Shape
的位置和角度以及每个角落。
然后在需要时使用Math.cos
和Math.sin
计算边缘:
var Shape = (function() {
/**
* Creates an instance of Shape.
*
* @param {ICoord} [position={ x: 0, y: 0 }]
* @param {ICoord[]} [points=[]]
* @param {number} [angle]
*
* @memberOf Shape
*/
function Shape(position, points, angle) {
if (position === void 0) {
position = {
x: 0,
y: 0
};
}
if (points === void 0) {
points = [];
}
this.position = position;
this.points = points;
this.angle = 0;
if (angle != void 0) {
this.setAngle(angle);
}
}
Shape.degreetoRadian = function(degree) {
return degree * (Math.PI / 180);
};
/**
* Create a shape from a position, a radius, the number of vertices and an angle in degrees [0;360]
*
* @static
* @param {ICoord} [position={ x: 0, y: 0 }]
* @param {number} [radius=10]
* @param {number} [stops=4]
* @param {number} [angle=0]
* @returns {Shape}
*
* @memberOf Shape
*/
Shape.poly = function(position, radius, stops, angle) {
if (position === void 0) {
position = {
x: 0,
y: 0
};
}
if (radius === void 0) {
radius = 10;
}
if (stops === void 0) {
stops = 4;
}
if (angle === void 0) {
angle = 0;
}
var points = [];
for (var index = 0; index < 360; index += (360 / stops)) {
points.push({
x: Math.cos(this.degreetoRadian(index)) * radius,
y: Math.sin(this.degreetoRadian(index)) * radius
});
}
return new Shape(position, points, angle);
};
/**
* Sets the angle to a value between 0 and 360
*
* @param {number} [value=this.angle]
* @returns {Shape}
*
* @memberOf Shape
*/
Shape.prototype.setAngle = function(value) {
if (value === void 0) {
value = this.angle;
}
this.angle = Math.abs(value) % 360;
return this;
};
/**
* Dissolves the points into lines, rotated to match the orientation of the Shape
*
* @returns {{ start: { x: number, y: number }, end: { x: number, y: number } }[]}
*
* @memberOf Shape
*/
Shape.prototype.getLines = function() {
var theta = Shape.degreetoRadian(this.angle);
var edges = [];
for (var indexa = 0; indexa < this.points.length; indexa++) {
var a = this.points[indexa];
var b = this.points[(indexa + 1) % this.points.length];
edges.push({
start: {
x: a.x * Math.cos(theta) - a.y * Math.sin(theta),
y: a.x * Math.sin(theta) + a.y * Math.cos(theta)
},
end: {
x: b.x * Math.cos(theta) - b.y * Math.sin(theta),
y: b.x * Math.sin(theta) + b.y * Math.cos(theta)
}
});
}
return edges;
};
return Shape;
}());
//>>Testing
//DOM
var c = document.createElement("canvas");
c.width = 100;
c.height = 100;
document.body.appendChild(c);
var ctx = c.getContext("2d");
//Shape
var drawings = [
Shape.poly({
x: 50,
y: 50
}, 50, 6, 360 / 12),
Shape.poly({
x: 50,
y: 50
}, 30, 6),
Shape.poly({
x: 50,
y: 50
}, 30, 3)
];
//Rendering
var colors = ["red", "green", "yellow", "blue", "magenta"];
var interval;
interval = setInterval(function() {
ctx.clearRect(0, 0, c.width, c.height);
for (var drawingIndex = 0; drawingIndex < drawings.length; drawingIndex++) {
var drawing = drawings[drawingIndex];
drawing.setAngle(drawing.angle + 1);
var edges = drawing.getLines();
ctx.lineWidth = 4;
for (var index = 0; index < edges.length; index++) {
var edge = edges[index];
ctx.beginPath();
ctx.strokeStyle = colors[index % colors.length];
ctx.moveTo(edge.start.x + drawing.position.x, edge.start.y + drawing.position.y);
ctx.lineTo(edge.end.x + drawing.position.x, edge.end.y + drawing.position.y);
ctx.stroke();
ctx.closePath();
}
}
}, 1000 / 60);
编辑1 - 有角度的边
基于评论显示Artsen希望得到一个有角度的交叉点。
这可以使用画布上的arc
方法轻松实现:
var Xagon = /** @class */ (function () {
function Xagon(sides, radius, angle, lineWidth) {
if (sides === void 0) { sides = 4; }
if (radius === void 0) { radius = 4; }
if (angle === void 0) { angle = 0; }
if (lineWidth === void 0) { lineWidth = 1; }
this.sides = sides;
this.radius = radius;
this.angle = angle;
this.lineWidth = lineWidth;
}
Xagon.prototype.draw = function (ctx, offset, handleSide) {
if (offset === void 0) { offset = { x: 0, y: 0 }; }
var sideOffset = 360 / this.sides;
for (var side = 0; side < this.sides; side++) {
var ang = Xagon.degreetoRadian(this.angle + sideOffset * side);
ctx.beginPath();
ctx.arc(offset.x, offset.y, this.radius - 0.5 * this.lineWidth, ang, ang);
ctx.arc(offset.x, offset.y, this.radius + 0.5 * this.lineWidth, ang, ang);
ctx.arc(offset.x, offset.y, this.radius + 0.5 * this.lineWidth, ang - Xagon.degreetoRadian(sideOffset), ang - Xagon.degreetoRadian(sideOffset));
ctx.arc(offset.x, offset.y, this.radius - 0.5 * this.lineWidth, ang - Xagon.degreetoRadian(sideOffset), ang - Xagon.degreetoRadian(sideOffset));
ctx.closePath();
if (handleSide !== void 0) {
handleSide(ctx, side);
}
}
};
Xagon.prototype.setAngle = function (value) {
if (value === void 0) {
value = this.angle;
}
this.angle = Math.abs(value) % 360;
return this;
};
Xagon.degreetoRadian = function (degree) {
return degree * (Math.PI / 180);
};
return Xagon;
}());
//TEST
var c = document.body.appendChild(document.createElement("canvas"));
var size = c.width = c.height = 500;
var ctx = c.getContext("2d");
var x = new Xagon(6, size * 0.4, 0, 50);
var interval;
var colors = ["red", "green", "yellow", "blue", "magenta", "cyan"];
function update() {
ctx.clearRect(0, 0, size, size);
x.setAngle(x.angle + 1);
x.draw(ctx, { x: size / 2, y: size / 2 }, function side(ctx, sideIndex) {
ctx.fillStyle = colors[sideIndex % colors.length];
ctx.fill();
});
cancelAnimationFrame(interval);
interval = requestAnimationFrame(update);
}
interval = requestAnimationFrame(update);