我需要你帮助一个带图层的小涂料应用程序。 我希望我的程序能够处理不同的图层,但不使用多个画布或使用外部库,以便更多地了解整个画布的工作原理。 我想要记住位于不同图层对象中的数组中的每个数据,而不是在画布上从最低到最高打印它们。问题是我想用手绘画,而不仅仅是用圆圈和正方形。如果我会记住我手工绘制的所有东西,那么它将会很慢(已经尝试过)。 谢谢大家的帮助!
答案 0 :(得分:0)
您当然可以只使用一个画布来应用非正式的z-index。
你已经确定了一种正确的方法:
然后您可以重播这些已保存的命令。显示将很快发生。
以下是您的Layer.draw
方法的一个版本,该版本已经过重构以获得更好的效果:
// draw() will define & stroke all polylines on this layer
// The 1st point in each polyline contains that line's styling
Layer.prototype.draw = function( ctx ) {
// just return if there's no points to draw
if(this.points.length<2){return;}
// cache an often used array
var pts=this.points;
// index for points
var i=0;
// process all points in the
while(i<pts.length){
// cache the often used first point in a new polyline
var p=pts[i];
// set styles for this polyline
ctx.lineWidth = p.lineWidth;
ctx.lineJoin = p.lineJoin;
ctx.lineCap = p.lineCap;
ctx.strokeStyle = p.strokeStyle;
// begin this polyline path
ctx.beginPath();
ctx.moveTo(p.x, p.y);
i++;
// define all segment points on this polyline
while( i<pts.length && pts[i].lineWidth==undefined ) {
ctx.lineTo( pts[i].x , pts[i].y );
i++;
}
// stroke this polyline
ctx.stroke();
} // end while(i<pts.length)
}
以下是示例代码和演示:
Point = function( x , y ) {
this.x = x;
this.y = y;
}
Point.prototype.invert = function() {
var t = this.x;
this.x = this.y;
this.y = t;
}
Layer = function() {
this.points = [];
}
Layer.prototype.draw = function( ctx ) {
// just return if there's no points to draw
if(this.points.length<2){return;}
// cache an often used array
var pts=this.points;
// index for points
var i=0;
// process all points in the
while(i<pts.length){
// cache the often used first point in a new polyline
var p=pts[i];
// set styles for this polyline
ctx.lineWidth = p.lineWidth;
ctx.lineJoin = p.lineJoin;
ctx.lineCap = p.lineCap;
ctx.strokeStyle = p.strokeStyle;
// begin this polyline path
ctx.beginPath();
ctx.moveTo(p.x, p.y);
i++;
// define all segment points on this polyline
while( i<pts.length && pts[i].lineWidth==undefined ) {
ctx.lineTo( pts[i].x , pts[i].y );
i++;
}
// stroke this polyline
ctx.stroke();
} // end while(i<pts.length)
}
ExtendedPoint = function( x , y , style ) {
this.x = x;
this.y = y;
this.lineWidth = style.lineWidth;
this.lineJoin = style.lineJoin;
this.lineCap = style.lineCap;
this.strokeStyle = style.strokeStyle;
}
function startLine( e ) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
var p = new ExtendedPoint( x , y , {
lineWidth: 5,
lineJoin: "round",
lineCap: "round",
// testing only: make each new polyline a different color
// strokeStyle: "black"
strokeStyle: randomColor(),
});
selectedLayer.points.push(p);
isDrawing = true;
}
function continueLine( e ) {
if (isDrawing == true) {
var x = e.clientX - canvas.offsetLeft;
var y = e.clientY - canvas.offsetTop;
var p = new Point( x , y );
selectedLayer.points.push( p );
}
}
function endLine() {
isDrawing = false;
}
function redraw() {
context.clearRect( 0, 0, 400, 400 );
for ( var i = 0 ; i < layers.length ; i++ ) {
layers[i].draw( context );
}
}
var canvas = document.getElementById("cvs");
canvas.setAttribute("width" , 400);
canvas.setAttribute("height", 400);
var context = canvas.getContext("2d");
var layers = [];
layers.push( new Layer() );
var selectedLayer = layers[0];
var isDrawing = false;
canvas.addEventListener( "mousedown" , startLine );
canvas.addEventListener( "mousemove" , continueLine );
canvas.addEventListener( "mousemove" , redraw );
canvas.addEventListener( "mouseup" , endLine );
// testing only: make each polyline a different color
function randomColor(){
return('#'+Math.floor(Math.random()*16777215).toString(16));
}
&#13;
body{ background-color: ivory; }
canvas{border:1px solid red;}
&#13;
<h4>Drag to draw layered lines</h4>
<canvas id="cvs" width=400 height=400></canvas>
&#13;