简体   繁体   English

KineticJS,像程序一样绘制,刷间隙

[英]KineticJS, Paint like program, brush gaps

I am trying to do something like paint with KineticJS. 我正在尝试使用KineticJS进行绘画等操作。 I am trying to draw the color with circles that originate from the mouse position. 我试图用源自鼠标位置的圆圈绘制颜色。 However the eventlistener of the mouse position seems too slow and when I move the mouse too fast the circles drawn are far from each other resulting this: 但是,鼠标位置的事件监听器似乎太慢,并且当我将鼠标移动得太快时,绘制的圆圈彼此之间距离很远,从而导致:

I have seen people filling array with points drawing lines between them, but I thought thats very bad for optimization because after dubbing the screen too much the canvas starts lagging because it has too much lines that it redraws every frame. 我见过人们用点之间的绘制点填充阵列,但是我认为这对优化非常不利,因为在复制屏幕后,画布开始滞后,因为画布上的线条太多,因此每帧都要重画。 I decided to cancel the cleaning of the layer and I am adding new circle at the current mouse position and I remove the old one for optimization. 我决定取消对图层的清洁,并在当前鼠标位置添加新的圆圈,并删除旧的圆圈以进行优化。 However since Im not drawing lines on fast mouse movement it leaves huge gaps. 但是,由于Im不能以快速的鼠标移动来绘制线条,因此留下了巨大的空白。 I would be very grateful if anyone can help me with this. 如果有人可以帮助我,我将不胜感激。

Here is my code: 这是我的代码:

 (function() { var stage = new Kinetic.Stage({ container: 'main-drawing-window', width: 920, height: 750 }), workplace = document.getElementById('main-drawing-window'), layer = new Kinetic.Layer({ clearBeforeDraw: false }), border = new Kinetic.Rect({ stroke: "black", strokeWidth: 2, x: 0, y: 0, width: stage.getWidth(), height: stage.getHeight() }), brush = new Kinetic.Circle({ radius: 20, fill: 'red', strokeWidth: 2, x: 100, y: 300 }); Input = function() { this.mouseIsDown = false; this.mouseX = 0; this.mouseY = 0; this.offsetX = 0; this.offsetY = 0; }; var input = new Input(); document.documentElement.onmousedown = function(ev) { input.mouseIsDown = true; }; document.documentElement.onmouseup = function(ev) { input.mouseIsDown = false; }; document.documentElement.onmousemove = function(ev) { ev = ev || window.event; // input.mouseX = (ev.clientX - workplace.offsetLeft); // input.mouseY = (ev.clientY - workplace.offsetTop); input.mouseX = (ev.offsetX); input.mouseY = (ev.offsetY); }; function DistanceBetweenPoints(x1, y1, x2, y2) { return Math.sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1))); } var canvasDraw = setInterval(function() { // console.log(input); if (input.mouseIsDown) { workplace.style.cursor = "crosshair"; var currentBrushPosition = brush.clone(); currentBrushPosition.setX(input.mouseX); currentBrushPosition.setY(input.mouseY); // var distance = DistanceBetweenPoints(brush.getX(), brush.getY(), currentBrushPosition.getX(), currentBrushPosition.getY()); // if (distance > brush.getRadius() * 2) { // var fillingLine = new Kinetic.Line({ // points: [brush.getX(), brush.getY(), currentBrushPosition.getX(), currentBrushPosition.getY()], // stroke: 'yellow', // strokeWidth: brush.getRadius()*2, // lineJoin: 'round' // }); // // layer.add(fillingLine); // } layer.add(currentBrushPosition); brush.remove(); brush = currentBrushPosition; layer.draw(); // if (fillingLine) { // fillingLine.remove(); // } } if (!input.mouseIsDown) { workplace.style.cursor = 'default'; } }, 16); layer.add(border); stage.add(layer); })(); 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Coloring Game</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/kineticjs/5.2.0/kinetic.min.js"></script> </head> <body> <div id="main-drawing-window"></div> <script type="text/javascript" src="./JS files/canvas-draw.js"></script> </body> </html> 

Don't use individual Kinetic.Circle s for each mousemove. 每次Kinetic.Circle不要使用单独的Kinetic.Circle Every Kinetic object is a "managed" object and that management takes up a lot of resources. 每个Kinetic对象都是一个“托管”对象,该管理占用大量资源。 KineticJS will slow to a crawl as the number of circles increases with every mousemove. 随着每次鼠标移动圆的数量增加,KineticJS将缓慢爬行。

Instead, use a Kinetic.Shape and draw you circles onto the canvas with 而是使用Kinetic.Shape并使用

// This is Pseudo-code since I haven't worked with KineticJS in a while
shapeContext.beginPath();
shapeContext.arc(mouseX,mouseY,20,0,Math.PI*2);
shapeContext.fillStrokeShape(this);

This will probably clear your problem, but if the mouse is moved very far in a single mousemove then you might have to draw a lineTo (instead of arc ) between the last mouse point and the current far-away mouse point. 这可能会解决您的问题,但是如果鼠标在一次mousemove中移动了很远,则可能必须在最后一个鼠标点和当前远距离的鼠标点之间绘制lineTo (而不是arc )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM