互動式網頁app 切換ppt

看到數學老師邊放投影片便走路演講遇到突然要寫字怎麼辦?。 透過node.js架設伺服器,掃描qrcode 進行認證進而切換ppt即時繪圖 node.js

readme

code
node.js
pdf.js
pdf.worker.js
用手機控制pdf切換 即時繪圖bug

test.js #nodejs

code
var express = require('express'),
    app = express(),
    http = require('http'),
    server = http.createServer(app),
    io = require('socket.io').listen(server);
      fs = require('fs'), 
server.listen(8081);
console.log('Server running');

app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});
function handler(request, response) { 
        fs.readFile('./eboard.html', function(err, data) { 
                if (err) 
                { 
                        response.writeHead(500, {'Content-Type':'text/plain'}); 
                        return response.end('Error loading msg.html'); 
                } 
                response.writeHead(200); 
                response.end(data); 
        }); 
}

// 連線
io.sockets.on('connection', function (socket) {


       //登入初始化 
        socket.on('login', function(data) 
        { 
                //伺服端訊息 
                console.log("connected"); 

                //宣告物件,放置訊息 
                var obj = new Object; 
                obj.name = data.name; 
                obj.msg = data.name + ' 已上線'; 

                //將在前端輸入的名稱記錄下來 
                socket.name = data.name; 

                //將自己上線訊息傳給自己的網頁 
                socket.emit('msg', obj); 

                //告訴其他人你上線了 
                socket.broadcast.emit('msg', obj); 
        }); 

        //接受畫布作業訊息 
        socket.on('draw', function(data){ 
                //將畫布作業訊息傳給其他線上的人 
                socket.broadcast.emit('show', data); 
        });

        //離線 
        socket.on('disconnect', function() { 
                //宣告物件,放置訊息 
                var obj = new Object; 
                obj.msg = socket.name + ' 已離開'; 

                //通知所有人自己已經離開 
                io.sockets.emit('msg', obj); 
        }); 
         // 偵聽 send 事件
    socket.on('send', function (data) {

        // 然後我們依據 data.act 做不同的動作
        switch ( data.act )
        {
            // 這個是使用者打開手機網頁後發生的事件
            case 'enter':
            io.sockets.emit('get_response', data);
            console.log('Sending getEnter');
            break;

            // 這個是使用者在手機網頁中點擊按鈕,讓電腦網頁背景變色的事件
            case 'changebg':
            io.sockets.emit('get_response', data);
            console.log('Sending changeBg');
            break;

                        // 這個是使用者在手機網頁中點擊按鈕,讓電腦網頁背景變色的事件
            case 'changebg2':
            io.sockets.emit('get_response', data);
            console.log('Sending changeBg2');
            break;
        }

    });


});

tmp.html

code
<!document html>
<html>
    <head>

        <meta charset="utf-8">
        <title>Nodejs - 電腦網頁</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script src="http://192.168.5.73:8081/socket.io/socket.io.js" type="text/javascript"></script>
        <script src="../../build/pdf.js"></script>
        <style type="text/css">
            #main {
                display: none;
            }
        </style>
        <script type="text/javascript">
            // 用來產生類似 GUID 的字串
            function S4() {
               return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
            }

            function NewGuid() {
               return (S4()+S4());
            }

            $(document).ready(function(){

                var key = NewGuid();
                console.log(key);

                $("#qrcode").append("<img src='http://chart.apis.google.com/chart?chs=300x300&cht=qr&chl=http://192.168.5.73/dashboard/work2/tmp2.php?key=" + key + "&choe=UTF-8' />");

                // NodeJS Server
                var nodejs_server = "192.168.5.73:8081";

                // 進行 connect
                var socket = io.connect("http://" + nodejs_server);

                // 偵聽 nodejs 事件
                socket.on("get_response", function (b) {

                    var combine = b.key + "_" + b.act;
                    console.log(combine);

                    switch (combine) {

                        // 當擁有特定 KEY 的使用者打開手機版網頁,觸發 enter 事件,就會將 qrcode 隱藏,並秀出一張圖
                        case key + "_enter":
                            setTimeout(function () {

                                $("#qrcode").hide();
                                $("#main").show();

                            }, 500);
                            break;

                        // 當擁有特定 KEY 的使用者在手機版網頁中,觸發 changebg 事件,就會將網頁的背景顏色隨機變換
                        case key + "_changebg":
                            setTimeout(function () {

                                var str = "0123456789abcdef", t = "";
                                for (j = 0; j < 6; j++) {
                                    t = t + str.charAt(Math.random() * str.length);
                                }

                                $("body").css("background-color", t);
                                 $('#next').get(0).click();


                            }, 500);
                            break;

                    }
                });

            });
        </script>

