将图像拖放到画布中 [英] Drag and Drop Images into Canvas

查看:197
本文介绍了将图像拖放到画布中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将在画布之外生成的图像拖动到画布中,画出一些线条和形状,然后移出画布。我使用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.336],[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 ++){
//每个可移动触摸事件:
if(e.touches [i] .target.className ==movable){
var id = e。 touches [i] .identifier;

//在移动散列中记录初始数据
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){

//移动到前面
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();

//将旋转/缩放模式重置为关闭
move [id] .rotateScaleMode = false;
// ***
updateTransform(moving [id] .target);
// ***
}
//}
} else if(e.type ===touchmove){
//如果有两个触摸和两个都在*相同*元素,我们在旋转/缩放模式
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(moving [idA] .rotateScaleMode&& moving [idB] .rotateScaleMode){
//计算平移,旋转和缩放
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(move [idA] .target);
} else {
//将rotate / scale模式设置为on
move [idA] .rotateScaleMode = moving [idB] .rotateScaleMode = true;
//记录初始旋转/缩放模式数据
move [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,
}
移动[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(窗口中的ontouchstart){
for(var i = 0; i < e.touches.length; i ++){
// var i = e.touches.length - 1;
var id = e.touches [i] .identifier;

//每个触摸事件:
if(moving [id]){
//将旋转/缩放模式重置为关闭
移动[id] .rotateScaleMode = false;
//计算翻译,离开旋转和缩放
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;

//每个触摸事件:
if(moving [id]){
//将旋转/缩放模式重置为关闭
移动[id] .rotateScaleMode = false;
//计算翻译,离开旋转和缩放
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每个从移动散列
for(var i = 0; 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();
}

函数jsonFlickrApi(data)
{
if(isLocal){
var loc = getLocalURI();
data = JSON.parse(data);
}
for(var i = 0; 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事件监听器
document.addEventListener(touchstart,touchHandler,false);
document.addEventListener(touchmove,touchHandler,false);
document.addEventListener(touchend,touchHandler,false);
document.addEventListener(touchcancel,touchHandler,false);

//从Flickr获取10个最新的有趣的图像
var flickrApiCall = document.createElement(script);
document.body.appendChild(flickrApiCall);

//将isLocal变量设置为boolean true或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';
}
}

函数log(message){
console.log(message);
}

//由Chad添加以执行本地映像
function getParameterByName(name){
var match = RegExp('[?&]'+ name +'=([^&] *)')。exec(window.location.search);
return match&&& decoderURIComponent(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} .jpg}]}}';
}

function getLocalURI(){
//构造本地映像位置
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')。 $ b 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 ('active');
$('''''');
$('。nav li')。 '.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();
});
// large
$('#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 '活性');
}

// =================================== =

//这个演示依赖于canvas元素
if(!document.createElement('canvas')中的'getContext')){
alert它看起来像你的浏览器不支持canvas!
return false;
}

//您的Web服务器的URL(端口在app.js中设置)
// var url ='http://192.168.0.113:8080 ';

var doc = $(document),
win = $(window),
canvas = $('#paper'),
ctx = canvas ] .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);

//生成唯一ID
var id = Math.round($。now()* Math.random());

//绘制活动的标志
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
}

//为当前用户的移动绘制一行,因为它是
//未在socket.on('moving')事件中接收到$ b $以上的事件b
if(drawing){
drawLine(prev.x,prev.y,ex,ey,curColor,curSize,mode);
if(mode ==free){
prev.x = ex;
prev.y = ey;
}
}
});
}

//在不活动10秒后删除非活动客户端
setInterval(function(){

for(ident in clients){
if($。now() - clients [ident] .updated> 200){
cursors [ident] .remove();
delete clients [ident];
删除游标[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;

//自由行
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);
}

//直线
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);

}

函数drawEllipse(ctx,x,y,w,h){
var kappa = .5522848,
ox = 2)* kappa,//控制点偏移水平
oy =(h / 2)* kappa,//控制点偏移垂直
xe = x + w,// x-end
ye = y + h,// y-end
xm = x + w / 2,// x-middle
ym = y + h / // 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); //用白色填充画布

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');
}


解决方案

/ p>


  • 在画布上拖曳img元素的副本,使其像素成为画布内容的一部分

    >
  • 在画布上绘制一些线条


  • 将img像素(使用涂鸦)导出为一个新的img元素






