HTML5 Canvas 如何填充鼠标绘制的三角形
HTML5 Canvas How To Fill A Mouse Drawn Triangle
我正在尝试通过拖动鼠标在 HTML5 canvas 上填充三角形。
我对圆形、矩形有类似的效果。
下面显示了有效的 drawCircle 和无效的 drawTriangle 函数的代码。绘制了三角形的轮廓,但未填充。我试过按顺序将 context.stroke
行爱到不同的地方,但没有效果。
<style>
#divContainer {
width: 100%;
height: 80%;
background: #ddd;
}
#divContentArea {
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.canvas {
cursor: crosshair;
position:relative;
left:0px;
top:0px;
}
</style>
<div>
Click the button to select the shape type then click and drag mouse on the canvas below.
<BR>
<button type="button" onClick='shapetype="circle";'>Draw Circle</button>
<button type="button" onClick='shapetype="triangle";'>Draw Triangle</button>
<BR>
</div>
<div id="divContainer">
<div id="divContentArea">
<canvas id="canvas" class='canvas'>
Sorry, your browser does not support a canvas object.
</canvas>
</div>
</div>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canrect = canvas.getBoundingClientRect();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var lastPoint;
var startPoint;
var isDrawing = false;
var shapetype = 'triangle';
canvas.onmousedown = function(e) {
isDrawing = true;
if ( shapetype == 'circle' ) {
canvas.removeEventListener("mousemove", drawTriangle, false);
canvas.addEventListener("mousemove", drawCircle, false);
} else {
canvas.removeEventListener("mousemove", drawCircle, false);
canvas.addEventListener("mousemove", drawTriangle, false);
}
lastPoint = { x: e.offsetX, y: e.offsetY };
startPoint = lastPoint;
};
function drawTriangle(e) {
// This doesn't work - triangle is not filled
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var twidth = Math.abs(mx - startPoint.x) ;
var theight = Math.abs(my - startPoint.y) ;
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
if ( mx >= startPoint.x ) {
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx-(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx-(2*twidth), my );
} else {
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx+(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx+(2*twidth), my );
}
context.closePath();
context.strokeStyle = 'red';
context.stroke();
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
}
function drawCircle(e) {
// This works
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var cradius = Math.abs(mx - startPoint.x) ;
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.strokeStyle = 'red';
context.arc(startPoint.x, startPoint.y, cradius, 0, 2 * Math.PI, false);
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
context.stroke();
}
canvas.onmouseup = function() {
isDrawing = false;
};
canvas.onmouseleave = function() {
isDrawing = false;
};
</script>
function drawTriangle(e) {
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// draw a new rect from the start position
// to the current mouse position
context.strokeStyle = 'red';
context.fillStyle = 'rgba(25,50,75,0.5)';
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.beginPath();
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(e.offsetX, e.offsetY);
context.lineTo(startPoint.x * 2 - e.offsetX, e.offsetY);
context.closePath();
context.stroke();
context.fill();
}
CanvasRenderingContext2D 的 fill()
方法用给定的颜色填充路径。为了能够填充这样的路径,它必须至少包含三个点 - 这在您的情况下已实现。
问题在于您创建路径的方式:
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx-(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx-(2*twidth), my );
通过再次调用 moveTo()
,您实际上是在开始一条新路径 - 因此您只有三行,因此无需填写任何内容。
尝试一次完成路径:
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.lineTo(mx-(2*twidth), my );
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canrect = canvas.getBoundingClientRect();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var lastPoint;
var startPoint;
var isDrawing = false;
var shapetype = 'triangle';
canvas.onmousedown = function(e) {
isDrawing = true;
if (shapetype == 'circle') {
canvas.removeEventListener("mousemove", drawTriangle, false);
canvas.addEventListener("mousemove", drawCircle, false);
} else {
canvas.removeEventListener("mousemove", drawCircle, false);
canvas.addEventListener("mousemove", drawTriangle, false);
}
lastPoint = {
x: e.offsetX,
y: e.offsetY
};
startPoint = lastPoint;
};
function drawTriangle(e) {
// This doesn't work - triangle is not filled
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var twidth = Math.abs(mx - startPoint.x);
var theight = Math.abs(my - startPoint.y);
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
if (mx >= startPoint.x) {
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(mx, my);
context.lineTo(mx - (2 * twidth), my);
} else {
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(mx, my);
context.lineTo(mx + (2 * twidth), my);
}
context.closePath();
context.strokeStyle = 'red';
context.stroke();
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
}
function drawCircle(e) {
// This works
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var cradius = Math.abs(mx - startPoint.x);
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.strokeStyle = 'red';
context.arc(startPoint.x, startPoint.y, cradius, 0, 2 * Math.PI, false);
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
context.stroke();
}
canvas.onmouseup = function() {
isDrawing = false;
};
canvas.onmouseleave = function() {
isDrawing = false;
};
#divContainer {
width: 100%;
height: 80%;
background: #ddd;
}
#divContentArea {
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.canvas {
cursor: crosshair;
position: relative;
left: 0px;
top: 0px;
}
<div>
Click the button to select the shape type then click and drag mouse on the canvas below.
<BR>
<button type="button" onClick='shapetype="circle";'>Draw Circle</button>
<button type="button" onClick='shapetype="triangle";'>Draw Triangle</button>
<BR>
</div>
<div id="divContainer">
<div id="divContentArea">
<canvas id="canvas" class='canvas'>
Sorry, your browser does not support a canvas object.
</canvas>
</div>
</div>
我正在尝试通过拖动鼠标在 HTML5 canvas 上填充三角形。
我对圆形、矩形有类似的效果。
下面显示了有效的 drawCircle 和无效的 drawTriangle 函数的代码。绘制了三角形的轮廓,但未填充。我试过按顺序将 context.stroke
行爱到不同的地方,但没有效果。
<style>
#divContainer {
width: 100%;
height: 80%;
background: #ddd;
}
#divContentArea {
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.canvas {
cursor: crosshair;
position:relative;
left:0px;
top:0px;
}
</style>
<div>
Click the button to select the shape type then click and drag mouse on the canvas below.
<BR>
<button type="button" onClick='shapetype="circle";'>Draw Circle</button>
<button type="button" onClick='shapetype="triangle";'>Draw Triangle</button>
<BR>
</div>
<div id="divContainer">
<div id="divContentArea">
<canvas id="canvas" class='canvas'>
Sorry, your browser does not support a canvas object.
</canvas>
</div>
</div>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canrect = canvas.getBoundingClientRect();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var lastPoint;
var startPoint;
var isDrawing = false;
var shapetype = 'triangle';
canvas.onmousedown = function(e) {
isDrawing = true;
if ( shapetype == 'circle' ) {
canvas.removeEventListener("mousemove", drawTriangle, false);
canvas.addEventListener("mousemove", drawCircle, false);
} else {
canvas.removeEventListener("mousemove", drawCircle, false);
canvas.addEventListener("mousemove", drawTriangle, false);
}
lastPoint = { x: e.offsetX, y: e.offsetY };
startPoint = lastPoint;
};
function drawTriangle(e) {
// This doesn't work - triangle is not filled
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var twidth = Math.abs(mx - startPoint.x) ;
var theight = Math.abs(my - startPoint.y) ;
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
if ( mx >= startPoint.x ) {
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx-(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx-(2*twidth), my );
} else {
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx+(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx+(2*twidth), my );
}
context.closePath();
context.strokeStyle = 'red';
context.stroke();
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
}
function drawCircle(e) {
// This works
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var cradius = Math.abs(mx - startPoint.x) ;
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.strokeStyle = 'red';
context.arc(startPoint.x, startPoint.y, cradius, 0, 2 * Math.PI, false);
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
context.stroke();
}
canvas.onmouseup = function() {
isDrawing = false;
};
canvas.onmouseleave = function() {
isDrawing = false;
};
</script>
function drawTriangle(e) {
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// draw a new rect from the start position
// to the current mouse position
context.strokeStyle = 'red';
context.fillStyle = 'rgba(25,50,75,0.5)';
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.beginPath();
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(e.offsetX, e.offsetY);
context.lineTo(startPoint.x * 2 - e.offsetX, e.offsetY);
context.closePath();
context.stroke();
context.fill();
}
CanvasRenderingContext2D 的 fill()
方法用给定的颜色填充路径。为了能够填充这样的路径,它必须至少包含三个点 - 这在您的情况下已实现。
问题在于您创建路径的方式:
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.moveTo(mx-(2*twidth), my );
context.lineTo(mx, my);
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx-(2*twidth), my );
通过再次调用 moveTo()
,您实际上是在开始一条新路径 - 因此您只有三行,因此无需填写任何内容。
尝试一次完成路径:
context.moveTo(startPoint.x, startPoint.y );
context.lineTo(mx, my);
context.lineTo(mx-(2*twidth), my );
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var canrect = canvas.getBoundingClientRect();
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var lastPoint;
var startPoint;
var isDrawing = false;
var shapetype = 'triangle';
canvas.onmousedown = function(e) {
isDrawing = true;
if (shapetype == 'circle') {
canvas.removeEventListener("mousemove", drawTriangle, false);
canvas.addEventListener("mousemove", drawCircle, false);
} else {
canvas.removeEventListener("mousemove", drawCircle, false);
canvas.addEventListener("mousemove", drawTriangle, false);
}
lastPoint = {
x: e.offsetX,
y: e.offsetY
};
startPoint = lastPoint;
};
function drawTriangle(e) {
// This doesn't work - triangle is not filled
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var twidth = Math.abs(mx - startPoint.x);
var theight = Math.abs(my - startPoint.y);
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
if (mx >= startPoint.x) {
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(mx, my);
context.lineTo(mx - (2 * twidth), my);
} else {
context.moveTo(startPoint.x, startPoint.y);
context.lineTo(mx, my);
context.lineTo(mx + (2 * twidth), my);
}
context.closePath();
context.strokeStyle = 'red';
context.stroke();
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
}
function drawCircle(e) {
// This works
e.preventDefault();
e.stopPropagation();
if (!isDrawing) return;
mx = e.offsetX;
my = e.offsetY;
// clear the canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var cradius = Math.abs(mx - startPoint.x);
// draw a new rect from the start position
// to the current mouse position
context.beginPath();
context.lineWidth = 3;
context.lineJoin = context.lineCap = 'round';
context.setLineDash([0, 0]);
context.globalAlpha = 1.0;
context.strokeStyle = 'red';
context.arc(startPoint.x, startPoint.y, cradius, 0, 2 * Math.PI, false);
context.fillStyle = 'rgba(25,50,75,0.5)';
context.fill();
context.stroke();
}
canvas.onmouseup = function() {
isDrawing = false;
};
canvas.onmouseleave = function() {
isDrawing = false;
};
#divContainer {
width: 100%;
height: 80%;
background: #ddd;
}
#divContentArea {
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.canvas {
cursor: crosshair;
position: relative;
left: 0px;
top: 0px;
}
<div>
Click the button to select the shape type then click and drag mouse on the canvas below.
<BR>
<button type="button" onClick='shapetype="circle";'>Draw Circle</button>
<button type="button" onClick='shapetype="triangle";'>Draw Triangle</button>
<BR>
</div>
<div id="divContainer">
<div id="divContentArea">
<canvas id="canvas" class='canvas'>
Sorry, your browser does not support a canvas object.
</canvas>
</div>
</div>