Поместите центр элемента в верхний левый угол с помощью css для ссылки «transform» на центр элемента. - PullRequest
0 голосов
/ 01 сентября 2018

Я хочу разместить центр элемента там же, где был нажат: while click enter image description here

Для этого я хочу использовать transform, но для исходного свойства css я не могу использовать:

#element{
  position:fixed;
  top:0;
  left:0;
   transform:translate(-50%, -50%);
}
Поскольку исходная ссылочная позиция одинакова и при использовании transform , она не будет работать при переводе, используйте следующие примеры:

let action1=document.querySelector("#actions1");
let action2=document.querySelector("#actions2");
let action3=document.querySelector("#actions3");
let action4=document.querySelector("#actions4");
let boton1=document.querySelector("#me1");
let boton2=document.querySelector("#me2");
let boton3=document.querySelector("#me3");
let boton4=document.querySelector("#me4");
boton1.addEventListener("click",move1);
boton2.addEventListener("click",move2);
boton3.addEventListener("click",move3);
boton4.addEventListener("click",move4);
function move1(e){
  let startX=e.clientX || e.touches[0].clientX;
  let startY=e.clientY || e.touches[0].clientY;
  action1.style.display="grid";
  action2.style.display="none";
  action3.style.display="none";
  action4.style.display="none";
  action1.style.transform="translate("+startX+"px,"+startY+"px)";
}
function move2(e){
  let startX=e.clientX || e.touches[0].clientX;
  let startY=e.clientY || e.touches[0].clientY;
  action2.style.display="grid";
  action1.style.display="none";
  action3.style.display="none";
  action4.style.display="none";
  action2.style.transform="translate("+startX+"px,"+startY+"px)";
}
function move3(e){
  let startX=e.clientX || e.touches[0].clientX;
  let startY=e.clientY || e.touches[0].clientY;
  action3.style.display="grid";
  action1.style.display="none";
  action2.style.display="none";
  action4.style.display="none";
  action3.style.transform="translate("+startX+"px,"+startY+"px)";
}
function move4(e){
  let startX=e.clientX || e.touches[0].clientX;
  let startY=e.clientY || e.touches[0].clientY;
  action4.style.display="grid";
  action1.style.display="none";
  action2.style.display="none";
  action3.style.display="none";
  let size=action4.getBoundingClientRect();
  action4.style.top=startY-(size.height/2)+"px";
  action4.style.left=startX-(size.width/2)+"px";
}
#actions1,#actions2,#actions3,#actions4{
  display:none;grid-template-columns:auto;grid-gap:5px;
    padding:10px;
}
#actions1{
    position:fixed;top:0;left:0;
}
#actions2{
    position:fixed;top:0;left:0;
    transform:translate(-50%, -50%);
}
#actions3{
    position:fixed;top:-40px;left:-45px;
}
#actions4{
    position:fixed;top:0;left:0;
}
#botons{
  position:fixed;
  top: 50px;left:0;right:0;
  display:flex;
  justify-content: space-around;
}
<div id="botons">
 <button id="me1">normal</button>
 <button id="me2">not posible to reference with transform</button>
 <button id="me3">desirable</button>
 <button id="me4">old school</button>
</div>
 <div id="actions1">
        <button>open1</button>
        <button>new1</button>
        <button>delete1</button>
 </div>
 <div id="actions2">
        <button>open2</button>
        <button>new2</button>
        <button>delete2</button>
 </div>
 <div id="actions3">
        <button>open3</button>
        <button>new3</button>
        <button>delete3</button>
 </div>
 <div id="actions4">
        <button>open4</button>
        <button>new4</button>
        <button>delete4</button>
 </div>

Как видите, первый пример и второй ведут себя одинаково, поскольку исходная ссылочная позиция элемента не изменяется, оба имеют:

#element{
    position:fixed;top:0;left:0;
}
Третий пример показывает желаемый результат, но этот метод заставляет меня все время знать ширину и высоту, он не будет работать, если я добавлю детей к этому элементу, последний пример показывает, как старая школа будет это делать, что будет принимая размер, а затем делим на 2, проблема в том, что это хак, и потому что преобразование имеет лучшую производительность по сравнению с изменением позиции напрямую.

1 Ответ

0 голосов
/ 02 сентября 2018

Если вы щелкнете в любом месте демо-кнопки, в центре кнопки вашего курсора внутри кнопки будет отображаться .dropdown-menu.

Не слишком хакерский, потому что его position: absolute внутри .btn-group, используя transform: translate(-50%,-50%), чтобы центрировать его по левому верхнему углу.

Вы можете добавить столько же кнопок к .dropdown-menu, и они всегда будут в центре вашего клика.

