कैनवास तत्व पर क्लिक इवेंट हैंडलर जोड़ने का सबसे सरल तरीका क्या है जो क्लिक के x और y निर्देशांक (कैनवास तत्व के सापेक्ष) को लौटाएगा?
कोई लीगेसी ब्राउज़र संगतता की आवश्यकता नहीं है, सफारी, ओपेरा और फ़ायरफ़ॉक्स करेंगे।
कैनवास तत्व पर क्लिक इवेंट हैंडलर जोड़ने का सबसे सरल तरीका क्या है जो क्लिक के x और y निर्देशांक (कैनवास तत्व के सापेक्ष) को लौटाएगा?
कोई लीगेसी ब्राउज़र संगतता की आवश्यकता नहीं है, सफारी, ओपेरा और फ़ायरफ़ॉक्स करेंगे।
जवाबों:
संपादित करें 2018: यह उत्तर बहुत पुराना है और यह पुराने ब्राउज़रों के लिए चेक का उपयोग करता है जो अब आवश्यक नहीं हैं, क्योंकि clientX
और clientY
गुण सभी वर्तमान ब्राउज़रों में काम करते हैं। आप एक सरल, अधिक हाल के समाधान के लिए पैट्रियक्स उत्तर की जांच करना चाह सकते हैं ।
मूल उत्तर:
जैसा कि मैंने एक लेख में बताया था, मैं वापस मिल गया लेकिन अब मौजूद नहीं है:
var x;
var y;
if (e.pageX || e.pageY) {
x = e.pageX;
y = e.pageY;
}
else {
x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
x -= gCanvasElement.offsetLeft;
y -= gCanvasElement.offsetTop;
मेरे लिए पूरी तरह से ठीक काम किया।
यदि आप सादगी पसंद करते हैं, लेकिन फिर भी क्रॉस-ब्राउज़र कार्यक्षमता चाहते हैं, तो मैंने पाया कि यह समाधान मेरे लिए सबसे अच्छा काम करता है। यह @ Aldekein के समाधान का सरलीकरण है लेकिन jQuery के बिना ।
function getCursorPosition(canvas, event) {
const rect = canvas.getBoundingClientRect()
const x = event.clientX - rect.left
const y = event.clientY - rect.top
console.log("x: " + x + " y: " + y)
}
const canvas = document.querySelector('canvas')
canvas.addEventListener('mousedown', function(e) {
getCursorPosition(canvas, e)
})
getBoundingClientRect
दृश्य बंदरगाह के सापेक्ष स्थिति देता है? तब मेरा अनुमान गलत था। मैंने इसका कभी भी परीक्षण नहीं किया क्योंकि यह मेरे लिए कभी समस्या नहीं थी, और मैं कृपया अन्य पाठकों को संभावित रूप से देखी गई समस्या के बारे में चेतावनी देना चाहता था, लेकिन आपके स्पष्टीकरण के लिए धन्यवाद।
var canvas = document.getElementById('canvasID'); canvas.addEventListener("mousedown", function (e) { getCursorPosition(canvas, e);});
अद्यतन (5/5/16): देशभक्तों के उत्तर का उपयोग किया जाना चाहिए, क्योंकि यह सरल और अधिक विश्वसनीय दोनों है।
चूंकि कैनवास हमेशा पूरे पृष्ठ के सापेक्ष नहीं होता है, इसलिए canvas.offsetLeft/Top
हमेशा वह नहीं लौटता है जिसकी आपको आवश्यकता होती है। यह अपने ऑफ़सेटपैरेंट तत्व के सापेक्ष ऑफसेट किए गए पिक्सेल की संख्या को वापस कर देगा, जो कि एक div
तत्व के साथ कैनवास की तरह कुछ हो सकता है, जिस पर एक position: relative
शैली लागू है। इसके लिए आपको offsetParent
एस की श्रृंखला के माध्यम से लूप करने की आवश्यकता है , शुरुआत कैनवास तत्व के साथ। यह कोड मेरे लिए पूरी तरह से काम करता है, फ़ायरफ़ॉक्स और सफारी में परीक्षण किया गया है लेकिन सभी के लिए काम करना चाहिए।
function relMouseCoords(event){
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var currentElement = this;
do{
totalOffsetX += currentElement.offsetLeft - currentElement.scrollLeft;
totalOffsetY += currentElement.offsetTop - currentElement.scrollTop;
}
while(currentElement = currentElement.offsetParent)
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
return {x:canvasX, y:canvasY}
}
HTMLCanvasElement.prototype.relMouseCoords = relMouseCoords;
अंतिम पंक्ति एक कैनवास तत्व के सापेक्ष माउस निर्देशांक प्राप्त करने के लिए चीजों को सुविधाजनक बनाती है। उपयोगी निर्देशांक प्राप्त करने के लिए सभी आवश्यक है
coords = canvas.relMouseCoords(event);
canvasX = coords.x;
canvasY = coords.y;
event.offsetX
और event.offsetY
गुण है, इसलिए मैं जोड़कर अपने समाधान संशोधित if (event.offsetX !== undefined && event.offsetY !== undefined) { return {x:event.offsetX, y:event.offsetY}; }
। ऐसा लगता है कि यह काम करता है।
event.offsetX
और event.offsetY
जो IE9 में भी काम करता है। फ़ायरफ़ॉक्स (परीक्षण w / v13) के लिए आप उपयोग कर सकते हैं event.layerX
और event.layerY
।
canvasX = event.pageX - totalOffsetX - document.body.scrollLeft; canvasY = event.pageY - totalOffsetY - document.body.scrollTop;
आधुनिक ब्राउज़र अब आपके लिए इसे संभाल रहा है। क्रोम, IE9, और फ़ायरफ़ॉक्स इस तरह से ऑफसेट / वाई का समर्थन करते हैं, क्लिक हैंडलर से घटना में गुजरते हैं।
function getRelativeCoords(event) {
return { x: event.offsetX, y: event.offsetY };
}
अधिकांश आधुनिक ब्राउज़र भी लेयरएक्स / वाई का समर्थन करते हैं, हालांकि क्रोम और पैड सहित पेज पर क्लिक के निरपेक्ष ऑफसेट के लिए क्रोम और आईई लेयरएक्स / वाई का उपयोग करते हैं। फ़ायरफ़ॉक्स, लेयरएक्स / वाई और ऑफसेटएक्स / वाई में समतुल्य हैं, लेकिन ऑफ़सेट डीएनएन 't पहले से मौजूद है। इसलिए, थोड़े पुराने ब्राउज़रों के साथ संगतता के लिए, आप इसका उपयोग कर सकते हैं:
function getRelativeCoords(event) {
return { x: event.offsetX || event.layerX, y: event.offsetY || event.layerY };
}
ताजा Quirksmode के अनुसार clientX
और clientY
तरीके सभी प्रमुख ब्राउज़रों में समर्थित हैं। तो, यहाँ यह जाता है - अच्छा, काम करने वाला कोड जो स्क्रॉलबार वाले पेज पर स्क्रॉलिंग डिव में काम करता है:
function getCursorPosition(canvas, event) {
var x, y;
canoffset = $(canvas).offset();
x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft - Math.floor(canoffset.left);
y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop - Math.floor(canoffset.top) + 1;
return [x,y];
}
इसके लिए भी jQuery की आवश्यकता होती है $(canvas).offset()
।
मैंने एक पूर्ण डेमोस्ट्रेशन बनाया जो इस समस्या के समाधान के पूर्ण स्रोत कोड के साथ हर ब्राउज़र में काम करता है: एक माउस के निर्देशांक जावास्क्रिप्ट में कैनवास पर क्लिक करते हैं । डेमो की कोशिश करने के लिए, कोड को कॉपी करें और इसे टेक्स्ट एडिटर में पेस्ट करें। फिर इसे example.html के रूप में सेव करें और आखिर में फाइल को ब्राउजर के साथ खोलें।
यहाँ एक चर (%) चौड़ाई के साथ कैनवस के लिए रयान आर्टकोना के उत्तर का एक छोटा संशोधन है :
HTMLCanvasElement.prototype.relMouseCoords = function (event) {
var totalOffsetX = 0;
var totalOffsetY = 0;
var canvasX = 0;
var canvasY = 0;
var currentElement = this;
do {
totalOffsetX += currentElement.offsetLeft;
totalOffsetY += currentElement.offsetTop;
}
while (currentElement = currentElement.offsetParent)
canvasX = event.pageX - totalOffsetX;
canvasY = event.pageY - totalOffsetY;
// Fix for variable canvas width
canvasX = Math.round( canvasX * (this.width / this.offsetWidth) );
canvasY = Math.round( canvasY * (this.height / this.offsetHeight) );
return {x:canvasX, y:canvasY}
}
समन्वय रूपांतरण करते समय सावधान रहें; एक क्लिक ईवेंट में लौटाए गए कई गैर-क्रॉस-ब्राउज़र मान हैं। अगर क्लाइंट विंडो ब्राउजर स्क्रॉल (फ़ायरफ़ॉक्स 3.5 और क्रोम 3.0 में सत्यापित) है तो क्लाइंटएक्स और क्लाइंट का उपयोग करना पर्याप्त नहीं है।
यह quirks मोड आलेख एक अधिक सही फ़ंक्शन प्रदान करता है जो किसी दस्तावेज़ के मूल के सापेक्ष क्लिक समन्वय की गणना करने के लिए document.body.scrollLeft और clientY के साथ पेजएक्स या पेजवाई या क्लाइंटएक्स के संयोजन का उपयोग कर सकता है।
अद्यतन: इसके अतिरिक्त, ऑफसेट लाइट और ऑफसेटटॉप तत्व के गद्देदार आकार के सापेक्ष हैं, न कि आंतरिक आकार के। पैडिंग के साथ एक कैनवास: लागू शैली ऑफसेट सामग्री के रूप में अपने सामग्री क्षेत्र के शीर्ष-बाएं को रिपोर्ट नहीं करेगी। इस समस्या के विभिन्न समाधान हैं; सबसे सरल हो सकता है कि कैनवास पर सभी बॉर्डर, पैडिंग, आदि शैलियों को साफ़ करें और इसके बजाय उन्हें कैनवास वाले बॉक्स पर लागू करें।
मुझे यकीन नहीं है कि इन सभी उत्तरों का क्या मतलब है जो मूल तत्वों के माध्यम से लूप करते हैं और सभी प्रकार के अजीब सामान करते हैं ।
HTMLElement.getBoundingClientRect
विधि किसी भी तत्व की वास्तविक स्क्रीन स्थिति को संभालने के लिए बनाया गया है। इसमें स्क्रॉलिंग शामिल है, इसलिए जैसे सामान की scrollTop
आवश्यकता नहीं है:
(MDN से) स्क्रॉलिंग की मात्रा जो व्यूपोर्ट क्षेत्र (या किसी अन्य स्क्रॉल करने योग्य तत्व ) से की गई है, बाउंडिंग आयत की गणना करते समय ध्यान में रखा जाता है।
बहुत सरल दृष्टिकोण पहले से ही यहाँ तैनात थे। यह तब तक सही है जब तक कोई जंगली सीएसएस नियम शामिल नहीं होते हैं।
जब छवि पिक्सेल चौड़ाई सीएसएस चौड़ाई से मेल नहीं खाती है, तो आपको पिक्सेल मूल्यों पर कुछ अनुपात लागू करने की आवश्यकता होगी:
/* Returns pixel coordinates according to the pixel that's under the mouse cursor**/
HTMLCanvasElement.prototype.relativeCoords = function(event) {
var x,y;
//This is the current screen rectangle of canvas
var rect = this.getBoundingClientRect();
var top = rect.top;
var bottom = rect.bottom;
var left = rect.left;
var right = rect.right;
//Recalculate mouse offsets to relative offsets
x = event.clientX - left;
y = event.clientY - top;
//Also recalculate offsets of canvas is stretched
var width = right - left;
//I use this to reduce number of calculations for images that have normal size
if(this.width!=width) {
var height = bottom - top;
//changes coordinates by ratio
x = x*(this.width/width);
y = y*(this.height/height);
}
//Return as an array
return [x,y];
}
जब तक कैनवास में कोई सीमा नहीं होती है, तब तक यह स्ट्रेच की गई छवियों (jsFiddle) के लिए काम करता है ।
यदि कैनवास में मोटी सीमा है, तो चीजें थोड़ी जटिल हो जाती हैं । आपको सचमुच सीमा आयत से सीमा को घटाना होगा। इसे .getComputedStyle का उपयोग करके किया जा सकता है । यह उत्तर प्रक्रिया का वर्णन करता है ।
फ़ंक्शन तब थोड़ा बढ़ता है:
/* Returns pixel coordinates according to the pixel that's under the mouse cursor**/
HTMLCanvasElement.prototype.relativeCoords = function(event) {
var x,y;
//This is the current screen rectangle of canvas
var rect = this.getBoundingClientRect();
var top = rect.top;
var bottom = rect.bottom;
var left = rect.left;
var right = rect.right;
//Subtract border size
// Get computed style
var styling=getComputedStyle(this,null);
// Turn the border widths in integers
var topBorder=parseInt(styling.getPropertyValue('border-top-width'),10);
var rightBorder=parseInt(styling.getPropertyValue('border-right-width'),10);
var bottomBorder=parseInt(styling.getPropertyValue('border-bottom-width'),10);
var leftBorder=parseInt(styling.getPropertyValue('border-left-width'),10);
//Subtract border from rectangle
left+=leftBorder;
right-=rightBorder;
top+=topBorder;
bottom-=bottomBorder;
//Proceed as usual
...
}
मैं इस अंतिम कार्य को भ्रमित करने वाली किसी भी चीज के बारे में नहीं सोच सकता। अपने आप को JsFiddle पर देखें ।
यदि आपको देशी prototype
एस को संशोधित करना पसंद नहीं है , तो बस फ़ंक्शन को बदलें और इसे कॉल करें (canvas, event)
(और किसी के this
साथ बदलें canvas
)।
यहाँ एक बहुत अच्छा ट्यूटोरियल है-
http://www.html5canvastutorials.com/advanced/html5-canvas-mouse-coordinates/
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
function writeMessage(canvas, message) {
var context = canvas.getContext('2d');
context.clearRect(0, 0, canvas.width, canvas.height);
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
writeMessage(canvas, message);
}, false);
उम्मीद है की यह मदद करेगा!
width
/ height
overriden है लेकिन फिर भी सबसे अच्छे समाधानों में से एक है।
2016 में jQuery का उपयोग करना, कैनवास के सापेक्ष निर्देशांक क्लिक करने के लिए, मैं करता हूं:
$(canvas).click(function(jqEvent) {
var coords = {
x: jqEvent.pageX - $(canvas).offset().left,
y: jqEvent.pageY - $(canvas).offset().top
};
});
यह कैनवास ऑफसेट () और jqEvent.pageX / Y दोनों के बाद से काम करता है, स्क्रॉल स्थिति की परवाह किए बिना दस्तावेज़ के सापेक्ष हैं।
ध्यान दें कि यदि आपका कैनवास छोटा है, तो ये निर्देशांक कैनवास तार्किक निर्देशांक के समान नहीं हैं । उन पाने के लिए, आप भी करेंगे :
var logicalCoords = {
x: coords.x * (canvas.width / $(canvas).width()),
y: coords.y * (canvas.height / $(canvas).height())
}
तो यह दोनों सरल है लेकिन लगता है की तुलना में थोड़ा अधिक जटिल विषय है।
सबसे पहले आम तौर पर यहाँ भ्रमित प्रश्न हैं
तत्व सापेक्ष माउस निर्देशांक कैसे प्राप्त करें
2 डी कैनवास एपीआई या वेबजीएल के लिए कैनवास पिक्सेल माउस निर्देशांक कैसे प्राप्त करें
तो, जवाब
तत्व एक कैनवास हो रहा है या नहीं तत्व सापेक्ष माउस निर्देशांक सभी तत्वों के लिए समान है।
प्रश्न के 2 सरल उत्तर हैं "कैनवास सापेक्ष माउस निर्देशांक कैसे प्राप्त करें"
offsetX
औरoffsetY
canvas.addEventListner('mousemove', (e) => {
const x = e.offsetX;
const y = e.offsetY;
});
यह उत्तर क्रोम, फ़ायरफ़ॉक्स और सफारी में काम करता है। अन्य सभी ईवेंट मानों के विपरीत offsetX
और offsetY
CSS रूपांतरण को ध्यान में रखें।
2019/05 के साथ सबसे बड़ी समस्या है offsetX
और offsetY
वे टच इवेंट्स में मौजूद नहीं हैं और इसलिए इसका इस्तेमाल iOS सफारी के साथ नहीं किया जा सकता है। वे पॉइंटर घटनाओं पर मौजूद हैं जो क्रोम और फ़ायरफ़ॉक्स में मौजूद हैं, लेकिन सफारी नहीं हैं, हालांकि जाहिर तौर पर सफारी इस पर काम कर रहा है ।
एक और मुद्दा यह है कि घटनाएँ कैनवास पर ही होनी चाहिए। यदि आप उन्हें किसी अन्य तत्व या खिड़की पर रखते हैं तो आप बाद में कैनवास को अपना संदर्भ बिंदु नहीं चुन सकते हैं।
clientX
, clientY
औरcanvas.getBoundingClientRect
आप सीएसएस रूपांतरण के बारे में परवाह नहीं है, तो अगले सरल जवाब कॉल करने के लिए है canvas. getBoundingClientRect()
से छोड़ दिया और घटाना clientX
और top
से clientY
के रूप में
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
});
यह तब तक काम करेगा जब तक कि कोई सीएसएस ट्रांसफॉर्म न हो। यह टच इवेंट्स के साथ भी काम करता है और इसलिए सफारी आईओएस के साथ काम करेगा
canvas.addEventListener('touchmove', (e) => {
const rect = canvas. getBoundingClientRect();
const x = e.touches[0].clientX - rect.left;
const y = e.touches[0].clientY - rect.top;
});
इसके लिए हमें उन मूल्यों को लेने की जरूरत है जो हमने ऊपर उठाई हैं और जिस आकार को कैनवास में दिखाया गया है, उससे कैनवास में खुद को बदल दिया है
साथ canvas.getBoundingClientRect
और clientX
औरclientY
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
const elementRelativeX = e.clientX - rect.left;
const elementRelativeY = e.clientY - rect.top;
const canvasRelativeX = elementRelativeX * canvas.width / rect.width;
const canvasRelativeY = elementRelativeY * canvas.height / rect.height;
});
या के साथ offsetX
औरoffsetY
canvas.addEventListener('mousemove', (e) => {
const elementRelativeX = e.offsetX;
const elementRelativeX = e.offsetY;
const canvasRelativeX = elementRelativeX * canvas.width / canvas.clientWidth;
const canvasRelativeY = elementRelativeX * canvas.height / canvas.clientHeight;
});
काम कर उदाहरण event.offsetX
,event.offsetY
उदाहरण के कार्य का उपयोग कर canvas.getBoundingClientRect
और event.clientX
औरevent.clientY
मैं इस लिंक की सलाह देता हूं- http://miloq.blogspot.in/2011/05/coordinates-mouse-click-canvas.html
<style type="text/css">
#canvas{background-color: #000;}
</style>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", init, false);
function init()
{
var canvas = document.getElementById("canvas");
canvas.addEventListener("mousedown", getPosition, false);
}
function getPosition(event)
{
var x = new Number();
var y = new Number();
var canvas = document.getElementById("canvas");
if (event.x != undefined && event.y != undefined)
{
x = event.x;
y = event.y;
}
else // Firefox method to get the position
{
x = event.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
alert("x: " + x + " y: " + y);
}
</script>
x = new Number()
? उस पुनर्निर्देश के नीचे दिए गए कोड का x
अर्थ है कि आवंटित संख्या को तुरंत हटा दिया गया है
प्रोटोटाइप में, ऊपर रेयान Artecona द्वारा वर्णित पुनरावर्ती योग करने के लिए संचयीऑफ़सेट () का उपयोग करें।
आप बस कर सकते हैं:
var canvas = yourCanvasElement;
var mouseX = (event.clientX - (canvas.offsetLeft - canvas.scrollLeft)) - 2;
var mouseY = (event.clientY - (canvas.offsetTop - canvas.scrollTop)) - 2;
यह आपको माउस पॉइंटर की सटीक स्थिति देगा।
Http://jsbin.com/ApuJOSA/1/edit?html,output पर डेमो देखें ।
function mousePositionOnCanvas(e) {
var el=e.target, c=el;
var scaleX = c.width/c.offsetWidth || 1;
var scaleY = c.height/c.offsetHeight || 1;
if (!isNaN(e.offsetX))
return { x:e.offsetX*scaleX, y:e.offsetY*scaleY };
var x=e.pageX, y=e.pageY;
do {
x -= el.offsetLeft;
y -= el.offsetTop;
el = el.offsetParent;
} while (el);
return { x: x*scaleX, y: y*scaleY };
}
यहाँ ऊपर रयान Artecona के समाधान के कुछ संशोधन दिए गए हैं।
function myGetPxStyle(e,p)
{
var r=window.getComputedStyle?window.getComputedStyle(e,null)[p]:"";
return parseFloat(r);
}
function myGetClick=function(ev)
{
// {x:ev.layerX,y:ev.layerY} doesn't work when zooming with mac chrome 27
// {x:ev.clientX,y:ev.clientY} not supported by mac firefox 21
// document.body.scrollLeft and document.body.scrollTop seem required when scrolling on iPad
// html is not an offsetParent of body but can have non null offsetX or offsetY (case of wordpress 3.5.1 admin pages for instance)
// html.offsetX and html.offsetY don't work with mac firefox 21
var offsetX=0,offsetY=0,e=this,x,y;
var htmls=document.getElementsByTagName("html"),html=(htmls?htmls[0]:0);
do
{
offsetX+=e.offsetLeft-e.scrollLeft;
offsetY+=e.offsetTop-e.scrollTop;
} while (e=e.offsetParent);
if (html)
{
offsetX+=myGetPxStyle(html,"marginLeft");
offsetY+=myGetPxStyle(html,"marginTop");
}
x=ev.pageX-offsetX-document.body.scrollLeft;
y=ev.pageY-offsetY-document.body.scrollTop;
return {x:x,y:y};
}
सबसे पहले, जैसा कि दूसरों ने कहा है, आपको कैनवास तत्व की स्थिति प्राप्त करने के लिए एक फ़ंक्शन की आवश्यकता है । यहां एक विधि है जो इस पृष्ठ (IMHO) के कुछ अन्य लोगों की तुलना में थोड़ी अधिक सुरुचिपूर्ण है। आप इसे किसी भी तत्व को पास कर सकते हैं और दस्तावेज़ में इसकी स्थिति प्राप्त कर सकते हैं :
function findPos(obj) {
var curleft = 0, curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return { x: curleft, y: curtop };
}
return undefined;
}
अब उस के सापेक्ष कर्सर की वर्तमान स्थिति की गणना करें:
$('#canvas').mousemove(function(e) {
var pos = findPos(this);
var x = e.pageX - pos.x;
var y = e.pageY - pos.y;
var coordinateDisplay = "x=" + x + ", y=" + y;
writeCoordinateDisplay(coordinateDisplay);
});
ध्यान दें कि मैंने जेनेरिक findPos
फ़ंक्शन को इवेंट हैंडलिंग कोड से अलग कर दिया है । ( जैसा होना चाहिए । हमें अपने कार्यों को प्रत्येक कार्य के लिए रखने की कोशिश करनी चाहिए।)
के मान offsetLeft
और offsetTop
सापेक्ष हैं offsetParent
, जो कुछ रैपर div
नोड (या उस चीज़ के लिए कुछ और) हो सकते हैं। जब कोई तत्व लपेटते हैं तो canvas
वे उसके सापेक्ष होते हैंbody
, तो , इसलिए घटाने के लिए कोई ऑफसेट नहीं होता है। यही कारण है कि हमें कुछ और करने से पहले कैनवास की स्थिति निर्धारित करने की आवश्यकता है।
सिमिलरी, e.pageX
औरe.pageY
दस्तावेज़ के सापेक्ष कर्सर की स्थिति दें। यही कारण है कि हम सही स्थिति में आने के लिए उन मूल्यों से कैनवास की ऑफसेट को घटाते हैं।
तैनात तत्वों के लिए एक विकल्प सीधे e.layerX
और के मूल्यों का उपयोग करना है e.layerY
। यह दो कारणों से ऊपर की विधि से कम विश्वसनीय है:
थ्रीजेएस आर 7
var x = event.offsetX == undefined ? event.layerX : event.offsetX;
var y = event.offsetY == undefined ? event.layerY : event.offsetY;
mouse2D.x = ( x / renderer.domElement.width ) * 2 - 1;
mouse2D.y = - ( y / renderer.domElement.height ) * 2 + 1;
कई उपाय आजमाने के बाद। इसने मेरे लिए काम किया। इसलिए पोस्ट करने में किसी और की मदद कर सकते हैं। यहीं से मिला
यहाँ एक सरलीकृत समाधान है (यह सीमाओं / स्क्रॉल के साथ काम नहीं करता है):
function click(event) {
const bound = event.target.getBoundingClientRect();
const xMult = bound.width / can.width;
const yMult = bound.height / can.height;
return {
x: Math.floor(event.offsetX / xMult),
y: Math.floor(event.offsetY / yMult),
};
}
मैं एक pdf के ऊपर कैनवास रखने वाला एक एप्लिकेशन बना रहा था , जिसमें कैनवास के बहुत सारे आकार शामिल थे जैसे कि ज़ूम-इन और पीडीएफ को ज़ूम आउट करना और पीडीएफ के प्रत्येक ज़ूम-इन / आउट को चालू करने के लिए मुझे कैनवास को अनुकूलित करना था। pdf का आकार, मैंने स्टैकओवरफ़्लो में बहुत सारे उत्तर दिए, और एक सही समाधान नहीं मिला जो अंततः समस्या का समाधान करेगा।
मैं rxjs और कोणीय 6 का उपयोग कर रहा था , और नवीनतम संस्करण के लिए कोई उत्तर नहीं मिला।
यहां संपूर्ण कोड स्निपेट है जो कैनवास के शीर्ष पर आकर्षित करने के लिए किसी भी rxjs का लाभ उठाने के लिए सहायक होगा ।
private captureEvents(canvasEl: HTMLCanvasElement) {
this.drawingSubscription = fromEvent(canvasEl, 'mousedown')
.pipe(
switchMap((e: any) => {
return fromEvent(canvasEl, 'mousemove')
.pipe(
takeUntil(fromEvent(canvasEl, 'mouseup').do((event: WheelEvent) => {
const prevPos = {
x: null,
y: null
};
})),
takeUntil(fromEvent(canvasEl, 'mouseleave')),
pairwise()
)
})
)
.subscribe((res: [MouseEvent, MouseEvent]) => {
const rect = this.cx.canvas.getBoundingClientRect();
const prevPos = {
x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
const currentPos = {
x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
this.coordinatesArray[this.file.current_slide - 1].push(prevPos);
this.drawOnCanvas(prevPos, currentPos);
});
}
और यहाँ स्निपेट है जो ठीक करता है, माउस कैनवास के आकार के सापेक्ष समन्वयित करता है, भले ही आप कैनवास को ज़ूम-इन / आउट कैसे करें।
const prevPos = {
x: Math.floor( ( res[0].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[0].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
const currentPos = {
x: Math.floor( ( res[1].clientX - rect.left ) / ( rect.right - rect.left ) * this.cx.canvas.width ),
y: Math.floor( ( res[1].clientY - rect.top ) / ( rect.bottom - rect.top ) * this.cx.canvas.height )
};
अरे, यह डोजो में है, बस इसका कारण है कि मेरे पास पहले से ही एक परियोजना के लिए कोड था।
यह काफी स्पष्ट होना चाहिए कि इसे गैर डोजो वेनिला जावास्क्रिप्ट में कैसे परिवर्तित किया जाए।
function onMouseClick(e) {
var x = e.clientX;
var y = e.clientY;
}
var canvas = dojo.byId(canvasId);
dojo.connect(canvas,"click",onMouseClick);
उम्मीद है की वो मदद करदे।