Touchmove数据不会持续传输到Node.js [英] Touchmove data is not transmitted constantly to Node.js

查看:99
本文介绍了Touchmove数据不会持续传输到Node.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了一个小程序,您可以在其中加载图像,在单击,拖动或触摸移动时在鼠标/手指位置选择颜色。
如果在图像( canvas )上拖动鼠标,颜色数据将不断传输到 node.js 服务器通过 socket.io 。在每个连接的客户端上,颜色都会立即更新。

I have written a little program, in which you can load an image, select the color at the mouse / finger position on clicking, dragging or touchmoving. If I drag the mouse on the image (canvas), the color data is transmitted constantly to a node.js server via socket.io. On every connected client, the color gets updated immediately.

请参见视频

但是,如果我在平板电脑上触摸移动,色彩数据将不会不断传输。
我不知道该如何解决。
您有想法吗?

However, if I touch move on a tablet, the color data won´t get transmitted constantly. I have no idea how to fix this. Do you have an idea?

请参见 Github

app.js(服务器)

app.js (Server)

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(浏览器)

index.html (Browser)

<!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>


推荐答案

大胆猜测,但您可能应该减少 getColorAtPos 。每次 touchmove 触发时,您遍历DOM至少五次(很多)。缓存元素,批量读取和写入DOM等。此外,您可能希望限制 touchmove 处理程序。我不知道它以什么速率发射,但我敢打赌它会淹没移动设备。

Wild guess, but you should probably do less work in getColorAtPos. You traverse the DOM at least five times every time touchmove fires (which is A LOT). Cache your elements, batch your DOM reads and writes etc. Also, you might want to throttle your touchmove handler. I don't know at what rate it fires, but I bet it can overwhelm a mobile device.

这篇关于Touchmove数据不会持续传输到Node.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