循环中的可拖动对象和画布

时间:2016-01-13 17:51:06

标签: javascript jquery canvas draggable

我有三个问题。第一个问题是最重要的,但我很欣赏能够得到其他问题的答案。

第一个问题,请看这个jsfiddle: https://jsfiddle.net/owLdgrdq/10

//copia nariz
$(document).on('click', '#add-nariz', function(){
    var a = $('#add-nariz');
  var src = a.attr('src');
  var elem = $('<img class="objetos" src="' + src + '" width="30px" height="30px" style="positon: relative;" />');
  $('#fotoAlterada').append(elem);
  elem.draggable();
});
//copia bolinha azul
$(document).on('click', '#add-bb', function(){
    var a = $('#add-bb');
  var src = a.find('img:first').attr('src');
  var elem = $('<img class="objetos" src="' + src + '" width="30px" height="30px" style="positon: relative;" />');
  $('#fotoAlterada').append(elem);
  elem.draggable();
});

$(document).on('click', '#salvaImagem', function(){

  var m = $('#foto');
  var totX = parseInt(m.css('width'));
  var totY = parseInt(m.css('height'));
  var c = document.getElementById('myCanvas');
  c.width = totX;
  c.height = totY;
  var ctx = c.getContext('2d');
  alert(totX + '\n' + totY);

  var base = document.getElementById('foto');
  ctx.drawImage(base,0,0,totX,totY,0,0,totX,totY);

  var posicoes = [];
  $(".objetos").each(function(){
    var img = $(this);
    x = parseInt(img.css("left"))+totX;
    y = parseInt(img.css("top"))+totY;
    altura = parseInt(img.css("width"));
    largura = parseInt(img.css("height"));
    posicoes.push([ 
     x,
     y,
     largura,
     altura
    ]);
  });
  alert( JSON.stringify(posicoes));
  var j;
  var numAderecos = posicoes.length;
  for(j = 0; j < numAderecos; j++){
    ctx.drawImage(base,posicoes[j][0],posicoes[j][1],posicoes[j][2],posicoes[j][3]);
  }

});

我有一些图标(Adicionar isto :)我想要添加到照片(Editar isto :)。当用户点击图标时,会在照片旁边制作副本。更多点击制作更多副本。这些副本是可拖动的。用户选择对象的位置并单击按钮进行保存(“SalvarMudanças”)。此按钮可以复制原始照片,并在其上显示新对象(在画布内)。

在JS代码的最后,我把小照片(与原始相同)作为画布中添加到照片中的小对象,但仅仅因为我不知道如何复制添加的每个对象。我怎么能这样做?

第二个问题,当点击按钮时,画布中的位置不一样,它们会向下拉一点(并且也是左侧)。如果我在CSS代码中添加填充和边距0px,为什么会发生这种情况?

第三个问题,变量'base'我使用$('#foto')来获取id,但我不能在canvas参数中使用它。当我使用document.getElementById('foto')我可以。他们之间有什么区别?

----编辑----

我的目标是通过cordova / phonegap制作移动应用程序。用户必须能够从设备获取图片或使用凸轮拍摄自拍照(已经可以)。当图片/照片被拿到时,窗口上会出现一些新的物体,如皇冠的鼻子,色彩缤纷的帽子和其他愚蠢的东西(没关系,只需更改style =“display:none;”,当用户点击时)这些东西他们在照片的底部制作副本,这些副本必须是可拖动的(这也很好)。然后,使用jQuery-UI,我将所有拖动对象的位置放入照片中,用户单击“SalvarMudanças”按钮(“保存更改”),此操作将照片和对象复制到画布区域(这是我制作应用程序的方式)。之后,用户点击另一个按钮,通过whatsapp,facebook,电子邮件以及设备可以执行的任何其他方式共享修改后的图像(在画布中)。

2 个答案:

答案 0 :(得分:1)

以下是仅使用画布将图标附加到图像上的替代方法

  • 在html5画布的顶部划出一个工具栏区域,并用所需的图标填充它。
  • 将目标图像放在工具栏下方。
  • 聆听鼠标事件。
  • 允许用户将工具栏中的图标放到下面的图像上。
  • 当用户&#34;掉线&#34;通过释放鼠标拖动图标,在拖放位置创建拖动图标的副本。

以下是带注释的代码和演示:

enter image description here

&#13;
&#13;
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

var isDown=false;
var startX,startY;

ctx.lineWidth=0.50;
ctx.strokeStyle='lightgray';
ctx.fillStyle='white';

// vars for icons, etc
var tbar={width:cw,height:35}
var tw=30;
var th=30;
var dragging=null;
var dropped=[];
var icons=[
  {name:'Flower',x:tw*0,y:2,url:'https://dl.dropboxusercontent.com/u/139992952/multple/flower.png'},
  {name:'Star',x:tw*1,y:2,url:'https://dl.dropboxusercontent.com/u/139992952/multple/star.png'},
  {name:'Plane',x:tw*2,y:2,url:'https://dl.dropboxusercontent.com/u/139992952/multple/plane2.png'},
  {name:'Mario',x:tw*3,y:2,url:'https://dl.dropboxusercontent.com/u/139992952/multple/marioStanding.png'},
];
  var thumbs=[];
