我正在尝试使用Kinetic/Paper/Fabric JS编写一个简单的手绘应用程序。然而,我注意到,使用这些库进行徒手绘制的所有示例都没有任何响应。
所谓响应,我的意思是KineticJS/PaperJS不会像使用jSignature那样,在我拖动鼠标时更新正在绘制的线。
有什么办法解决这个问题吗?
下面是一个使用KineticJS的例子:http://jsfiddle.net/m1erickson/EsFSg/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
}
</style>
<script>
$(function(){
// create a stage and a layer
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
// an empty stage does not emit mouse-events
// so fill the stage with a background rectangle
// that can emit mouse-events
var background = new Kinetic.Rect({
x: 0,
y: 0,
width: stage.getWidth(),
height: stage.getHeight(),
fill: 'white',
stroke: 'black',
strokeWidth: 1,
})
layer.add(background);
layer.draw();
// a flag we use to see if we're dragging the mouse
var isMouseDown=false;
// a reference to the line we are currently drawing
var newline;
// a reference to the array of points making newline
var points=[];
// on the background
// listen for mousedown, mouseup and mousemove events
background.on('mousedown', function(){onMousedown();});
background.on('mouseup', function(){onMouseup();});
background.on('mousemove', function(){onMousemove();});
// On mousedown
// Set the isMouseDown flag to true
// Create a new line,
// Clear the points array for new points
// set newline reference to the newly created line
function onMousedown(event) {
isMouseDown = true;
points=[];
points.push(stage.getMousePosition());
var line = new Kinetic.Line({
points: points,
stroke: "green",
strokeWidth: 5,
lineCap: 'round',
lineJoin: 'round'
});
layer.add(line);
newline=line;
}
// on mouseup end the line by clearing the isMouseDown flag
function onMouseup(event) {
isMouseDown=false;
}
// on mousemove
// Add the current mouse position to the points[] array
// Update newline to include all points in points[]
// and redraw the layer
function onMousemove(event) {
if(!isMouseDown){return;};
points.push(stage.getMousePosition());
newline.setPoints(points);
// use layer.drawScene
// This avoids unnecessarily updating the hit canva
layer.drawScene();
}
}); // end $(function(){});
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
[添加答案:进一步优化]
进一步的性能包括从绘图中取消鼠标点捕获的链接。
在mousemove中:只捕捉鼠标位置——不要试图在mousemove中绘制任何内容。
- accumulatedPointsArray.push({x:mouseX,y:mouseY})
您甚至可以考虑忽略一些鼠标点,因为更少的点仍然可以绘制出相当好的多段线。也许只保存每三个传入的鼠标指针。
绘制:设置一个动画循环:
将累积的点添加到Kinetic.Line--myLine.setPoints(accumulatedPointsArray)
做一个myLine.draw().
要挤出每一点性能,可以考虑使用Kinetic.Shape而不是Kinetic.Line来显示用户创建的多段线。Kinetic.Shape为您提供了一个画布上下文,因此它"更接近金属",并且与"托管"Kinetic.Line相比具有更好的绘图性能。当用户定义完他们的线后,您可以将这些累积的点移动到Kinetic.Line中,并隐藏Kinetic.Shape-best。
不管怎样,祝你的项目好运!