javascript - وضع الماوس الحقيقي في قماش




canvas html5-canvas mouse-position (5)

أحاول رسم الماوس فوق لوحة HTML5 ، ولكن الطريقة الوحيدة التي يبدو أنها تعمل بشكل جيد هي إذا كانت اللوحة في الموضع 0،0 (الزاوية اليسرى العليا) إذا قمت بتغيير موضع اللوحة ، لسبب ما لا يرسم كما ينبغي. هنا هو رمز بلدي.

 function createImageOnCanvas(imageId){
    document.getElementById("imgCanvas").style.display = "block";
    document.getElementById("images").style.overflowY= "hidden";
    var canvas = document.getElementById("imgCanvas");
    var context = canvas.getContext("2d");
    var img = new Image(300,300);
    img.src = document.getElementById(imageId).src;
    context.drawImage(img, (0),(0));
}

function draw(e){
    var canvas = document.getElementById("imgCanvas");
    var context = canvas.getContext("2d");
    posx = e.clientX;
    posy = e.clientY;
    context.fillStyle = "#000000";
    context.fillRect (posx, posy, 4, 4);
}

جزء HTML

 <body>
 <div id="images">
 </div>
 <canvas onmousemove="draw(event)" style="margin:0;padding:0;" id="imgCanvas"
          class="canvasView" width="250" height="250"></canvas> 

لقد قرأت أن هناك طريقة لإنشاء وظيفة بسيطة في جافا سكريبت للحصول على الوضع الصحيح ، ولكن ليس لدي أي فكرة عن كيفية القيام بذلك.


Answers

السيناريو البسيط 1: 1

بالنسبة إلى المواقف التي يكون فيها عنصر لوحة الرسم 1: 1 مقارنة بحجم الصورة النقطية ، يمكنك الحصول على مواضع الماوس باستخدام هذا المقتطف:

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
      x: evt.clientX - rect.left,
      y: evt.clientY - rect.top
    };
}

ما عليك سوى الاتصال به من الحدث الخاص بك مع الحدث وقماش كحجج. تقوم بإرجاع كائن مع x و y من أجل مواضع الماوس.

نظرًا لأن موضع الماوس الذي تحصل عليه هو نسبة إلى نافذة العميل ، سيتعين عليك طرح موضع عنصر لوحة الرسم لتحويله إلى عنصر متعلق بالعنصر نفسه.

مثال للتكامل في شفرتك:

//put this outside the event loop..
var canvas = document.getElementById("imgCanvas");
var context = canvas.getContext("2d");

function draw(evt) {
    var pos = getMousePos(canvas, evt);

    context.fillStyle = "#000000";
    context.fillRect (pos.x, pos.y, 4, 4);
}

عزف مع التعديلات

ملاحظة: الحدود والحشو ستؤثر على الموضع إذا تم تطبيقهما مباشرة على عنصر لوحة الرسم بحيث يجب أخذها في الاعتبار عبر getComputedStyle() - أو تطبيق تلك الأنماط على div الأصل بدلاً من ذلك.

عندما يكون العنصر و Bitmap من أحجام مختلفة

عندما يكون هناك موقف من وجود عنصر بحجم مختلف عن الصورة النقطية نفسها ، على سبيل المثال ، يتم تحجيم العنصر باستخدام CSS أو أن هناك نسبة إلى البايكسل وما إلى ذلك ، سيكون عليك معالجة ذلك.

مثال:

function  getMousePos(canvas, evt) {
  var rect = canvas.getBoundingClientRect(), // abs. size of element
      scaleX = canvas.width / rect.width,    // relationship bitmap vs. element for X
      scaleY = canvas.height / rect.height;  // relationship bitmap vs. element for Y

  return {
    x: (evt.clientX - rect.left) * scaleX,   // scale mouse coordinates after they have
    y: (evt.clientY - rect.top) * scaleY     // been adjusted to be relative to element
  }
}

كمان باستخدام مقياس

مع تطبيق التحولات على السياق (المقياس ، الدوران ، إلخ)

ثم هناك حالة أكثر تعقيدا حيث قمت بتطبيق التحول إلى السياق مثل التناوب ، انحراف / القص ، مقياس ، ترجمة وما إلى ذلك. للتعامل مع هذا يمكنك حساب مصفوفة عكس المصفوفة الحالية.

تتيح لك المستعرضات الأحدث قراءة المصفوفة الحالية عبر الخاصية currentTransform و Firefox (alpha الحالي) حتى توفر مصفوفة معكوسة عبر mozCurrentTransformInverted . ولكن ، عبر فايرفوكس ، mozCurrentTransform متصفح فايرفوكس mozCurrentTransform وليس DOMMatrix كما ينبغي. لن يتمكن Chrome ، عند تمكينه عبر العلامات التجريبية ، من عرض DOMMatrix ولكن باستخدام SVGMatrix .

في معظم الحالات ، سيكون عليك تنفيذ حل مصفوفة خاص بك (مثل الحل الخاص بي here - مشروع MIT / المجاني) حتى تحصل على الدعم الكامل.

عندما تحصل في نهاية المطاف على المصفوفة بغض النظر عن المسار الذي تحصل عليه للحصول على واحد ، ستحتاج إلى عكسه وتطبيقه على إحداثيات الماوس. ثم يتم تمرير الإحداثيات إلى اللوحة التي ستستخدم مصفوفة لها لتحويلها إلى الوراء أينما كانت في الوقت الحالي.

بهذه الطريقة ستكون النقطة في الموضع الصحيح بالنسبة للماوس. هنا أيضا تحتاج إلى ضبط الإحداثيات (قبل تطبيق المصفوفة العكسيّة عليها) لتكون قريبة من العنصر.

مثال يوضح فقط خطوات المصفوفة

function draw(evt) {
    var pos = getMousePos(canvas, evt);        // get adjusted coordinates as above
    var imatrix = matrix.inverse();            // get inverted matrix somehow
    pos = imatrix.applyToPoint(pos.x, pos.y);  // apply to adjusted coordinate

    context.fillStyle = "#000000";
    context.fillRect(pos.x-1, pos.y-1, 2, 2);
}

مثال باستخدام الحل المرتبط أعلاه (استبدل بحل المتصفح الأصلي عند دعمه على نطاق أوسع).

مثال على استخدام currentTransform عند تنفيذها سيكون:

    var pos = getMousePos(canvas, e);          // get adjusted coordinates as above
    var matrix = ctx.currentTransform;         // W3C (future)
    var imatrix = matrix.invertSelf();         // invert

    // apply to point:
    var x = pos.x * imatrix.a + pos.y * imatrix.c + imatrix.e;
    var y = pos.x * imatrix.b + pos.y * imatrix.d + imatrix.f;

التحديث قمت بعمل حل حر (MIT) لتضمين كل هذه الخطوات في كائن واحد سهل الاستخدام يمكن العثور عليه here كما يعتني ببضع أشياء أخرى أكثر أهمية تجاهلها.



يمكنك الحصول على موضع الماوس باستخدام هذا المقتطف:

function getMousePos(canvas, evt) {
    var rect = canvas.getBoundingClientRect();
    return {
        x: (evt.clientX - rect.left) / (rect.right - rect.left) * canvas.width,
        y: (evt.clientY - rect.top) / (rect.bottom - rect.top) * canvas.height
    };
}

يأخذ هذا الكود في الاعتبار كلا الإحداثيات المتغيرة لمساحة القماش ( evt.clientX - rect.left ) والقياس عند اختلاف حجم منطقي الرسم evt.clientX - rect.left عن حجم النمط الخاص به ( / (rect.right - rect.left) * canvas.width see: Canvas width والارتفاع في HTML5 ).

مثال: http://jsfiddle.net/sierawski/4xezb7nL/

المصدر: تعليق jerryj على http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/


تحتاج إلى الحصول على موضع الماوس نسبة إلى اللوحة

للقيام بذلك تحتاج إلى معرفة موقف X / Y من قماش على الصفحة.

يسمى هذا "إزاحة" اللوحة الفنية ، وإليك كيفية الحصول على الإزاحة. (أنا أستخدم jQuery من أجل تبسيط التوافق بين المتصفحات ، ولكن إذا كنت ترغب في استخدام جافا سكريبت الخام ، فستتوفر Google سريعة أيضًا).

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

ثم في معالج الماوس ، يمكنك الحصول على الماوس X / Y مثل هذا:

  function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
}

إليك رمزًا توضيحيًا وعزفًا يوضح كيفية تتبع أحداث الماوس بنجاح على اللوحة:

http://jsfiddle.net/m1erickson/WB7Zu/

<!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>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

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

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    function handleMouseDown(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#downlog").html("Down: "+ mouseX + " / " + mouseY);

      // Put your mousedown stuff here

    }

    function handleMouseUp(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#uplog").html("Up: "+ mouseX + " / " + mouseY);

      // Put your mouseup stuff here
    }

    function handleMouseOut(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#outlog").html("Out: "+ mouseX + " / " + mouseY);

      // Put your mouseOut stuff here
    }

    function handleMouseMove(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
      $("#movelog").html("Move: "+ mouseX + " / " + mouseY);

      // Put your mousemove stuff here

    }

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

}); // end $(function(){});
</script>

</head>

<body>
    <p>Move, press and release the mouse</p>
    <p id="downlog">Down</p>
    <p id="movelog">Move</p>
    <p id="uplog">Up</p>
    <p id="outlog">Out</p>
    <canvas id="canvas" width=300 height=300></canvas>

</body>
</html>

يمكن لتطبيق الويب الخاص بك الآن التقاط لقطة شاشة "أصلية" لسطح مكتب العميل بأكمله باستخدام getUserMedia() :

إلقاء نظرة على هذا المثال:

https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/

سيتعين على العميل استخدام chrome (في الوقت الحالي) وسيتعين عليه تمكين دعم التقاط الشاشة تحت chrome: // flags.





javascript canvas html5-canvas mouse-position