2016-07-16 7 views
1

実際には、JavaScriptで作成されたキャンバステキストをドラッグアンドドロップしようとしました。しかし、テキストの選択が正しく行われていないため、適切にドラッグできません。私は以下のスニペットに自分のコードを保存しました。キャンバスイメージにテキストをドラッグアンドドロップできない

私にこれを手伝ってください。前もって感謝します。

var canvas = document.getElementById("canvas"); 
 
var ctx = canvas.getContext("2d"); 
 

 
// variables used to get mouse position on the canvas 
 
var $canvas = $("#canvas"); 
 
var canvasOffset = $canvas.offset(); 
 
var offsetX = canvasOffset.left; 
 
var offsetY = canvasOffset.top; 
 
var scrollX = $canvas.scrollLeft(); 
 
var scrollY = $canvas.scrollTop(); 
 

 
// variables to save last mouse position 
 
// used to see how far the user dragged the mouse 
 
// and then move the text by that distance 
 
var startX; 
 
var startY; 
 

 
// an array to hold text objects 
 
var texts = []; 
 

 
// this var will hold the index of the hit-selected text 
 
var selectedText = -1; 
 

 
// clear the canvas & redraw all texts 
 
function draw() { 
 
    ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
    ctx.drawImage(window.imageSrc, 0, 0, canvas.width, canvas.height); 
 
    for (var i = 0; i < texts.length; i++) { 
 
     var text = texts[i]; 
 
\t \t ctx.strokeText(text.text, text.x, text.y); 
 
     ctx.fillText(text.text, text.x, text.y); 
 
    } 
 
} 
 

 
// test if x,y is inside the bounding box of texts[textIndex] 
 
function textHittest(x, y, textIndex) { 
 
    var text = texts[textIndex]; 
 
    return (x >= text.x && x <= text.x + text.width && y >= text.y - text.height && y <= text.y); 
 
} 
 

 
// handle mousedown events 
 
// iterate through texts[] and see if the user 
 
// mousedown'ed on one of them 
 
// If yes, set the selectedText to the index of that text 
 
function handleMouseDown(e) { 
 
    e.preventDefault(); 
 
    startX = parseInt(e.clientX - offsetX); 
 
    startY = parseInt(e.clientY - offsetY); 
 
    // Put your mousedown stuff here 
 
    //alert(texts.length); 
 
\t 
 
\t 
 
    for (var i = 0; i < texts.length; i++) { 
 
     if (textHittest(startX, startY, i)) { 
 
      selectedText = i; 
 
     } 
 
    } 
 
} 
 

 
// done dragging 
 
function handleMouseUp(e) { 
 
    e.preventDefault(); 
 
    selectedText = -1; 
 
} 
 

 
// also done dragging 
 
function handleMouseOut(e) { 
 
    e.preventDefault(); 
 
    selectedText = -1; 
 
} 
 

 
// handle mousemove events 
 
// calc how far the mouse has been dragged since 
 
// the last mousemove event and move the selected text 
 
// by that distance 
 
function handleMouseMove(e) { 
 
    if (selectedText < 0) { 
 
     return; 
 
    } 
 
    e.preventDefault(); 
 
    mouseX = parseInt(e.clientX - offsetX); 
 
    mouseY = parseInt(e.clientY - offsetY); 
 

 
    // Put your mousemove stuff here 
 
    var dx = mouseX - startX; 
 
    var dy = mouseY - startY; 
 
    startX = mouseX; 
 
    startY = mouseY; 
 

 
    var text = texts[selectedText]; 
 
    text.x += dx; 
 
    text.y += dy; 
 
    draw(); 
 
} 
 

 
// listen for mouse events 
 
$("#canvas").mousedown(function (e) { 
 
    handleMouseDown(e); 
 
}); 
 
$("#canvas").mousemove(function (e) { 
 
    handleMouseMove(e); 
 
}); 
 
$("#canvas").mouseup(function (e) { 
 
    handleMouseUp(e); 
 
}); 
 