演示 http://jsfiddle.net/m1erickson/83o87v32/



这里有一个简单的方法: / strong>




  • 将jQuery的拖放功能添加到图片源工具箱中的每个img元素。

    / li>
  • 使用以下形式将图像像素绘制到画布像素上: context.drawImage


  • 在包含图片的画布像素上涂鸦。


  • 从图片像素加上乱写像素到新的img元素。




注释代码示例

 <!doctype html> 
< html>
< head>
< link rel =stylesheettype =text / cssmedia =allhref =css / reset.css/> <! - reset css - >
< script type =text / javascriptsrc =http://code.jquery.com/jquery.min.js>< / script>
< script src =http://code.jquery.com/ui/1.9.2/jquery-ui.min.js>< / script>
< style>
body {background-color:ivory; }
canvas {border:1px solid red;}
#exportedImgs {border:1px solid green; padding:15px; width:300px; height:70px;}
#toolbar {
width:350px;
height:35px;
border:solid 1px blue;
}
< / style>
< script>
$(function(){

//获取对画布及其上下文的引用
var canvas = document.getElementById(canvas);
var ctx = canvas.getContext(2d);

//获取画布的偏移位置
var $ canvas = $(#canvas);
var Offset = $ canvas.offset();
var offsetX = Offset.left;
var offsetY = Offset.top;

var x,y,width,height;

//选择所有.tool的
var $ tools = $(。tool);


//使所有.tool的draggable
$ tools.draggable({
helper:'clone',
});


//为每个工具分配它的索引$ tools
$ tools.each(function(index,element){
$(this).data(toolsIndex,index);
});


使画布成为一个dropzone
$ canvas.droppable({
drop:dragDrop,
});


//处理画布
function dragDrop(e,ui){

//获取放置点(务必调整边框)
x = parseInt(ui.offset.left-offsetX) 1;
y = parseInt(ui.offset.top-offsetY);
width = ui.helper [0] .width;
height = ui.helper [0] .height;

//获取下载有效负载(这里的有效负载是$ tools索引)
var theIndex = ui.draggable.data(toolsIndex);

//使用drop图像在drop point处绘制图像
//这将使img成为画布内容的一个永久部分
ctx.drawImage($ tools [theIndex] ,x,y,width,height);

}


//只是测试:在删除的img像素上涂抹一些行
//在你的应用程序中,你可以任何你想要的方式
$('#scribble')。click(function(){
ctx.beginPath();
ctx.moveTo(x-20,y-20);
ctx .lineTo(x + 10,y + height + 5);
ctx.lineTo(x + 20,y-20);
ctx.lineTo(x + width,y + height + 5);
ctx.stroke();
console.log('scribble',x,y,width,height);
});

//导出img像素加上乱写像素
//(1)将所需的像素绘制到临时画布上
//(2)创建一个新的img元素临时画布的数据url
//(3)将这个新的img添加到#exportedImgs div
$('#export')click(function(){
var tempCanvas = document.createElement ('canvas');
var tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = width;
tempCanvas.height = height;
tempCtx.drawImage canvas,x,y,width,height,0,0,width,height);
var img = new Image();
img.onload = function(){
$ #exportedImgs')。append(img);
};
img.src = tempCanvas.toDataURL();
});

}); // end $(function(){});
< / script>
< / head>
< body>
< p>从蓝色工具栏拖到红色画布< br>然后按下< / p>下方的操作按钮
< div id =toolbar>
< img class =toolwidth = 32 height = 32 src =https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpgcrossOrigin ='anonymous'>
< img class =toolwidth = 32 height = 32 src =https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-2.jpgcrossOrigin ='anonymous'>
< img class =toolwidth = 32 height = 32 src =https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpgcrossOrigin ='anonymous'>
< img class =toolwidth = 32 height = 32 src =https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpgcrossOrigin ='anonymous'>
< / div>< br>
< canvas id =canvaswidth = 350 height = 150>< / canvas>< br>
< button id = scribble>在画布上模拟绘图< / button>
< button id = export>导出到img元素< / button>
< p>导出的图片将被放入此绿色Div< / p>
< div id = exportedImgs>
< / div>
< / body>
< / html>


