javascript - Div 位置错误

标签 javascript css

我正在编辑我在 this color picker 中使用的垂直 slider .它使用 top 来调整光标位置。我想改用 transform translateY。当我这样做时,我显然必须以不同的方式计算它。

原来的计算是:( Line: #286 )

hsv_barcursor.style.top = ((1 - color.hsv.v) * hsv_barHeight) + 'px';

我的更新版本是:(下面 JSFiddle 的第 43 行)

hsv_barcursor.style.transform = 'translateY(calc(' + (color.RND.hsv.v * 10) + '% - ' + cursorRadius + 'px))';

我的版本位置不对

  1. 为什么 top 的数学运算不适用于 tranlateY
  2. translateY 的正确数学是什么?

我不是在寻找 JQuery 答案,也不是在寻找 html 的 输入范围。

JSFiddle

var luminenceBarWrapper = document.getElementById('luminenceBarWrapper'),
  hsv_barBGLayer = document.getElementById('bar-bg'),
  hsv_barcursor = document.getElementById('hsv-barcursor'),
  hsv_barCursors = document.getElementById('hsv-barcursors'),

  hsv_barHeight = hsv_barCursors.offsetHeight,
  cursorRadius = hsv_barcursor.offsetHeight / 2,
  startPoint,
  currentTarget,
  myColor = new Colors();

// Create Event Functions
var hsvDown = function(e) { // mouseDown callback
    e.preventDefault();

    if (e.target === hsv_barcursor) currentTarget = e.target.parentNode;
    else if (e.target === hsv_barCursors) currentTarget = e.target;
    else return;

    startPoint = getOrigin(currentTarget);

    window.addEventListener('mousemove', hsvMove);
    hsvMove(e);
    startRender();
  },
  hsvMove = function(e) { // mouseMove callback
    myColor.setColor({
      v: (hsv_barHeight - (e.clientY - startPoint.top)) / hsv_barHeight * 100
    }, 'hsv');
  };

// Initial Rendering
doRender(myColor.colors);

// Adde Events To Objects
luminenceBarWrapper.addEventListener('mousedown', hsvDown);
window.addEventListener('mouseup', function() {
  window.removeEventListener('mousemove', hsvMove);
  stopRender();
});

function doRender(color) {
  hsv_barcursor.style.transform = 'translateY(calc(' + (color.RND.hsv.v * 10) + '% - ' + cursorRadius + 'px))';
  //hsv_barcursor.style.top = ((1 - color.hsv.v) * hsv_barHeight) + 'px';
}

var renderTimer,
  startRender = function(oneTime) {
    renderTimer = window.setInterval(function() {
      doRender(myColor.colors);
    }, 13); // 1000 / 60); // ~16.666 -> 60Hz or 60fps
  },
  stopRender = function() {
    window.clearInterval(renderTimer);
  };

function getOrigin(elm) {
  var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {
      top: 0,
      left: 0
    },
    doc = elm && elm.ownerDocument,
    body = doc.body,
    win = doc.defaultView || doc.parentWindow || window,
    docElem = doc.documentElement || body.parentNode,
    clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both
    clientLeft = docElem.clientLeft || body.clientLeft || 0;

  return {
    left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft,
    top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop
  };
}
body {
  position: absolute;
}
#bar-bg {
  width: 15px;
  height: 500px;
  background-color: greenyellow;
}
#hsv-barcursors {
  position: absolute;
  right: -7.5px;
  width: 30px;
  top: 0;
  height: 500px;
  overflow: hidden;
  cursor: pointer;
}
#hsv-barcursor {
  position: absolute;
  right: 7.5px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 2px solid black;
  margin-bottom: 5px;
}
<script src="https://rawgit.com/PitPik/colorPicker/master/colors.js"></script>

<div id="luminenceBarWrapper">
  <div id="bar-bg"></div>
  <div id="hsv-barcursors" id="hsv_cursors">
    <div id="hsv-barcursor"></div>
  </div>
</div>

最佳答案

translateY(Npx) 如果 N > 0 则向下平移一些东西,因此当标记向上并且 时你需要 translate(0px) >translate(Npx) 当标记位于组件底部时

你的变量是

  • color.RND.hsv.v 当标记向上时为 100,当标记向下时为 0
  • hsv_barHeight 是你的组件的高度

