【发布时间】:2015-10-29 23:40:46
【问题描述】:
在我的项目中,画布元素显示了一个操纵杆。通过鼠标/触摸事件,画布被更新为用户正在移动操纵杆。这工作正常。坐标保存在一个对象中,如下所示:
scope.point = {
x: 0,
y: 0,
};
我已经添加了这个 HTML 来展示给用户:
<span>X:{{point.x.toFixed(2)}} Y:{{point.y.toFixed(2)}}</span>
问题是,当 scope.point.x 和 scope.point.y 的值发生变化时(在鼠标/触摸事件处理程序中),它们不会在 HTML 中得到更新。唯一的解决方案似乎是添加:
scope.$apply()
//or
scope.$digest()
到渲染循环。这确实有效,但看起来不优雅(恕我直言)并且正如预期的那样使性能明显下降。
还有其他解决办法吗?
提前致谢。
PS:虽然我认为这无关紧要,但作为参考,这是事件处理程序代码和渲染循环:
//handles mouse or touch movement on joystick
scope.mouseMove = function(evt) {
if (leftClick == 1) { //check if left mouse button down or touch
// get cursor or touch coordinates, saved in point object.
if (evt.type == 'touchstart' || evt.type == 'touchmove') {
scope.point.x = evt.targetTouches[0].pageX - joystick.offsetLeft;
scope.point.y = evt.targetTouches[0].pageY - joystick.offsetTop;
} else {
scope.point.x = evt.pageX - joystick.offsetLeft - 3;
scope.point.y = evt.pageY - joystick.offsetTop - 3;
};
//make coordinates relative to canvas center
scope.point = GeometrySrv.centerCoord(scope.point, joystick);
//if Directional Lock is ON, enforce
if (scope.lockMode != "fullAnalog") {
scope.point = GeometrySrv.forceDirectionLock(scope.point.x, scope.point.y, scope.lockMode);
};
// force coordinates into maxRadius
if (!GeometrySrv.isInsideCircle(scope.point.x, scope.point.y, maxRadius)) {
scope.point = GeometrySrv.forceIntoCircle(scope.point.x, scope.point.y, maxRadius);
};
//send coordinates back to server (websocket)
updateJoystick(scope.point, scope.lockMode);
};
};
function renderLoop() {
//erases previous joystick position
resetJoystick();
// erases previous vector
resetVector();
//change coordinates to canvas reference
scope.point = GeometrySrv.canvasCoord(scope.point, joystick);
DrawSrv.drawLineFromCenter(joystickctx, scope.point.x, scope.point.y);
if (scope.showVector) {
DrawSrv.drawLineFromCenter(vectorctx, scope.point.x * vector.width / joystick.width, scope.point.y * vector.width / joystick.width);
};
//redraw joystick position
DrawSrv.drawCircle(joystickctx, scope.point.x, scope.point.y, radius, maxRadiusBGColor);
//change back to relative coordinates
scope.point = GeometrySrv.centerCoord(scope.point, joystick);
//scope.$digest();
//call renderLoop every 15ms (60fps)
renderReq = requestAnimationFrame(renderLoop);
};
【问题讨论】:
-
如果事件发生在改变范围的角核心之外,你必须使用
$applystackoverflow.com/a/31756769/1175966 -
感谢您的回答。这是一个明确的“不可能”吗?真可惜,因为操纵杆的性能确实受到影响,特别是在移动设备上添加 $apply 时。如果是这种情况,我想我会删除文本,因为它弊大于利。
标签: javascript angularjs canvas data-binding angularjs-scope