互動式網頁app 切換ppt
看到數學老師邊放投影片便走路演講遇到突然要寫字怎麼辦?。
透過node.js架設伺服器,掃描qrcode 進行認證進而切換ppt即時繪圖 node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node.js
pdf.js
pdf.worker.js
用手機控制pdf切換 即時繪圖bug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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;
}
});
});
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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>
<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>
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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>
看到數學老師邊放投影片便走路演講遇到突然要寫字怎麼辦?。
透過node.js架設伺服器,掃描qrcode 進行認證進而切換ppt即時繪圖 node.js
透過node.js架設伺服器,掃描qrcode 進行認證進而切換ppt即時繪圖 node.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
node.js | |
pdf.js | |
pdf.worker.js | |
用手機控制pdf切換 即時繪圖bug |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> | |
| |
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |