javascript – Div不在正确的位置

前端之家收集整理的这篇文章主要介绍了javascript – Div不在正确的位置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在使用这个color wheel picker,我正在尝试添加div作为拖动器,而不是将其嵌入到画布中.

我创建了一个外部div(一个包装器),并插入了一个div(dragger),然后是画布.我把拖拉机的位置变成了绝对的位置.然后在重绘(e)函数中,我将左侧和顶部设置为以下内容

  1. dragger.style.left = currentX + 'px';
  2. dragger.style.top = currentY + 'px';

这有效,即拖拉机应该移动,但它处于错误的位置.

如何让拖动器与光标位于同一位置?

JSFiddle

  1. var b = document.body;
  2. var c = document.getElementsByTagName('canvas')[0];
  3. var a = c.getContext('2d');
  4. var wrapper = document.getElementById('wrapper');
  5. var dragger = document.createElement('div');
  6. dragger.id = 'dragger';
  7. wrapper.appendChild(dragger);
  8. wrapper.insertBefore(dragger,c);
  9. document.body.clientWidth; // fix bug in webkit: http://qfox.nl/weblog/218
  10. (function() {
  11. // Declare constants and variables to help with minification
  12. // Some of these are inlined (with comments to the side with the actual equation)
  13. var doc = document;
  14. doc.c = doc.createElement;
  15. b.a = b.appendChild;
  16. var width = c.width = c.height = 400,label = b.a(doc.c("p")),input = b.a(doc.c("input")),imageData = a.createImageData(width,width),pixels = imageData.data,oneHundred = input.value = input.max = 100,circleOffset = 10,diameter = 380,//width-circleOffset*2,radius = 190,//diameter / 2,radiusPlusOffset = 200,//radius + circleOffset
  17. radiusSquared = radius * radius,two55 = 255,currentY = oneHundred,currentX = -currentY,wheelPixel = 16040; // circleOffset*4*width+circleOffset*4;
  18. // Math helpers
  19. var math = Math,PI = math.PI,PI2 = PI * 2,sqrt = math.sqrt,atan2 = math.atan2;
  20. // Setup DOM properties
  21. b.style.textAlign = "center";
  22. label.style.font = "2em courier";
  23. input.type = "range";
  24. // Load color wheel data into memory.
  25. for (y = input.min = 0; y < width; y++) {
  26. for (x = 0; x < width; x++) {
  27. var rx = x - radius,ry = y - radius,d = rx * rx + ry * ry,rgb = hsvToRgb(
  28. (atan2(ry,rx) + PI) / PI2,// Hue
  29. sqrt(d) / radius,// Saturation
  30. 1 // Value
  31. );
  32. // Print current color,but hide if outside the area of the circle
  33. pixels[wheelPixel++] = rgb[0];
  34. pixels[wheelPixel++] = rgb[1];
  35. pixels[wheelPixel++] = rgb[2];
  36. pixels[wheelPixel++] = d > radiusSquared ? 0 : two55;
  37. }
  38. }
  39. // Bind Event Handlers
  40. input.onchange = redraw;
  41. c.onmousedown = doc.onmouseup = function(e) {
  42. // Unbind mousemove if this is a mouseup event,or bind mousemove if this a mousedown event
  43. doc.onmousemove = /p/.test(e.type) ? 0 : (redraw(e),redraw);
  44. }
  45. // Handle manual calls + mousemove event handler + input change event handler all in one place.
  46. function redraw(e) {
  47. // Only process an actual change if it is triggered by the mousemove or mousedown event.
  48. // Otherwise e.pageX will be undefined,which will cause the result to be NaN,so it will fallback to the current value
  49. currentX = e.pageX - c.offsetLeft - radiusPlusOffset || currentX;
  50. currentY = e.pageY - c.offsetTop - radiusPlusOffset || currentY;
  51. // Scope these locally so the compiler will minify the names. Will manually remove the 'var' keyword in the minified version.
  52. var theta = atan2(currentY,currentX),d = currentX * currentX + currentY * currentY;
  53. // If the x/y is not in the circle,find angle between center and mouse point:
  54. // Draw a line at that angle from center with the distance of radius
  55. // Use that point on the circumference as the draggable location
  56. if (d > radiusSquared) {
  57. currentX = radius * math.cos(theta);
  58. currentY = radius * math.sin(theta);
  59. theta = atan2(currentY,currentX);
  60. d = currentX * currentX + currentY * currentY;
  61. }
  62. label.textContent = b.style.background = hsvToRgb(
  63. (theta + PI) / PI2,// Current hue (how many degrees along the circle)
  64. sqrt(d) / radius,// Current saturation (how close to the middle)
  65. input.value / oneHundred // Current value (input type="range" slider value)
  66. )[3];
  67. dragger.style.left = currentX + 'px';
  68. dragger.style.top = currentY + 'px';
  69. // Reset to color wheel and draw a spot on the current location.
  70. a.putImageData(imageData,0);
  71. // Draw the current spot.
  72. // I have tried a rectangle,circle,and heart shape.
  73. /*
  74. // Rectangle:
  75. a.fillStyle = '#000';
  76. a.fillRect(currentX+radiusPlusOffset,currentY+radiusPlusOffset,6,6);
  77. */
  78. /*
  79. // Circle:
  80. a.beginPath();
  81. a.strokeStyle = '#000';
  82. a.arc(~~currentX+radiusPlusOffset,~~currentY+radiusPlusOffset,4,PI2);
  83. a.stroke();
  84. */
  85. // Heart:
  86. a.font = "1em arial";
  87. a.fillText("♥",currentX + radiusPlusOffset - 4,currentY + radiusPlusOffset + 4);
  88. }
  89. // Created a shorter version of the HSV to RGB conversion function in TinyColor
  90. // https://github.com/bgrins/TinyColor/blob/master/tinycolor.js
  91. function hsvToRgb(h,s,v) {
  92. h *= 6;
  93. var i = ~~h,f = h - i,p = v * (1 - s),q = v * (1 - f * s),t = v * (1 - (1 - f) * s),mod = i % 6,r = [v,q,p,t,v][mod] * two55,g = [t,v,p][mod] * two55,b = [p,q][mod] * two55;
  94. return [r,g,b,"rgb(" + ~~r + "," + ~~g + "," + ~~b + ")"];
  95. }
  96. // Kick everything off
  97. redraw(0);
  98. /*
  99. // Just an idea I had to kick everything off with some changing colors…
  100. // Probably no way to squeeze this into 1k,but it could probably be a lot smaller than this:
  101. currentX = currentY = 1;
  102. var interval = setInterval(function() {
  103. currentX--;
  104. currentY*=1.05;
  105. redraw(0)
  106. },7);
  107. setTimeout(function() {
  108. clearInterval(interval)
  109. },700)
  110. */
  111. })();
  1. #wrapper {
  2. width: 400px;
  3. height: 400px;
  4. position: relative;
  5. }
  6. #dragger {
  7. background-color: orange;
  8. width: 15px;
  9. height: 15px;
  10. border-radius: 50%;
  11. position: relative;
  12. }
最佳答案
我通过操纵currentX和currentY坐标得到了它.上述评论者接近解决方案;必须将~50%的高度和宽度添加到相对位置.我还建议在拖动器上使用z-index属性,如果您希望心脏位于顶部以及它与色轮之间的拖动器.

具有适当偏移的最终版本和正确版本:Fiddle

如果拖动器的尺寸从15px减小到5px,则分别添加7和4px:
https://jsfiddle.net/6n9zwahL/(固定金额)或https://jsfiddle.net/mak3Lace/(非固定,程序化解决方案).

  1. dragger.style.left = (currentX + radiusPlusOffset + (radiusPlusOffset/30)) + 'px';
  2. dragger.style.top = (currentY + radiusPlusOffset+(radiusPlusOffset/40)) + 'px';

在我有时间编辑之前保留历史回复

Forked Fiddle

代码 – 这里是以像素为单位手动完成的,但我创建了一个变量,并通过查询浏览器的宽度将其设置为更准确的值:

  1. dragger.style.left = currentX + 210 + 'px';
  2. dragger.style.top = currentY +195 + 'px';

New Fiddle,with dragger exactly aligned to heart

新职位:

  1. dragger.style.left = currentX + 204 + 'px';
  2. dragger.style.top = currentY +199 + 'px';

添加了一个改进ux的指针:https://jsfiddle.net/4cLpvu2m/

要进一步详细说明,请使用您拥有的心脏位置代码

  1. currentX + radiusPlusOffset - 4,currentY + radiusPlusOffset + 4

查询浏览器拖拉机div的位置.然后简单地从x-dragger中减去x,从y-dragger中减去y以获得差异.将差异添加到dragger.style.left等等(碰巧这些数字是~204和199).

Another fork with alerts indicating x/y position values

杰西卡的更新,删除/ -4以对齐元素:
https://jsfiddle.net/hf5k2ecg/

猜你在找的CSS相关文章