<script id="script">
  //
  // If absolute URL from the remote server is provided, configure the CORS
  // header on that server.
  //
  var url = 'compressed.tracemonkey-pldi-09.pdf';
  //
  // Disable workers to avoid yet another cross-origin issue (workers need
  // the URL of the script to be loaded, and dynamically loading a cross-origin
  // script does not work).
  //
  // PDFJS.disableWorker = true;
  //
  // In cases when the pdf.worker.js is located at the different folder than the
  // pdf.js's one, or the pdf.js is executed via eval(), the workerSrc property
  // shall be specified.
  //
  // PDFJS.workerSrc = '../../node_modules/pdfjs-dist/build/pdf.worker.js';
  var pdfDoc = null,
      pageNum = 1,
      pageRendering = false,
      pageNumPending = null,
      scale = 0.8,
      canvas = document.getElementById('the-canvas'),
      ctx = canvas.getContext('2d');
  /**
   * Get page info from document, resize canvas accordingly, and render page.
   * @param num Page number.
   */
  function renderPage(num) {
    pageRendering = true;
    // Using promise to fetch the page
    pdfDoc.getPage(num).then(function(page) {
      var viewport = page.getViewport(scale);
      canvas.height = viewport.height;
      canvas.width = viewport.width;
      // Render PDF page into canvas context
      var renderContext = {
        canvasContext: ctx,
        viewport: viewport
      };
      var renderTask = page.render(renderContext);
      // Wait for rendering to finish
      renderTask.promise.then(function () {
        pageRendering = false;
        if (pageNumPending !== null) {
          // New page rendering is pending
          renderPage(pageNumPending);
          pageNumPending = null;
        }
      });
    });
    // Update page counters
    document.getElementById('page_num').textContent = pageNum;
  }
  /**
   * If another page rendering in progress, waits until the rendering is
   * finised. Otherwise, executes rendering immediately.
   */
  function queueRenderPage(num) {
    if (pageRendering) {
      pageNumPending = num;
    } else {
      renderPage(num);
    }
  }
  /**
   * Displays previous page.
   */
  function onPrevPage() {
    if (pageNum <= 1) {
      return;
    }
    pageNum--;
    queueRenderPage(pageNum);
  }
  document.getElementById('prev').addEventListener('click', onPrevPage);
  /**
   * Displays next page.
   */
  function onNextPage() {
    if (pageNum >= pdfDoc.numPages) {
      return;
    }
    pageNum++;
    queueRenderPage(pageNum);
  }
  document.getElementById('next').addEventListener('click', onNextPage);
  /**
   * Asynchronously downloads PDF.
   */
  PDFJS.getDocument(url).then(function (pdfDoc_) {
    pdfDoc = pdfDoc_;
    document.getElementById('page_count').textContent = pdfDoc.numPages;
    // Initial/first page rendering
    renderPage(pageNum);
  });
</script>
    </head>
<body>

        <div id="qrcode"></div>
        <div id="main">


                <div>
  <button id="prev">Previous</button>
  <button id="next">Next</button>
  &nbsp; &nbsp;
  <span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
</div>

  <div>
  <canvas id="the-canvas" style="border:1px solid black"></canvas>
</div>
        </div>

</body>
</html>

tmp2.php

code
<!DOCTYPE html>

<html>
<head>
    <meta charset="UTF-8" />
    <title>Nodejs -  手機網頁</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <meta name="author" content="patw, Patrick Wang" />
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script src="http://192.168.5.73:8081/socket.io/socket.io.js" type="text/javascript"></script>
        <script src="../build/pdf.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {

        // ==========================================================================================================================
        // 建立 Socket IO 連線
        // ==========================================================================================================================
        var socket = io.connect("http://192.168.5.73:8081");
        "undefined" != typeof console && console.log("user enter via mobile");
        // ==========================================================================================================================

        "undefined" != typeof console && console.log("enter mobile page");
        socket.emit("send", {
            key: "<?php echo $_GET['key'];?>",
            act: "enter"
        });

        $("#change_btn").click(function(){
            "undefined" != typeof console && console.log("send change color command");
            socket.emit("send", {
                key: "<?php echo $_GET['key'];?>",
                act: "changebg"
            });
        });
                $("#change_btn2").click(function(){
            "undefined" != typeof console && console.log("send change color command");
            socket.emit("send", {
                key: "<?php echo $_GET['key'];?>",
                act: "changebg2"
            });
        });


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

