jQuery-点击图像上的坐标并在那里画一个圆圈

我有一个divimage_preview ,里面有一个图像。 有一个输入框可以从用户那里获得圆的半径。 当我点击图像上的某个点时,我需要一个圆圈,以该点为中心,半径输入为半径。 圆圈应标有标记。 id为hotspot_displaydiv用作标记, div circle用作要显示的圆圈。 两者都绝对定位。 标记的背景为尺寸为24X24的图像。

每当我点击时,标记和圆圈的克隆都会被制作并定位在我点击的点周围。 单击鼠标即可更改标记和圆圈位置(您可以在此问题的末尾找到小提琴链接)。

我可以捕获我用offsetclientX等点击的点的坐标,其代码如下:

HTML:图片:

  
background

JS:

  $('#image_preview').bind('click', function (ev) { var $div = $(ev.target); var $div = $(this); var $display = $('#image_preview').find('#hotspot_display'); var offset_t = $(this).offset().top - $(window).scrollTop(); var offset_l = $(this).offset().left - $(window).scrollLeft(); var left = Math.round( (ev.clientX - offset_l) ); var top = Math.round( (ev.clientY - offset_t) ); if(window.console){ console.log("left = "+left+" top = "+top); } var display_clone=$display.clone().show(); display_clone.css({'top':top+33,'left':left+10,'display':'block'}); }); 

display_clone.css的代码在其参数中有一些值(33和10)添加到lefttop没有这些值我无法让图像标记的中心位于坐标上。

问题1)我只是随机使用了要添加的33和10值。 这里应该做什么计算,因为要添加的这些数字可能会有所不同如果我的HTML代码位于复杂的HTML页面中?

问题2 :我不能让圆圈的中心成为我点击的坐标。 这里的方式应该是什么?

整个场景都在这里 。

编辑:我的方案实际上有2个部分。 上述情况发生在管理区域。 在用户区域中,我再次在div显示图像,即hotspot_user_area 。 我从管理区域将已点击的坐标保存在数据库中。 在用户I区域,我有HTML:

 
background

我从数据库中获取坐标,并希望在图像的hotspot_user_area使用标记显示它们。 假设我从DB获得坐标变量x1y1 ; 现在,如果我使用Roko C. Buljan的答案中的以下代码,它将无效:

  $("
", { "class": "circle", css: { top: y1, left: x1, width: r * 2, height: r * 2, }, appendTo: $this // append to #image_preview! }).

这不起作用,因为在管理面板中, lefttop属性分别具有值xy ,具有以下计算:

 y = ev.pageY - o.top, x = ev.pageX - o.left; 

那么如何将图像放置在图像的同一位置,无论图像再次放置在哪个div中?

这是一个更简单的方法:

  • 让中心使用类似ev.pageX - el.offset().left
  • 不要克隆元素。 动态创建它们。
  • 使用CSS transform translate来居中
 var App = App || {}; App.points = []; // Use array to store objects like [{x,y,r}, {x,y,r} ...] jQuery(function($) { const $radius = $(".radius"); $('#image_preview').on('click', function(ev) { const $this = $(this), r = parseInt($radius.val().trim(), 10), // Parse as Integer radix 10 o = $this.offset(), y = ev.pageY - o.top, x = ev.pageX - o.left; $("
", { "class": "circle", css: { top: y, left: x, width: r * 2, height: r * 2, }, appendTo: $this // append to #image_preview! }); // Append data to App.points App.points.push({x,y,r}); // Test console.log( App.points ) }); });
 #image_preview { position: relative; /* Add this since child are absolute! */ background: #eee; margin: 15px; cursor: crosshair; } #image_preview img { display: inline-block; vertical-align: top; } .circle { position: absolute; background: rgba(255, 0, 0, 0.2) url("https://i.imgur.com/qtpC8Rf.png") no-repeat 50% 50%; border-radius: 50%; transform: translate(-50%, -50%); /* use translate instead of JS calculations */ } .radius { position: absolute; } 
 Radius:  
graph