第一步是反转 color.RND.hsv.v 的值,即 (100 - color.RND.hsv.v) 接下来我们将映射它到 [0,1] 范围,这是通过一个简单的除法简单完成的,即 t = (100 - color.RND.hsv.v)/100 我们这样做高度与此值 t 线性映射到 [0, height] 范围内,即 (100 - color.RND.hsv.v)/100 * hsv_barHeight 这是最终的等式

var luminenceBarWrapper = document.getElementById('luminenceBarWrapper'),
  hsv_barBGLayer = document.getElementById('bar-bg'),
  hsv_barcursor = document.getElementById('hsv-barcursor'),
  hsv_barCursors = document.getElementById('hsv-barcursors'),

  hsv_barHeight = hsv_barCursors.offsetHeight,
  cursorRadius = hsv_barcursor.offsetHeight / 2,
  startPoint,
  currentTarget,
  myColor = new Colors();

// Create Event Functions
var hsvDown = function(e) { // mouseDown callback
    e.preventDefault();

    if (e.target === hsv_barcursor) currentTarget = e.target.parentNode;
    else if (e.target === hsv_barCursors) currentTarget = e.target;
    else return;

    startPoint = getOrigin(currentTarget);

    window.addEventListener('mousemove', hsvMove);
    hsvMove(e);
    startRender();
  },
  hsvMove = function(e) { // mouseMove callback
    myColor.setColor({
      v: (hsv_barHeight - (e.clientY - startPoint.top)) / hsv_barHeight * 100
    }, 'hsv');
  };

// Initial Rendering
doRender(myColor.colors);

// Adde Events To Objects
luminenceBarWrapper.addEventListener('mousedown', hsvDown);
window.addEventListener('mouseup', function() {
  window.removeEventListener('mousemove', hsvMove);
  stopRender();
});

function doRender(color) {
  hsv_barcursor.style.transform = 'translateY(' + (100 - color.RND.hsv.v) / 100 * (hsv_barHeight - cursorRadius) + 'px)';
  //hsv_barcursor.style.top = ((1 - color.hsv.v) * hsv_barHeight) + 'px';
}

var renderTimer,
  startRender = function(oneTime) {
    renderTimer = window.setInterval(function() {
      doRender(myColor.colors);
    }, 13); // 1000 / 60); // ~16.666 -> 60Hz or 60fps
  },
  stopRender = function() {
    window.clearInterval(renderTimer);
  };

function getOrigin(elm) {
  var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {
      top: 0,
      left: 0
    },
    doc = elm && elm.ownerDocument,
    body = doc.body,
    win = doc.defaultView || doc.parentWindow || window,
    docElem = doc.documentElement || body.parentNode,
    clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both
    clientLeft = docElem.clientLeft || body.clientLeft || 0;

  return {
    left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft,
    top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop
  };
}
body {
  position: absolute;
}
#bar-bg {
  width: 15px;
  height: 500px;
  background-color: greenyellow;
}
#hsv-barcursors {
  position: absolute;
  right: -7.5px;
  width: 30px;
  top: 0;
  height: 500px;
  overflow: hidden;
  cursor: pointer;
}
#hsv-barcursor {
  position: absolute;
  right: 7.5px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 2px solid black;
  margin-bottom: 5px;
}
<script src="https://rawgit.com/PitPik/colorPicker/master/colors.js"></script>

<div id="luminenceBarWrapper">
  <div id="bar-bg"></div>
  <div id="hsv-barcursors" id="hsv_cursors">
    <div id="hsv-barcursor"></div>
  </div>
</div>

关于javascript - Div 位置错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37017319/

相关文章:

javascript - jquery 添加带有动态 url 的背景图片

javascript - 有没有办法在 es6 中导入一个只适用于一个特定元素并且不是全局的 css 文件?

javascript - NodeJS - Electron 托盘图标一分钟后消失

javascript - 以声明方式更新组件内的标记

jquery - bootstrap 2.0 通过选项卡内容中的 url 激活选项卡和数据

css - 通过r.js优化require.js/backbone app css文件是否包含cdn @imports

html - Bootstrap容器间距

javascript - Angular ui.grid。在两个网格之间移动行

javascript - 正在加载并等待 "global" meteor 订阅

javascript - 在 Javascript 中获取第一个数字出现后的子字符串