traduccion examples example ejemplos drop bootstrap and javascript math user-interface draggable effect

javascript - examples - droppable



Cálculo de la ventana arrastrando y sesgando en JavaScript (1)

Estoy usando JavaScript y tratando de hacer un efecto de sesgo en un div.

Primero, eche un vistazo a este video: http://www.youtube.com/watch?v=ny5Uy81smpE (0: 40-0: 60 debería ser suficiente). El video muestra algunas transformaciones agradables (sesgar) cuando mueves la ventana. Lo que quiero hacer es lo mismo: sesgar un div cuando lo muevo.

Actualmente solo tengo un simple div:

<div id="a" style="background: #0f0; position: absolute; left: 0px; top: 0px;"></div>

He realizado una transformación simple y sesgada utilizando la propiedad de transformación de CSS3, pero mi implementación tiene errores. ¿Hay buenos tutoriales o sitios o recursos matemáticos que describan la lógica detrás de esto? Conozco JavaScript y CSS lo suficientemente bien como para implementar, si supiera la lógica y las matemáticas. Intenté leer el código fuente de FreeWins , pero no soy bueno en C.

Estoy aceptando cualquier respuesta ingeniosa o pseudo código. Mi sistema de arrastre es parte de un sistema más grande, por lo tanto, ahora que publico un código real, no funciona sin darle todo el sistema (que no puedo hacer en este momento). Por lo tanto, no puede ejecutar este código como es. El código que uso es este (aunque ligeramente modificado) para demostrar mi idea:

/** * The draggable object. */ Draggable = function(targetElement, options) { this.targetElement = targetElement; // Initialize drag data. this.dragData = { startX: null, startY: null, lastX: null, lastY: null, offsetX: null, offsetY: null, lastTime: null, occuring: false }; // Set the cursor style. targetElement.style.cursor = ''move''; // The element to move. this.applyTo = options.applyTo || targetElement; // Event methods for "mouse down", "up" and "move". // Mouse up and move are binded to window. // We can attach and deattach "move" and "up" events as needed. var me = this; targetElement.addEventListener(''mousedown'', function(event) { me.onMouseDown.call(me, event); }, false); this.mouseUp = function(event) { me.onMouseUp.call(me, event); }; this.mouseMove = function(event) { me.onMouseMove.call(me, event); }; }; /** * The mouse down event. * @param {Object} event */ Draggable.prototype.onMouseDown = function(event) { // New drag event. if (this.dragData.occuring === false) { this.dragData.occuring = true; this.dragData.startX = this.dragData.lastX = event.clientX; this.dragData.startY = this.dragData.lastY = event.clientY; this.dragData.offsetX = parseInt(this.applyTo.style.left, 10) - event.clientX; this.dragData.offsetY = parseInt(this.applyTo.style.top, 10) - event.clientY; this.dragData.lastTime = (new Date()).getTime(); // Mouse up and move events. var me = this; window.addEventListener(''mousemove'', this.mouseMove, false); window.addEventListener(''mouseup'', this.mouseUp, false); } }; /** * The mouse movement event. * @param {Object} event */ Draggable.prototype.onMouseMove = function(event) { if (this.dragData.occuring === true) { // He is dragging me now, we move if there is need for that. var moved = (this.dragData.lastX !== event.clientX || this.dragData.lastY !== event.clientY); if (moved === true) { var element = this.applyTo; // The skew animation. :) var skew = (this.dragData.lastX - event.clientX) * 1; var limit = 25; if (Math.abs(skew) > limit) { skew = limit * (skew > 0 ? 1 : -1); } var transform = ''translateX('' + (event.clientX + this.dragData.offsetX - parseInt(element.style.left, 10)) + ''px)''; transform += ''translateY('' + (event.clientY + this.dragData.offsetY - parseInt(element.style.top, 10)) + ''px)''; transform += ''skew('' + skew + ''deg)''; element.style.MozTransform = transform; element.style.webkitTransform = transform; this.dragData.lastX = event.clientX; this.dragData.lastY = event.clientY; this.dragData.lastTime = (new Date()).getTime(); } } }; /** * The mouse up event. * @param {Object} event */ Draggable.prototype.onMouseUp = function(event) { this.dragData.occuring = false; var element = this.applyTo; // Reset transformations. element.style.MozTransform = ''''; element.style.webkitTransform = ''''; // Save the new position. element.style.left = (this.dragData.lastX + this.dragData.offsetX) + ''px''; element.style.top = (this.dragData.lastY + this.dragData.offsetY) + ''px''; // Remove useless events. window.removeEventListener(''mousemove'', this.mouseMove, false); window.removeEventListener(''mousemove'', this.mouseUp, false); };

Actualmente mi sistema de arrastre es buggy y simple. Necesito más información sobre la lógica que debería aplicar.


Vaya, la idea mola . :) He limpiado un poco su código y he resuelto los problemas con la inicialización. Ahora funciona bien para mí en Firefox y Chrome (aunque dijiste que no debería).

