我写了一个小程序,你可以在其中加载图像,在点击,拖动或触摸移动时选择鼠标/手指位置的颜色。
如果我在图像上拖动鼠标(canvas
),颜色数据将通过node.js
不断传输到socket.io
服务器。在每个连接的客户端上,颜色会立即更新。
请参阅video。
但是,如果我在平板电脑上触摸移动,颜色数据将不会持续传输。 我不知道如何解决这个问题。 你有什么想法吗?
查看Github上的项目。
app.js(服务器)
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
// include external data, eg. css, images (public folder)
app.use(express.static(__dirname + '/public'));
// By typing localhost:3000 the browser will load index.html
app.get('/', function (req, res) {
res.redirect('/html/index.html'); // alternative: res.sendfile('./public/html/index.html');
});
// Put the application on port 3000
http.listen(3000, function () {
console.log('listening on port 3000');
});
var currentColor = "000000";
io.on('connection', function (socket) {
// Light Control
socket.emit('updateCurrentColor', currentColor);
socket.on('farbe_ClientToServer', function (data) {
currentColor = data;
io.emit('updateCurrentColor', currentColor);
});
socket.on('test',function(data){
console.log(data);
});
});
index.html(浏览器)
<!DOCTYPE HTML>
<html>
<head>
<title> Color Sync </title>
<link rel="shortcut icon" href="../img/favicon.ico">
<script src="../js/jquery-1.11.1.js"></script>
<script src="/socket.io/socket.io.js"></script>
<style>
#canvas, body {
background-color: #000000;
}
#field {
background-color: white;
}
</style>
</head>
<body>
<div id="field">
<div id="touchX">touchX</div>
<div id="touchY">touchY</div>
<div id="color">color</div>
</div>
<canvas id="canvas"></canvas>
</body>
<script type="text/javascript">
var socket = io();
//synchronice current color on every device with information from server
socket.on('updateCurrentColor', function (currentColor) {
$('#canvas').css("background-color", "#" + currentColor);
$('body').css("background-color", "#" + currentColor);
});
// setup image on canvas
var margin = 50;
var leftMButtonDown = false;
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var img = new Image();
img.src = "../img/farbrad.png";
img.onload = function () {
context.canvas.width = img.width; // apply correct side proportions
context.canvas.height = img.height;
resize();
};
window.addEventListener('resize', function () {
resize();
});
/**
* Scale proportionally: If the width of the canvas > the height, the canvas height
* equals the height of the browser window. Else, the canvas width equals the width of the browser window.
* If the window is resized, the size of the canvas changes dynamically.
*/
function resize() {
var ratio = canvas.width / canvas.height;
var canvas_height = window.innerHeight;
var canvas_width = canvas_height * ratio;
if (canvas_width > window.innerWidth) {
canvas_width = window.innerWidth;
canvas_height = canvas_width / ratio;
}
canvas.width = canvas_width - 2 * margin; // resize canvas
canvas.height = canvas_height - 2 * margin;
context.drawImage(img, 0, 0, canvas.width, canvas.height); // resize image on the canvas
}
// checks if the left mouse button is pressed
$("#canvas").mousedown(function () {
leftMButtonDown = true;
});
$("#canvas").mouseup(function () {
leftMButtonDown = false;
});
// get the color at the mouse position on mouse move, but only if the left mouse button is pressed
$('#canvas').mousemove(function (e) {
if (leftMButtonDown == true) {
getColorAtPos(e.pageX, e.pageY);
}
});
// get the color at mouse position on click
$('#canvas').click(function (e) {
getColorAtPos(e.pageX, e.pageY);
});
// implement touch gesture
$('#canvas').on("touchmove", function (ev) {
var e = ev.originalEvent;
e.preventDefault();
getColorAtPos(e.targetTouches[0].pageX, e.targetTouches[0].pageY);
});
// get canvas position and color at this position (mouse/touch)
function getColorAtPos(pageX, pageY) {
var canvasTopLeft = {
x: canvas.offsetLeft,
y: canvas.offsetTop
}
var x = pageX - canvasTopLeft.x;
var y = pageY - canvasTopLeft.y;
$('#touchX').text('canvasX: ' + x);
$('#touchY').text('canvasY: ' + y);
var c = canvas.getContext('2d');
var p = c.getImageData(x, y, 1, 1).data;
var currentColor = ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
// distribute color information
$('#color').text('color: ' + currentColor);
$('#canvas').css("background-color", "#" + currentColor);
$('body').css("background-color", "#" + currentColor);
//@todo: Touchmove position does not get updated constantly! why?
socket.emit('farbe_ClientToServer', currentColor); // send to server
socket.emit('test', currentColor); // watch console in Terminal
}
function rgbToHex(r, g, b) {
return componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
// get border around canvas
$('#canvas').css('margin', margin);
</script>
</html>
答案 0 :(得分:0)
疯狂猜测,但您应该在getColorAtPos
中减少工作量。每次touchmove
触发时,您至少会遍历DOM五次(这很多)。缓存你的元素,批量你的DOM读写等。另外,你可能想要限制你的touchmove
处理程序。我不知道它会以什么速度发射,但我敢打赌它可以压倒移动设备。