I want to drag the images generated outside canvas into the canvas draw some lines and shapes and move out than out of canvas. I used touchstart/touchmove functions to track the images being dragged but when i move them over canvas, i can place them in canvas and draw does not effect any image than. Below are the scripts for generating images and creating paint canvas respectively.

Code for image script.

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;
}

Code for paintbar script.

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');
}

解决方案

Here's one way to:

  • Drag a copy of an img element on top of canvas make its pixels part of the canvas content

  • Scribble some lines on the canvas

  • Export the img pixels (with scribbles) into a new img element

A Demo: http://jsfiddle.net/m1erickson/83o87v32/

Here's an outline of one way to do it:

  • Add jQuery's drag/drop capabilities to each img element in your source toolbox of images.

  • Draw the image pixels onto the canvas pixels using: context.drawImage

  • Scribble over the canvas pixels containing the image.

  • Export from the canvas the image pixels plus the scribble pixels to a new img element.

Example annotated code:

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>
<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
    #exportedImgs{border:1px solid green; padding:15px; width:300px; height:70px;}
    #toolbar{
      width:350px;
      height:35px;
      border:solid 1px blue;
    }
</style>
<script>
$(function(){

    // get references to the canvas and its context
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    // get the offset position of the canvas
    var $canvas=$("#canvas");
    var Offset=$canvas.offset();
    var offsetX=Offset.left;
    var offsetY=Offset.top;

    var x,y,width,height;

    // select all .tool's
    var $tools=$(".tool");


    // make all .tool's draggable
    $tools.draggable({
            helper:'clone',
    });


    // assign each .tool its index in $tools
    $tools.each(function(index,element){
        $(this).data("toolsIndex",index);
    });


    // make the canvas a dropzone
    $canvas.droppable({
        drop:dragDrop,
    });


    // handle a drop into the canvas
    function dragDrop(e,ui){

        // get the drop point (be sure to adjust for border)
        x=parseInt(ui.offset.left-offsetX)-1;
        y=parseInt(ui.offset.top-offsetY);
        width=ui.helper[0].width;
        height=ui.helper[0].height;

        // get the drop payload (here the payload is the $tools index)
        var theIndex=ui.draggable.data("toolsIndex");

        // drawImage at the drop point using the dropped image 
        // This will make the img a permanent part of the canvas content
        ctx.drawImage($tools[theIndex],x,y,width,height);

    }


    // Just testing: Scribble some lines over the dropped img pixels
    // In your app you can scribble any way you desire
    $('#scribble').click(function(){
        ctx.beginPath();
        ctx.moveTo(x-20,y-20);
        ctx.lineTo(x+10,y+height+5);
        ctx.lineTo(x+20,y-20);
        ctx.lineTo(x+width,y+height+5);
        ctx.stroke();
        console.log('scribble',x,y,width,height);
    });

    // export the img pixels plus the scribble pixels
    // (1) Draw the desired pixels onto a temporary canvas
    // (2) Create a new img element from the temp canvas's dataURL
    // (3) Append that new img to the #exportedImgs div
    $('#export').click(function(){
        var tempCanvas=document.createElement('canvas');
        var tempCtx=tempCanvas.getContext('2d');
        tempCanvas.width=width;
        tempCanvas.height=height;
        tempCtx.drawImage(canvas,x,y,width,height,0,0,width,height);
        var img=new Image();
        img.onload=function(){
            $('#exportedImgs').append(img);
        };
        img.src=tempCanvas.toDataURL();
    });

}); // end $(function(){});
</script>
</head>
<body>
    <p>Drag from blue toolbar onto red canvas<br>Then press the action buttons below</p>
    <div id="toolbar">
        <img class="tool" width=32 height=32 src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg" crossOrigin='anonymous'>
        <img class="tool" width=32 height=32 src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-2.jpg" crossOrigin='anonymous'>
        <img class="tool" width=32 height=32 src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg" crossOrigin='anonymous'>
        <img class="tool" width=32 height=32 src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg" crossOrigin='anonymous'>
    </div><br>
    <canvas id="canvas" width=350 height=150></canvas><br>
    <button id=scribble>Simulate drawing on canvas</button>
    <button id=export>Export to img element</button>
    <p>Exported images will be put in this green Div</p>
    <div id=exportedImgs>
    </div>
</body>
</html>

这篇关于将图像拖放到画布中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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