Touchmove数据不会持续传输到Node.js

时间:2015-12-10 22:17:51

标签: javascript node.js canvas socket.io touchmove

我写了一个小程序,你可以在其中加载图像,在点击,拖动或触摸移动时选择鼠标/手指位置的颜色。 如果我在图像上拖动鼠标(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>

1 个答案:

答案 0 :(得分:0)

疯狂猜测,但您应该在getColorAtPos中减少工作量。每次touchmove触发时,您至少会遍历DOM五次(这很多)。缓存你的元素,批量你的DOM读写等。另外,你可能想要限制你的touchmove处理程序。我不知道它会以什么速度发射,但我敢打赌它可以压倒移动设备。