jQuery-点击图像上的坐标并在那里画一个圆圈
我有一个div
即image_preview
,里面有一个图像。 有一个输入框可以从用户那里获得圆的半径。 当我点击图像上的某个点时,我需要一个圆圈,以该点为中心,半径输入为半径。 圆圈应标有标记。 id为hotspot_display
的div
用作标记, div
circle
用作要显示的圆圈。 两者都绝对定位。 标记的背景为尺寸为24X24的图像。
每当我点击时,标记和圆圈的克隆都会被制作并定位在我点击的点周围。 单击鼠标即可更改标记和圆圈位置(您可以在此问题的末尾找到小提琴链接)。
我可以捕获我用offset
和clientX
等点击的点的坐标,其代码如下:
HTML:图片:
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)添加到left
和top
没有这些值我无法让图像标记的中心位于坐标上。
问题1)我只是随机使用了要添加的33和10值。 这里应该做什么计算,因为要添加的这些数字可能会有所不同如果我的HTML代码位于复杂的HTML页面中?
问题2 :我不能让圆圈的中心成为我点击的坐标。 这里的方式应该是什么?
整个场景都在这里 。
编辑:我的方案实际上有2个部分。 上述情况发生在管理区域。 在用户区域中,我再次在div
显示图像,即hotspot_user_area
。 我从管理区域将已点击的坐标保存在数据库中。 在用户I区域,我有HTML:
我从数据库中获取坐标,并希望在图像的hotspot_user_area
使用标记显示它们。 假设我从DB获得坐标变量x1
和y1
; 现在,如果我使用Roko C. Buljan的答案中的以下代码,它将无效:
$("", { "class": "circle", css: { top: y1, left: x1, width: r * 2, height: r * 2, }, appendTo: $this // append to #image_preview! }).
这不起作用,因为在管理面板中, left
和top
属性分别具有值x
和y
,具有以下计算:
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: