我想将生成在画布外部的图像拖入画布中,画出一些线条和形状,然后移出画布。我使用touchstart/touchmove函数来追踪被拖动的图像,但是当我将它们移动到画布上时,我可以将它们放置在画布上,并且绘制不会影响任何图像。以下是分别生成图像和创建画布画布的脚本。将图像拖放到画布
图像脚本代码。
var zIndexCount = 1;
var moving = {};
var imgData = [[620, 166, 2.9, 0.570], [606, 134, 10.4, 0.403], [633, 103, 45.9, 0.396], [618, 110,
-46.5, 0.576], [618, 40, -69.3, 0.550], [694, 84, 18.7, 0.642], [688, 46, 32.2, 0.363], [614, 114, 64.6, 0.437], [627, 59, 63.3, 0.288], [690, 127, 22.2, 0.352]];
function touchHandler(e) {
if (e.type === "touchstart") {
for (var i = 0; i < e.touches.length; i++) {
// for each "movable" touch event:
if (e.touches[i].target.className == "movable") {
var id = e.touches[i].identifier;
// record initial data in the "moving" hash
moving[id] = {
identifier : id,
target : e.touches[i].target,
mouse : {
x : e.touches[i].clientX,
y : e.touches[i].clientY
},
position : {
x : e.touches[i].target.xfmTX,
y : e.touches[i].target.xfmTY
},
rotation : e.touches[i].target.xfmR,
scale : e.touches[i].target.xfmS
};
}
}
if (e.touches[i - 1].target.className === "movable") {
// move to the front
moving[id].target.style.zIndex = ++zIndexCount;
imgId = moving[id].target.id;
action = "frnt";
// imgX = e.touches[i - 1].target.xfmTX;
// imgY = e.touches[i - 1].target.xfmTY;
// handleSend();
// reset rotate/scale mode to off
moving[id].rotateScaleMode = false;
//***
updateTransform(moving[id].target);
//***
}
//}
} else if (e.type === "touchmove") {
// if there are two touches and both are on the *same* element, we're in rotate/scale mode
if (e.touches.length == 2 && e.touches[0].target == e.touches[1].target) {
var idA = e.touches[0].identifier, idB = e.touches[1].identifier;
// if we've previously recorded initial rotate/scale mode data:
if (moving[idA].rotateScaleMode && moving[idB].rotateScaleMode) {
// calculate translation, rotation, and scale
moving[idA].target.xfmTX = ((moving[idA].positionCenter.x - moving[idA].mouseCenter.x) + ((e.touches[0].clientX + e.touches[1].clientX)/2));
moving[idA].target.xfmTY = ((moving[idA].positionCenter.y - moving[idA].mouseCenter.y) + ((e.touches[0].clientY + e.touches[1].clientY)/2));
moving[idA].target.xfmR = moving[idA].rotation + e.rotation;
moving[idA].target.xfmS = moving[idA].scale * e.scale;
action = "move";
imgId = moving[idA].target.id;
imgX = moving[idA].target.xfmTX;
imgY = moving[idA].target.xfmTY;
updateTransform(moving[idA].target);
} else {
// set rotate/scale mode to on
moving[idA].rotateScaleMode = moving[idB].rotateScaleMode = true;
// record initial rotate/scale mode data
moving[idA].mouseCenter = moving[idB].mouseCenter = {
x : (e.touches[0].clientX + e.touches[1].clientX)/2,
y : (e.touches[0].clientY + e.touches[1].clientY)/2,
}
moving[idA].positionCenter = moving[idB].positionCenter = {
x : moving[idA].target.xfmTX,
y : moving[idA].target.xfmTY
}
action = "move";
imgId = moving[idA].target.id;
imgX = moving[idA].target.xfmTX;
imgY = moving[idA].target.xfmTY;
updateTransform(moving[idA].target);
}
} else {
// if it's a touch device
if ("ontouchstart" in window) {
for (var i = 0; i < e.touches.length; i++) {
// var i = e.touches.length - 1;
var id = e.touches[i].identifier;
// for each touch event:
if (moving[id]) {
// reset rotate/scale mode to off
moving[id].rotateScaleMode = false;
// calculate translation, leave rotation and scale alone
moving[id].target.xfmTX = ((moving[id].position.x - moving[id].mouse.x) + e.touches[i].clientX);
moving[id].target.xfmTY = ((moving[id].position.y - moving[id].mouse.y) + e.touches[i].clientY);
imgX = moving[id].target.xfmTX;
imgY = moving[id].target.xfmTY;
action = "move";
updateTransform(moving[id].target);
doubleMove = false;
}
}
} else {
var i = e.touches.length - 1;
var id = e.touches[i].identifier;
// for each touch event:
if (moving[id]) {
// reset rotate/scale mode to off
moving[id].rotateScaleMode = false;
// calculate translation, leave rotation and scale alone
moving[id].target.xfmTX = ((moving[id].position.x - moving[id].mouse.x) + e.touches[i].clientX);
moving[id].target.xfmTY = ((moving[id].position.y - moving[id].mouse.y) + e.touches[i].clientY);
imgX = moving[id].target.xfmTX;
imgY = moving[id].target.xfmTY;
action = "move";
updateTransform(moving[id].target);
}
}
}
} else if (e.type == "touchend" || e.type == "touchcancel") {
// clear each from the "moving" hash
for (var i = 0; i < e.touches.length; i++)
delete moving[e.touches[i].identifier];
}
e.preventDefault();
}
function updateTransform(element) {
element.style['-webkit-transform'] = 'translate(' + element.xfmTX + 'px,' + element.xfmTY + 'px) ' + 'scale(' + element.xfmS + ') ' + 'rotate(' + element.xfmR + 'deg)';
action = (action === undefined) ? "trafo" : action;
imgId = element.id;
imgX = (imgX === undefined) ? element.xfmTX.toString() : imgX;
imgY = (imgY === undefined) ? element.xfmTY.toString() : imgY;
scale = element.xfmS;
rotate = element.xfmR;
handleSend();
}
function jsonFlickrApi(data)
{
if (isLocal) {
var loc = getLocalURI();
data = JSON.parse(data);
}
for (var i = 0; i < data.photos.photo.length; i++) {
var p = data.photos.photo[i], img = document.createElement("img");
if (isLocal == true) {
img.src = loc + p.name;
} else {
img.src = 'img/' + i + '.jpg';
}
img.id = "img" + [i];
img.className = "movable";
img.xfmTX = imgData[i][0];
img.xfmTY = imgData[i][1];
img.xfmR = imgData[i][2];
img.xfmS = imgData[i][3];
img.setAttribute("style", "position: absolute; top: 0px; left: 0px;");
document.body.appendChild(img);
updateTransform(img);
}
}
function init() {
// touch event listeners
document.addEventListener("touchstart", touchHandler, false);
document.addEventListener("touchmove", touchHandler, false);
document.addEventListener("touchend", touchHandler, false);
document.addEventListener("touchcancel", touchHandler, false);
// get the 10 latest "interesting images" from Flickr
var flickrApiCall = document.createElement("script");
document.body.appendChild(flickrApiCall);
// set the isLocal variable to boolean true or false
isLocal = getParameterByName("local") == "true";
if (isLocal) {
jsonFlickrApi(getLocalJSON());
} else {
flickrApiCall.src = 'https://api.flickr.com/services/rest/?method=flickr.interestingness.getList&api_key=856affa07586845de6fcbfb82520aa3e&per_page=' + 10 + '&format=json';
}
}
function log(message) {
console.log(message);
}
// added by Chad to perform local images
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
function getLocalJSON() {
return '{"photos":{"photo":[{"name":"1.jpg"},{"name":"2.jpg"},{"name":"3.jpg"},{"name":"4.jpg"},{"name":"5.jpg"},{"name":"6.jpg"},{"name":"7.jpg"},{"name":"8.jpg"},{"name":"9.jpg"},{"name":"10.jpg"}]}}';
}
function getLocalURI() {
// construct the local image location
var localURI = new URI(document.URL || location.href);
localURI = localURI.toString();
localURI = localURI.substring(0, localURI.lastIndexOf("/") + 1) + "localimages/";
return localURI;
}
paintbar脚本的代码。
var canvasWidth = '500';
var canvasHeight = '400';
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var black = "#000000";
var purple = "#B424F0";
var green = "#97F024";
var yellow = "#F0DA24";
var orange = "#F06C24";
var white = "#ffffff";
var red = "#F02437";
var blue = "#2459F0";
var lightblue = "#24F0E4";
var curColor = black;
var clickColor = new Array();
var sizesmall = 1;
var sizenormal = 3;
var sizelarge = 10;
var sizehuge = 20;
var curSize = sizenormal;
var clickSize = new Array();
var mode = "free";
var prevMode = "free";
var prevColor = "#000000";
var prevSize = 3;
var colorName = "black";
var sizeName = "normal";
var name = '';
$(function(){
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) {
$('#customWidget').hide();
}
$('.colorpicker_submit').live('click',function(){
var colorPicked = $('#selColor').val();
curColor = colorPicked;
prevColor = colorPicked;
});
$('#green').click(function(){
curColor = green;
prevColor = green;
colorName = "green";
updateMode();
});
$('#yellow').click(function(){
curColor = yellow;
prevColor = yellow;
colorName = "yellow";
updateMode();
});
$('#orange').click(function(){
curColor = orange;
prevColor = orange;
colorName = "orange";
updateMode();
});
$('#purple').click(function(){
curColor = purple;
prevColor = purple;
colorName = "purple";
updateMode();
});
$('#lightblue').click(function(){
curColor = lightblue;
prevColor = lightblue;
colorName = "lightblue";
updateMode();
});
$('#black').click(function(){
curColor = black;
prevColor = black;
colorName = "black";
updateMode();
});
//red
$('#red').click(function(){
curColor = red;
prevColor = red;
colorName = "red";
updateMode();
});
$('#blue').click(function(){
curColor = blue;
prevColor = blue;
colorName = "blue";
updateMode();
});
//white
$('#white').click(function(){
curColor = "#ffffff";
prevColor = "#ffffff";
});
//eraser
$('#eraser').click(function(){
curColor = "#ffffff";
prevColor = "#ffffff";
mode="free";
prevMode="free";
$('.nav li').find('a').removeClass('active');
$('.nav li').filter('[id=eraser]').find('a').addClass('active');
$('.nav li').filter('[id='+sizeName+']').find('a').addClass('active');
});
//size=============
//small
$('#small').click(function(){
curSize = sizesmall;
prevSize = sizesmall;
sizeName = "normal";
updateMode();
});
//normal
$('#normal').click(function(){
curSize = sizenormal;
prevSize = sizenormal;
sizeName = "normal";
updateMode();
});
//large
$('#large').click(function(){
curSize = sizelarge;
prevSize = sizelarge;
sizeName = "large";
updateMode();
});
//huge
$('#huge').click(function(){
curSize = sizehuge;
prevSize = sizehuge;
sizeName = "huge";
updateMode();
});
$('#elipse').click(function(){
mode="elipse";
prevMode="elipse";
updateMode();
});
$('#rectangle').click(function(){
mode="rectangle";
prevMode="rectangle";
updateMode();
});
$('#straight').click(function(){
mode="straight";
prevMode="straight";
updateMode();
});
$('#free').click(function(){
curColor = prevColor;
//prevColor = black;
mode="free";
prevMode="free";
updateMode();
});
$('.chatLink').click(function(){
$('.chatBox').toggle();
$('#msg').focus();
});
function updateMode(){
if(curColor=="#ffffff"){
curColor = black;
prevColor = black;
}
$('#mode').html(mode);
$('.nav li').find('a').removeClass('active');
$('.nav li').filter('[id='+mode+']').find('a').addClass('active');
$('.nav li').filter('[id='+sizeName+']').find('a').addClass('active');
$('.nav li:eq(0)').find('.sub li').filter('[id='+colorName+']').find('a').addClass('active');
}
//====================================
// This demo depends on the canvas element
if(!('getContext' in document.createElement('canvas'))){
alert('Sorry, it looks like your browser does not support canvas!');
return false;
}
// The URL of your web server (the port is set in app.js)
//var url = 'http://192.168.0.113:8080';
var doc = $(document),
win = $(window),
canvas = $('#paper'),
ctx = canvas[0].getContext('2d');
$('#paper').attr('width','500');
$('#paper').attr('height','400');
var tmp_canvas = document.createElement('canvas');
var tmp_ctx = tmp_canvas.getContext('2d');
tmp_canvas.id = 'tmp_canvas';
tmp_canvas.width = canvasWidth;
tmp_canvas.height = canvasHeight;
var sketch = document.querySelector('#sketch');
sketch.appendChild(tmp_canvas);
// Generate an unique ID
var id = Math.round($.now()*Math.random());
// A flag for drawing activity
var drawing = false;
var clients = {};
var cursors = {};
var prev = {};
canvas.on('mousedown',function(e){
e.preventDefault();
drawing = true;
mode = prevMode;
curColor = prevColor;
curSize = prevSize;
prev.x = e.pageX;
prev.y = e.pageY;
});
//doc.('mouseup mouseleave',function(){
doc.bind('mouseup mouseleave', function(){
drawing = false;
ctx.drawImage(tmp_canvas, 0, 0);
//tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
});
var lastEmit = $.now();
doc.on('mousemove',function(e){
if($.now() - lastEmit > 30){
lastEmit = $.now();
}
if(drawing){
e.preventDefault();
drawLine(prev.x, prev.y, e.pageX, e.pageY,curColor,curSize,mode,id);
if(mode=="free"){
prev.x = e.pageX;
prev.y = e.pageY;
}
}
});
if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)) || (navigator.userAgent.match(/iPad/i))) {
canvas.on('touchstart',function(e){
e.preventDefault();
var orig = e.originalEvent;
drawing = true;
prev.x = orig.targetTouches[0].pageX;
prev.y = orig.targetTouches[0].pageY;
});
doc.bind('touchend touchcancel',function(e){
drawing = false;
ctx.drawImage(tmp_canvas, 0, 0);
});
var lastEmit = $.now();
doc.on('touchmove',function(e){
//e.preventDefault();
var orig = e.originalEvent;
ex = orig.targetTouches[0].pageX;
ey = orig.targetTouches[0].pageY;
if($.now() - lastEmit > 30){
lastEmit = $.now();
}
// Draw a line for the current user's movement, as it is
// not received in the socket.on('moving') event above
if(drawing){
drawLine(prev.x, prev.y, ex, ey, curColor, curSize, mode);
if(mode=="free"){
prev.x = ex;
prev.y = ey;
}
}
});
}
// Remove inactive clients after 10 seconds of inactivity
setInterval(function(){
for(ident in clients){
if($.now() - clients[ident].updated > 200){
cursors[ident].remove();
delete clients[ident];
delete cursors[ident];
}
}
},350);
function drawLine(clickX, clickY, tox, toy,curColor,curSize,mode,dataId){
tmp_ctx.beginPath();
tmp_ctx.lineCap = "round";
tmp_ctx.lineJoin = "round";
tmp_ctx.fillStyle = "solid";
tmp_ctx.strokeStyle = curColor;
tmp_ctx.lineWidth = curSize;
//free line
if(mode=="free"){
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
tmp_ctx.moveTo(clickX, clickY);
tmp_ctx.lineTo(tox, toy);
//tmp_ctx.closePath();
tmp_ctx.stroke();
ctx.drawImage(tmp_canvas, 0, 0);
}
//straight line
else if(mode=="straight"){
tmp_ctx.clearRect(0, 0, canvasWidth, canvasHeight);
tmp_ctx.moveTo(clickX, clickY);
tmp_ctx.lineTo(tox, toy);
tmp_ctx.closePath();
tmp_ctx.stroke();
}
//rectangle
else if(mode=="rectangle"){
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
var x = Math.min(tox, clickX);
var y = Math.min(toy, clickY);
var width = Math.abs(tox - clickX);
var height = Math.abs(toy - clickY);
tmp_ctx.strokeRect(x, y, width, height);
}
//ellipse
else if(mode=="elipse"){
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
var x = Math.min(tox, clickX);
var y = Math.min(toy, clickY);
var w = Math.abs(tox - clickX);
var h = Math.abs(toy - clickY);
}
drawEllipse(tmp_ctx, x, y, w, h);
}
function drawEllipse(ctx, x, y, w, h) {
var kappa = .5522848,
ox = (w/2) * kappa, // control point offset horizontal
oy = (h/2) * kappa, // control point offset vertical
xe = x + w, // x-end
ye = y + h, // y-end
xm = x + w/2, // x-middle
ym = y + h/2; // y-middle
ctx.beginPath();
ctx.moveTo(x, ym);
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
ctx.closePath();
ctx.stroke();
}
$('#clearCanvas').click(function(){
tmp_ctx.clearRect(0, 0, tmp_canvas.width, tmp_canvas.height);
ctx.clearRect(0, 0, canvasWidth, canvasHeight); // Fill in the canvas with white
ctx.drawImage(tmp_canvas, 0, 0);
curColor = black;
prevColor = black;
updateMode();
});
//=============================
});
//chat ========================
//=============================
$(".btnSend").click(function(e) {
e.preventDefault();
if($("textarea#msg").val()!=""){
$("p#data_recieved").append("<br /><b>" + name + '</b>: ' + $("textarea#msg").val());
divx = document.getElementById('msgLog');
divx.scrollTop = divx.scrollHeight;
}
$("textarea#msg").val('');
});
function keyEnter(e){
if (e.keyCode == 13){
e.preventDefault();
if($("textarea#msg").val()!=""){
$("p#data_recieved").append("<br /><b>" + name + '</b>: ' + $("textarea#msg").val());
divx = document.getElementById('msgLog');
divx.scrollTop = divx.scrollHeight;
}
$("textarea#msg").val('');
}
}
function closePalette(){
$('.sub').removeClass('open');
}
工作示例会去这么远的路.. – myfunkyside 2014-10-27 08:25:31