Algunas notas:

  • debe tomar las posiciones top e left inicio durante la inicialización ( getBoundingClientRect )
  • almacene referencias como this.dragData y element.style para una ejecución más rápida y rápida
  • dragData se puede inicializar como un objeto vacío. Está bien en javascript. Puede agregar propiedades más tarde.
  • options deben inicializarse condicionalmente como un objeto vacío, para que pueda tomar cero opciones
  • moved y dragData.occuring fueron totalmente inútiles debido a la gestión del evento.
  • preventDefault es necesario para no seleccionar texto durante el arrastre
  • es posible que desee realizar un seguimiento de z-indexes para que sea el elemento activo siempre visible

¡Que te diviertas!

Código [ verlo en acción ]

/** * The draggable object. */ Draggable = function(targetElement, options) { this.targetElement = targetElement; // we can take zero options options = options || {}; // Initialize drag data. // @props: startX, startY, lastX, lastY, // offsetX, offsetY, lastTime, occuring this.dragData = {}; // Set the cursor style. targetElement.style.cursor = ''move''; // The element to move. var el = this.applyTo = options.applyTo || targetElement; // Event methods for "mouse down", "up" and "move". // Mouse up and move are binded to window. // We can attach and deattach "move" and "up" events as needed. var me = this; targetElement.addEventListener(''mousedown'', function(event) { me.onMouseDown.call(me, event); }, false); this.mouseUp = function(event) { me.onMouseUp.call(me, event); }; this.mouseMove = function(event) { me.onMouseMove.call(me, event); }; // initialize position, so it will // be smooth even on the first drag var position = el.getBoundingClientRect(); el.style.left = position.left + "px"; el.style.top = position.top + "px"; el.style.position = "absolute"; if (el.style.zIndex > Draggable.zindex) Draggable.zindex = el.style.zIndex + 1; }; Draggable.zindex = 0; /** * Sets the skew and saves the position * @param {Number} skew */ Draggable.prototype.setSkew = function(skew) { var data = this.dragData; var style = this.applyTo.style; // Set skew transformations. data.skew = skew; style.MozTransform = skew ? ''skew('' + skew + ''deg)'' : ''''; style.webkitTransform = skew ? ''skew('' + skew + ''deg)'' : ''''; // Save the new position. style.left = (data.lastX + data.offsetX) + ''px''; style.top = (data.lastY + data.offsetY) + ''px''; } /** * The mouse down event. * @param {Object} event */ Draggable.prototype.onMouseDown = function(event) { var data = this.dragData; // New drag event. var style = this.applyTo.style; data.startX = data.lastX = event.clientX; data.startY = data.lastY = event.clientY; data.offsetX = parseInt(style.left, 10) - event.clientX; data.offsetY = parseInt(style.top, 10) - event.clientY; style.zIndex = Draggable.zindex++; data.lastTime = (new Date()).getTime(); // Mouse up and move events. window.addEventListener(''mousemove'', this.mouseMove, false); window.addEventListener(''mouseup'', this.mouseUp, false); event.preventDefault(); // prevent text selection }; /** * The mouse movement event. * @param {Object} event */ Draggable.prototype.onMouseMove = function(event) { // He is dragging me now var me = this; var data = me.dragData; var element = me.applyTo; var clientX = event.clientX; var clientY = event.clientY; data.moving = true; // The skew animation. :) var skew = (data.lastX - clientX) * 1; var limit = 25; if (Math.abs(skew) > limit) { skew = limit * (skew > 0 ? 1 : -1); } var style = element.style; var left = parseInt(style.left, 10); var top = parseInt(style.top, 10); var transform = ''translateX('' + (clientX + data.offsetX - left) + ''px)'' + ''translateY('' + (clientY + data.offsetY - top) + ''px)'' + ''skew('' + skew + ''deg)''; style.MozTransform = transform; style.webkitTransform = transform; data.lastX = clientX; data.lastY = clientY; data.lastTime = (new Date()).getTime(); // here is the cooldown part in order // not to stay in disorted state var pre = skew > 0 ? 1 : -1; clearInterval(data.timer); data.timer = setInterval(function() { var skew = data.skew - (pre * 10); skew = pre * skew < 0 ? 0 : skew; me.setSkew(skew); if (data.moving || skew === 0) clearInterval(data.timer); }, 20); data.moving = false; }; /** * The mouse up event. * @param {Object} event */ Draggable.prototype.onMouseUp = function(event) { this.setSkew(''''); // Remove useless events. window.removeEventListener(''mousemove'', this.mouseMove, false); window.removeEventListener(''mousemove'', this.mouseUp, false); };