$("#canvas").mouseout(function (e) { 
 
    handleMouseOut(e); 
 
}); 
 

 
$("[id^='memeText']").change(function() { 
 
    // calc the y coordinate for this text on the canvas 
 
    var y = texts.length * 20 + 100; 
 
\t \t var position = $(this).attr('name'); 
 
    
 
    position = position - 1; 
 
    // get the text from the input element 
 
    var text = { 
 
     text: $(this).val(), 
 
     x: 250, 
 
     y: y 
 
    }; 
 

 
    // calc the size of this text for hit-testing purposes 
 
    ctx.font = "32px verdana"; 
 
    ctx.textAlign = 'center'; 
 
\t ctx.lineWidth = 3; 
 
\t ctx.fillStyle = "#fff"; 
 
\t ctx.strokeStyle = "#000"; 
 
    text.width = ctx.measureText(text.text).width; 
 
    text.height = 16; 
 
\t \t if(texts[position]==""||texts[position]==null||texts[position]==undefined){ 
 
    \t texts.push(text); 
 
    } else { 
 
    \t console.log(texts[position].text); 
 
    \t texts[position].text = $(this).val(); 
 
    } 
 
    // put this new text in the texts array 
 
    
 

 
    // redraw everything 
 
    draw(); 
 

 
}); 
 

 
function handleFileSelect(evt) { 
 
\t \t \t \t \t \t //var canvasWidth = 500; 
 
\t \t \t \t \t // \t var canvasHeight = 500; 
 
\t \t \t \t \t \t var file = evt.target.files[0]; 
 
\t \t \t \t \t \t var reader = new FileReader(); 
 
\t \t \t \t \t \t reader.onload = function(fileObject) { 
 
\t \t \t \t \t \t \t var data = fileObject.target.result; 
 
\t \t \t \t \t \t \t var image = new Image(); 
 
\t \t \t \t \t \t \t image.onload = function() { 
 
\t \t \t \t \t \t \t \t window.imageSrc = this; 
 
\t \t \t \t \t \t \t \t ctx.drawImage(window.imageSrc, 0, 0, canvas.width, canvas.height); 
 

 
\t \t \t \t \t \t \t }; 
 
\t \t \t \t \t \t \t document.getElementById('box2').style.display = "block"; 
 
\t \t \t \t \t \t \t image.src = data; 
 
\t \t \t \t \t \t \t // console.log(fileObject.target.result); 
 
\t \t \t \t \t \t }; 
 
\t \t \t \t \t \t reader.readAsDataURL(file); 
 
\t \t \t \t \t } 
 
      
 
      document.getElementById('file').addEventListener('change', 
 
\t \t \t \t \t \t \t handleFileSelect, false);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div id="box1" style=""> 
 
     
 
     <input id="file" type="file" autocomplete="off"> 
 
     <br><br> 
 
    </div> 
 
    
 
    <div id="box2" style="display: none;"> 
 
     
 
     <input id="memeText" name="1" autocomplete="off"> 
 
     <br><br> 
 
     <input id="memeText" name="2" autocomplete="off"> 
 
     <br><br> 
 
     <canvas id="canvas" width="500" height="500"></canvas> 
 
     <br><br> 
 
     <a class="buttonLink" id="downloadLink">Download Meme!</a> 
 
     <br><br> 
 
     <a href="">Make Another Meme!</a> 
 
    </div>

+0

注:最新のjqueryバージョン2.2.4を使用していますが、コードスニペットでは最も古いものを使用しています。 –

答えて

1

これで問題がいくつかあります。

まず、Get the coordinates of a mouse click on Canvasをご覧ください。現在、オフセットは両方とも0です。とcanvas.offsetTop - 注:canvas$canvasではありません)を呼び出してみてください。

第2に、テキストの位置はテキストの中央に設定され、左上または左下には設定されません。テキストプロパティhere

return (x >= (text.x - 0.5*text.width) && x <= (text.x + 0.5*text.width) && y >= (text.y - 0.5*text.height) && y <= (text.y + 0.5*text.height)); 

より:だからあなたのtextHittest機能で、あなたはこのreturn文をしたいです。

ソートされたら、イベントがあなたが望むとおりに正確に登録されているかどうかを再度確認します。あなたが始められるのに十分だと思います:)

関連する問題