var mainImg=new Image();
mainImg.crossOrigin='anonymous';
mainImg.onload=start;
mainImg.src='https://dl.dropboxusercontent.com/u/139992952/multple/husky.jpg';
var imgCount=icons.length+1;
for(var i=0;i<icons.length;i++){
  var icon=icons[i];
  icon.index=i;
  icon.img=new Image();
  icon.img.crossOrigin='anonymous';
  icon.img.onload=start;
  icon.img.src=icon.url;
}

// start is called when each image is fully loaded
function start(){
  // wait for all images to load
  if(--imgCount>0){return;}
  // create 
  for(var i=0;i<icons.length;i++){
    var icon=icons[i];
    thumbs.push(thumb(icon.img,tw,th));
  }
  // draw the toolbar & image
  draw();
  // listen for mouse events
  $("#canvas").mousedown(function(e){handleMouseDown(e);});
  $("#canvas").mousemove(function(e){handleMouseMove(e);});
  $("#canvas").mouseup(function(e){handleMouseUpOut(e);});
  $("#canvas").mouseout(function(e){handleMouseUpOut(e);});
}

// create thumbnails for each image (to be used as icons in the toolbar)
function thumb(img,w,h){
  var iw=img.width;
  var ih=img.height;
  var s=Math.min((w/iw),(h/ih))
  var c=document.createElement('canvas');
  c.width=iw*s;
  c.height=ih*s;
  c.getContext('2d').drawImage(img,0,0,iw,ih,0,0,iw*s,ih*s);
  return(c);
}

// draw the toolbar, image & any clone thumbnails added to the image
function draw(){
  ctx.clearRect(0,0,cw,ch);
  ctx.fillRect(0,0,cw,tbar.height);
  ctx.strokeRect(0,0,cw,tbar.height);
  ctx.drawImage(mainImg,0,tbar.height);
  for(var i=0;i<icons.length;i++){
    var icon=icons[i];
    ctx.drawImage(thumbs[icon.index],icon.x,icon.y);
  }
  for(var i=0;i<dropped.length;i++){
    var icon=dropped[i];
    ctx.drawImage(thumbs[icon.thumbIndex],icon.x,icon.y);
  }
  if(dragging){
    ctx.drawImage(thumbs[dragging.thumbIndex],dragging.x,dragging.y);
  }
}

//
function handleMouseDown(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  // get the mouse position
  startX=parseInt(e.clientX-offsetX);
  startY=parseInt(e.clientY-offsetY);
  // hit test the toolbar icons and any dropped icons
  var mx=startX;
  var my=startY;
  // hit test toolbar icons
  if(mx>0 && mx<tw*icons.length && my>2 && my<2+tw){
    var icon=icons[parseInt(mx/tw)];
    dragging={thumbIndex:icon.index,x:icon.x,y:icon.y};
    dragging.source='icons';
    return;
  }
  // hit test dropped icons
  for(var i=0;i<dropped.length;i++){
    var icon=dropped[i];
    if(mx>icon.x && mx<icon.x+tw && my>icon.y && my<icon.y+th){
      dragging=dropped[i];
      dragging.source='dropped';
      dragging.droppedIndex=i;
      return;
    }
  }
}

// Add any 
function handleMouseUpOut(e){
  if(!dragging){return;}
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  //
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);
  // add the icon to its dropped position
  if(dragging.source=='icons'){
    if(dragging.y>tbar.height){
      dropped.push(dragging);
    }
    // remove the dropped icon if it's back in the toolbar
  }else if(dragging.y<tbar.height){
    dropped.splice(dragging.droppedIndex,1);
  }
  // clear dragging
  dragging=null;
  // redraw
  draw();
}

// move any icon that's being dragged
function handleMouseMove(e){
  if(!dragging){return;}
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();
  // get mouse position
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);
  // move the dragged icon by the distance the mouse
  // has moved since the last mousemove event
  var dx=mouseX-startX;
  var dy=mouseY-startY;
  startX=mouseX;
  startY=mouseY;
  dragging.x+=dx;
  dragging.y+=dy;
  // redraw
  draw();
}

// save just the image with dropped icons
$('#save').click(function(){
  var c=document.createElement('canvas');
  c.width=cw;
  c.height=ch-tbar.height;
  c.getContext('2d').drawImage(canvas,0,tbar.height,cw,ch-tbar.height,0,0,c.width,c.height);
  var img=new Image();
  img.onload=function(){
    document.body.appendChild(img);
  }
  img.src=c.toDataURL();
});
&#13;
body{ background-color: ivory; }
#canvas{border:1px solid lightgray; }
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button id='save'>Save</button>
<h4>Drag from top toolbar & icon will be drop-copied<br>Drag dropped icons around image<br>Drag dropped icon back to toolbar to delete.</h4>
<canvas id="canvas" width=300 height=300></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

有点难以理解,但我怀疑你是否要求将所有现有的DOM图像合成到一个画布上下文中。为此,您可能希望查看2dcanvas上的globalCompositeOperation属性:

globalCompositeOperation - 属性

Compositing Tutorial - 不同类型如何运作的基本概要

同样是你的第三个问题:$('#foto')返回一个jquery对象,document.getElementById返回一个DOM对象。要获得实际的DOM元素,您可以执行以下操作:var theEl = $('#foto')[0]