gpt4 book ai didi

javascript - RXJS 在 html5 Canvas 上画线

转载 作者:搜寻专家 更新时间:2023-10-31 22:45:01 24 4
gpt4 key购买 nike

我正在尝试使用 Reactive Extensions for Javascript (RX-JS) 实现与我在此处发布的效果相同的效果。我对如何去做有点困惑。这是页面:

      <!DOCTYPE html>
<html>
<head>
<title>drag and drop</title>
</head>
<style type="text/css">

canvas {
border:1px solid steelblue;
background-color: whitesmoke;
}

</style>
<body>
<canvas id="canvas" width=300 height=300></canvas>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
$(function() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");

var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

var drawing = false;
var mouseX = 0;
var mouseY = 0;


function handleMouseDown(e) {
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
drawing= true;
}

function handleMouseUp(e) {
drawing = false;
}
function handleMouseMove(e) {
if(drawing){
mouseeX = parseInt(e.clientX - offsetX);
mouseeY = parseInt(e.clientY - offsetY);
$("#movelog").html("Move: " + mouseX + " / " + mouseY);

var ctx = canvas.getContext("2d");
// some cleanup code
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.beginPath();
ctx.moveTo(mouseX,mouseY);
ctx.lineTo(mouseeX,mouseeY);
ctx.stroke();
}
}

$("#canvas").mousedown(function(e) {
handleMouseDown(e);
});
$("#canvas").mousemove(function(e) {
handleMouseMove(e);
});
$("#canvas").mouseup(function(e) {
handleMouseUp(e);
});

});
</script>
</body>
</html>

我想我应该为 mouseDown、mouseMove 和 mouseUp 事件创建可观察对象。

    var mouseDown = Rx.Observable.fromEvent(canvas, 'mousedown');
var mouseMove = Rx.Observable.fromEvent(canvas, 'mousemove');
var mouseUp = Rx.Observable.fromEvent(canvas, 'mouseup');

但我不知道如何组合它们。我认为应该开始观察 mousedown,然后收集所有移动,直到 mouseup 被抬起,并在同时重新绘制从起点到鼠标在 mousemove 期间的当前点的线。你有什么想法?多谢。

°°°°°°°°°°°°°°°°°°°°°°°°°编辑°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°° °°°°°°°°°°°°°

这是布兰登回答后我的代码:

              $(function() {

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext("2d");
var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;

var mouseDown = Rx.Observable.fromEvent($("#canvas"), 'mousedown');
var mouseMove = Rx.Observable.fromEvent($("#canvas"), 'mousemove');
var mouseUp = Rx.Observable.fromEvent($("#canvas"), 'mouseup');

// keep a reference to the pisition when the mouse down was fired
// then flatten the stream with concatAll


var traceLineStream = mouseDown.map(function(md) {
var movesFromMouseDown = mouseMove.takeUntil(mouseUp);
var movesFromMouseDownAndMouseDown = movesFromMouseDown.map(function(mm) {
return {
mouseDownPoint: md,
mouseMovePoint: mm
}
});
return movesFromMouseDownAndMouseDown;
}).concatAll();


var subscription = traceLineStream.subscribe(
function(y) {

var mouseDown = y.mouseDownPoint;
var mouseMove = y.mouseMovePoint;

var mouseDownX = parseInt(mouseDown.clientX - offsetX);
var mouseDownY = parseInt(mouseDown.clientY - offsetY);

var mouseMoveX = parseInt(mouseMove.clientX - offsetX);
var mouseMoveY = parseInt(mouseMove.clientY - offsetY);

ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.restore();
ctx.beginPath();
ctx.moveTo(mouseDownX, mouseDownY);
ctx.lineTo(mouseMoveX, mouseMoveY);
ctx.stroke();

},
function(e) {
console.log('onError: ' + e.message);
},
function() {
console.log('onCompleted');
});
});

最佳答案

首先,组合流,这样您就有了代表单个拖动的事件流。

var drag = mouseDown.first().concat(mouseMove.takeUntil(mouseUp));

接下来,将此事件流投影到 previous,current 元组流中。

var moves = drag
.scan({}, function(acc, x) {
return { previous: acc.current, current: x };
})
.skip(1);

现在我们有一个只在第一次工作的流。当它结束时,我们要开始监听下一个拖动:

var allMoves = moves.repeat();

最后,订阅:

allMoves.subscribe(function (move) {
var mouseX = move.previous.clientX - offsetX,
mouseY = move.previous.clientY - offsetY,
mouseeX = move.current.clientX - offsetX,
mouseeY = move.current.clientY - offsetY,
...
});

在没有所有中间变量的情况下将它们放在一起:

mouseDown
.first()
.concat(mouseMove.takeUntil(mouseUp))
.scan({}, function(acc, x) {
return { previous: acc.current, current: x };
})
.skip(1)
.repeat()
.subscribe(function (move) {
var mouseX = move.previous.clientX - offsetX,
mouseY = move.previous.clientY - offsetY,
mouseeX = move.current.clientX - offsetX,
mouseeY = move.current.clientY - offsetY,
...
});

关于javascript - RXJS 在 html5 Canvas 上画线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22225810/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com