<p>打開手機網頁成功!快看看你的電腦螢幕吧!</p>

<input id="change_btn" type="button" value="控制電腦端變背景色" />
<input id="change_btn2" type="button" value="控制電腦端變背景色" />
  <div>
  <canvas id="the-canvas" style="border:1px solid black"></canvas>
</div>
</body>
</html>
<script> 
$(document).ready(function() { 
        /* socket.io 相關設定 */ 

        //連線位置與初始化 
        var socket = io.connect("http://192.168.5.73:8081");

        //連線作業 
        socket.on('connect', function() { 
                //宣告物件,放置訊息 
                var obj = new Object; 
                obj.name = prompt('尊姓大名?'); 

                //將輸入名稱傳到後端 node.js server 來通知其他人您已上線的訊息 
                socket.emit('login', obj); 
        }); 

        //上線通知 
        socket.on('msg', function(data){ 
                $('#member_msg').append('<div>' + data.msg + '</div>'); 
        }); 

        //別人畫布上的動作,呈現在我們自己的頁面上 
        socket.on('show', function(data){ 
                //設定筆尖大小 
                $('#size').val( data.size ); 
                ctx.lineWidth = data.size; 

                //繪圖 
                ctx.beginPath();  
        ctx.moveTo(data.x, data.y);  
        ctx.lineTo(data.new_x, data.new_y);  
        ctx.closePath();  
        ctx.stroke(); 
        }); 



        /* 繪圖相關設定 */ 
        //宣告 canvas 元素 
        var c = document.getElementsByTagName('canvas')[0]; 

        //設定 canvas 寬與高 
        c.width  = 648; 
        c.height = 770; 

        //判斷畫布是否有動作的布林變數 
        var drawing = false; 

        //canvas 元素本身沒有畫作能力,僅為圖形容器,需要使用 javascript 來操作畫布 
        //我們須要透過 getContext() 來取得一個提供在 canvas 上畫圖的方法與屬性之「物件」 
    var ctx = c.getContext('2d'); 

        //繪圖物件初始設定 
    ctx.lineCap = 'round'; 
    ctx.lineJoin = 'round'; 
    ctx.strokeStyle = '#000000'; 
    ctx.lineWidth = 1; 

    //座標相關變數 
    var offset, x, y, new_x, new_y; 

    //滑鼠在畫布按下時的事件處理 
    $(document).on('mousedown', '#the-canvas', function(e){ 
            e.preventDefault(); 

            //打開可供畫圖的機制 
        drawing = true; 

            //計算相對的畫布範圍(這很重要) 
            offset = $(e.currentTarget).offset(); 
        x = e.pageX - offset.left;  
        y = e.pageY - offset.top; 
        drawLine(x, y, x+1, y+1); 
    }); 

    //滑鼠在畫布上按下左右時,移動的情況 
    $(document).on('mousemove', '#the-canvas', function(e){ 
            e.preventDefault(); 

            //是否開啟畫圖機制 
            if( drawing ) 
            { 
                    //計算移動後的新座標,再進行畫圖作業 
                new_x = e.pageX - offset.left; 
                new_y = e.pageY - offset.top; 
                drawLine(x, y, new_x, new_y); 
                x = new_x; 
                y = new_y; 
            } 
    }); 

    //放開滑鼠鍵 
    $(document).on('mouseup', '#the-canvas', function(e){ 
            e.preventDefault(); 

            //關閉繪圖機制 
            drawing = false; 
    }); 

    //選擇筆尖大小 
        $(document).on('change', '#size', function(e){ 
                ctx.lineWidth = $(this).val(); 
        }); 

        //畫圖,並將繪畫座標傳給網頁上的其他使用者 
    function drawLine(x, y, new_x, new_y) 
    {  
                //繪圖 
        ctx.beginPath();  
        ctx.moveTo(x, y);  
        ctx.lineTo(new_x, new_y);  
        ctx.closePath();  
        ctx.stroke(); 

        //將繪畫座標透過 node.js 傳給使用者 
        var obj = new Object; 
        obj.x = x; 
        obj.y = y; 
        obj.new_x = new_x; 
        obj.new_y = new_y; 
        obj.size = $('#size').val(); 
        socket.emit('draw', obj); 
    }

}); 
</script>