Вероятно, лучше всего визуализировать кнопки внутри .dropdown-menu при загрузке страницы, но если у вас есть динамические кнопки для добавления через javascript, тогда добавляйте кнопки, когда вам нужно.

Вам нужно вызвать метод .hide() a .dropdown-menu при щелчке по меню, что должно быть достаточно просто.

См. http://jsfiddle.net/joshmoto/sdn5eboa/ тоже, если вы хотите играть.

Выполните код ниже, чтобы увидеть пример ...

// demo button click event
$('.btn-demo').on('click', function(e) {
	
  // get the next element matching .dropdown-menu
  var $dropdown_menu = $(this).next('.dropdown-menu');
	
  // your custom button or add these however method you are doing
  var btn_1 = '<button class="dropdown-item" type="button">Button 1</button>';
  var btn_2 = '<button class="dropdown-item" type="button">Button 2</button>';
  var btn_3 = '<button class="dropdown-item" type="button">Button 3</button>';
  
  // add the desired buttons to the .dropdown-menu on click
  $dropdown_menu.html(btn_1 + btn_2 + btn_3);
  
  // add this css to .dropdown-menu menu on click
  $dropdown_menu.css({
  
    //  top postion: cursor click postion minus .btn-demo top-offset position
    top: (e.pageY - $(this).offset().top),
  	
    // left postion: cursor click postion minus .btn-demo left-offset position
    left: (e.pageX - $(this).offset().left),
    
    // display block to reveal the .dropdown-menu or use .show() function
    // display: 'block'
    
  }).show();

});
@import 'http://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css';

HTML,
BODY {
  height: 100%;
  min-height: 100%;
  cursor: crosshair;
  width: 100%;
}

BUTTON {
  cursor: crosshair !important;
}

.btn-group {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
}

.dropdown-menu {
  transform: translate(-50%,-50%);
  position: absolute;
  display: none;
  z-index: 1000;
  float: left;
  min-width: 0;
}
<!-- demo containers to center .btn-group please ignore this -->
<div class="d-flex align-items-center h-100">
  <div class="container">
    <div class="col-12 text-center">
      
      <!-- question related code only -->
      <div class="btn-group">
        <button class="btn btn-primary btn-demo">
          Long demo button title for testing
        </button>
        <div class="dropdown-menu"></div>
      </div>
      
    </div>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Перевести только версию

См. Ниже transform: translate() только версия для размещения центра выпадающего меню внутри кнопки на курсоре мыши.

Вот также jsfiddle: http://jsfiddle.net/joshmoto/2qLvp5a3/

// demo button click event
$('.btn-demo').on('click', function(e) {

  // get the next element matching .dropdown-menu
  var $dropdown_menu = $(this).next('.dropdown-menu');

  // your custom button or add these however method you are doing
  var btn_1 = '<button class="dropdown-item" type="button">Button 1</button>';
  var btn_2 = '<button class="dropdown-item" type="button">Button 2</button>';
  var btn_3 = '<button class="dropdown-item" type="button">Button 3</button>';

  // add the desired buttons to the .dropdown-menu on click
  $dropdown_menu.html(btn_1 + btn_2 + btn_3);
  
  // show the dropdown menu so we can get its width height
  // currently hidden using css opacity: 0;
  $dropdown_menu.show();
  
  // dropdown menu width height
  var ddm_w = $dropdown_menu.outerWidth();
  var ddm_h = $dropdown_menu.outerHeight();

  // click position values inside button
  var click_x = e.pageX - $(this).offset().left;
  var click_y = e.pageY - $(this).offset().top;
  
  // new translate positions for center menu
  var trans_x = click_x - (ddm_w / 2);
  var trans_y = click_y - (ddm_h / 2);

  // add this css to .dropdown-menu menu on click
  $dropdown_menu.css({
		
    // translate position to top left corner of dropdown
    'transform' : 'translate(' + trans_x + 'px,' + trans_y + 'px)',
    
    // reveal the dropdown menu
    'opacity' : 1
	
  });

});
@import 'http://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css';

HTML,
BODY {
  height: 100%;
  min-height: 100%;
  cursor: crosshair;
  width: 100%;
}

BUTTON {
  cursor: crosshair !important;
}

.btn-group {
  position: relative;
  display: inline-flex;
  vertical-align: middle;
}

.dropdown-menu {
  opacity: 0;
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  float: left;
  min-width: 0;
  margin: 0;
}
<!-- demo containers to center .btn-group please ignore this -->
<div class="d-flex align-items-center h-100">
  <div class="container">
    <div class="col-12 text-center">
      
      <!-- question related code only -->
      <div class="btn-group">
        <button class="btn btn-primary btn-demo" type="button">
          Long demo button title for testing
        </button>
        <div class="dropdown-menu">
        </div>
      </div>

    </div>
  </div>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
...