Проблема с захватом мышью
Вложений: 2
Стал решать задачу с этого сайта, где картинку нужно таскать за правый нижний угол, изменяя её размер. Для этого в углу создаётся элемент для захвата. Но при выходе за его пределы mousedown не срабатывает, а срабатывает лишь при повторном нажатии. Изучение решения на сайте не помогло, т. к. оно существенно отличается от моего. Помогите, пожалуйста. Текст ниже. Картинки присоединяю.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://code.jquery.com/jquery-latest.js"></script> </head> <body> <div style="width:503px;height:285px;background-color:grey;position:relative" id="skin"> <img style="width:500px;height:282px;position:absolute" id="heroes" src="heroes.jpg"> <img style="position:absolute;right:0;bottom:0" id="corner" src="handle-se.png"> </div> <div id="info"></div> <script> function Resizeable(options) { var elem = options.elem; elem.move=false; elem.on('mousedown', capture); elem.on('mousemove', cursorMove); elem.on('mouseup', release); function capture(e){ if($(e.target).attr('id')=='corner' && elem.move==false){ elem.move=true; getCoords(e); console.log(elem.x+' '+elem.y); } } function cursorMove(e){ if(elem.move==true){ size($('#skin'), e); size($('#heroes'), e); } getCoords(e); } function release(e){ elem.move=false; } function size(rect, e){ rect.css('height',rect.height()-(elem.y-e.pageY)) .css('width',rect.width()-(elem.x-e.pageX)); } function getCoords(e){ elem.x=e.pageX; elem.y=e.pageY; } } </script> </body> </html> |
Моя попытка:
<!DOCTYPE html> <style> .resizeable{ padding: 10px; position: relative; -moz-box-sizing: border-box; box-sizing: border-box; } .resizeable .resizer{ position: absolute; bottom: 0; right: 0; width: 16px; height: 16px; background: url(http://javascript.ru/forum/attachments/jquery/2137d1394200133-problema-s-zakhvatom-myshyu-handle-se-png); cursor: se-resize; } .resizeable img{ width: 100%; height: 100%; } </style> <div class="resizeable" style="width: 750px; height: 258px"> <img src="http://upload.wikimedia.org/wikipedia/commons/a/aa/Logo_Google_2013_Official.svg" alt="" /> </div> <script> function Resizeable(element) { this.element = element; this.resizer = document.createElement('div'); this.resizer.className = 'resizer'; this.element.appendChild(this.resizer); this.resizer.addEventListener('mousedown', this); this.startMousePosition = null; this.startElementDimension = null; } Resizeable.prototype.handleEvent = function(event) { this['handle' + event.type.charAt(0).toUpperCase() + event.type.slice(1) + 'Event'](event); }; Resizeable.prototype.handleMousedownEvent = function(event) { if (this.element.setCapture) this.element.setCapture(); window.addEventListener('mousemove', this); window.addEventListener('mouseup', this); this.startMousePosition = {x: event.pageX, y: event.pageY}; this.startElementDimension = {width: this.element.offsetWidth, height: this.element.offsetHeight}; event.preventDefault(); }; Resizeable.prototype.handleMousemoveEvent = function(event) { var offset = { x: event.pageX - this.startMousePosition.x, y: event.pageY - this.startMousePosition.y, }; console.log(event); this.element.style.width = this.startElementDimension.width + offset.x + 'px'; this.element.style.height = this.startElementDimension.height + offset.y + 'px'; }; Resizeable.prototype.handleMouseupEvent = function(event) { window.removeEventListener('mousemove', this); window.removeEventListener('mouseup', this); if (this.element.releaseCapture) this.element.releaseCapture(); this.startMousePosition = null; }; new Resizeable(document.querySelector('.resizeable')); </script> Для работы в IE8 нужен костыль для addEventListener |
Рабочий вариант есть и на сайте. Хотелось бы понять, почему мой вариант не работает в Mozilla. У меня пока небольшой опыт работы с jQuery
|
Цитата:
|
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <script src="http://code.jquery.com/jquery-latest.js"></script> </head> <body> <div style="width:503px;height:285px;background-color:grey;position:relative" id="skin"> <img style="width:500px;height:282px;position:absolute" id="heroes" src="http://javascript.ru/forum/attachments/jquery/2136d1394200133t-problema-s-zakhvatom-myshyu-heroes-jpg"> <img style="position:absolute;right:0;bottom:0" id="corner" src="http://javascript.ru/forum/attachments/jquery/2137d1394200133-problema-s-zakhvatom-myshyu-handle-se-png"> </div> <div id="info"></div> <script> function Resizeable(options) { var elem = options.elem; elem.move=false; elem.on('mousedown', capture); *!* //mousemove и mouseup нужно отслеживать на документе а не конкретно на этом элементе. $(document).on('mousemove', cursorMove); $(document).on('mouseup', release); */!* function capture(e){ if($(e.target).attr('id')=='corner' && elem.move==false){ elem.move=true; getCoords(e); console.log(elem.x+' '+elem.y); return false; } } function cursorMove(e){ if(elem.move==true){ size($('#skin'), e); size($('#heroes'), e); } getCoords(e); } function release(e){ elem.move=false; } function size(rect, e){ rect.css('height',rect.height()-(elem.y-e.pageY)) .css('width',rect.width()-(elem.x-e.pageX)); } function getCoords(e){ elem.x=e.pageX; elem.y=e.pageY; } } *!* //тут строчку нужно было дописать */!* Resizeable({'elem': $('#corner')}); </script> </body> </html> |
Zuenf,
неплохобы return false поставить в строку 38 а то браузер картинку копирует |
рони, поправил.
|
:write:
ещё можно убрать строку 35 и стиль из строки 10 и заменить на <style type="text/css"> #skin #heroes{ width: 100%; height: 100%; } </style> |
Если уж так хочется jQuery, то есть готовое: http://jqueryui.com/resizable/
|
Zuenf, вот как раз такой вариант у меня в Mozille и не работает. Я зацепляю мышью за угол, сдвигаю, отпускаю мышь, после этого размер резко меняется, и дальше меняется плавно, хотя мышь не зажата; а хотелось бы без этого бага. А насчёт строчки
Resizeable({'elem': $('#corner')}); - по ошибке удалил при отправке сообщения. У меня была Resizeable({'elem': $('html')}); danik.js, спасибо, но хочется для начала освоить базовый js без надстроек. |
Добавил в 24 строке запрет переноса элементов.
|
Цитата:
Цитата:
Цитата:
|
Цитата:
30 строка добавил. |
Спасибо, Zuenf.
danik.js, конечно я имел ввиду jQuery без надстроек (описАлся). А про DOM я читал на этом сайте и более или менее понял (даже примеры делал) |
Сделал опцию сохранения пропорции (жмём Shift в процессе ресайза).
И обертка создается автоматом. <!DOCTYPE html> <style> .resizeable{ position: relative; display: inline-block; overflow: hidden; min-width: 16px; min-height: 16px; } .resizeable .resizer{ position: absolute; bottom: 0; right: 0; width: 16px; height: 16px; background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAACVBMVEX///9/f38/Pz8NdHQxAAAAAXRSTlMAQObYZgAAAC9JREFUeNpNyDENADAMBLGoY5mESuAFwwOtvPWGG1z1d+xaW9CiQSxBiwY1Clo0D+HwCieH9fp/AAAAAElFTkSuQmCC); cursor: se-resize; } </style> <img width="200" height="193" src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/86/TUX-G2-SVG.svg/610px-TUX-G2-SVG.svg.png" alt="" /> <script> function Resizeable(element, preserveAspectRatio) { if (!(this instanceof Resizeable)) return new Resizeable(element, preserveAspectRatio); this.top = NaN; this.left = NaN; this.preserveAspectRatio = Boolean(preserveAspectRatio); this.aspectRatio = element.offsetWidth / element.offsetHeight; this.element = element; this.wrapper = document.createElement('div'); this.wrapper.className = 'resizeable'; this.resizer = document.createElement('div'); this.resizer.className = 'resizer'; this.resizer.addEventListener('mousedown', this); element.parentNode.replaceChild(this.wrapper, element); this.wrapper.appendChild(element); this.wrapper.appendChild(this.resizer); } Resizeable.prototype.resize = function(width, height) { width = width > 0 ? width : 0; height = height > 0 ? height : 0; if (this.preserveAspectRatio) { if (width > height) { width = height * this.aspectRatio; } else { height = width / this.aspectRatio; } } this.element.style.width = width + 'px'; this.element.style.height = height + 'px'; }; Resizeable.prototype.handleEvent = function(event) { switch (event.type) { case 'mousedown': return this.handleMouseDownEvent(event); case 'mousemove': return this.handleMouseMoveEvent(event); case 'mouseup': return this.handleMouseUpEvent(event); } }; Resizeable.prototype.handleMouseDownEvent = function(event) { if (this.resizer.setCapture) this.resizer.setCapture(); document.addEventListener('mousemove', this); document.addEventListener('mouseup', this); this.top = event.pageX - this.element.offsetWidth; this.left = event.pageY - this.element.offsetHeight; event.preventDefault(); }; Resizeable.prototype.handleMouseMoveEvent = function(event) { this.resize(event.pageX - this.top, event.pageY - this.left); }; Resizeable.prototype.handleMouseUpEvent = function(event) { document.removeEventListener('mousemove', this); document.removeEventListener('mouseup', this); if (this.resizer.releaseCapture) this.resizer.releaseCapture(); this.top = NaN; this.left = NaN; }; Resizeable.prototype.setPreserveAspectRatio = function(preserveAspectRatio) { if (this.preserveAspectRatio != preserveAspectRatio) { this.preserveAspectRatio = preserveAspectRatio; this.resize(this.element.offsetWidth, this.element.offsetHeight); } } var resizeable = new Resizeable(document.querySelector('img'), false); var shiftKeyListener = function(event) { resizeable.setPreserveAspectRatio(event.shiftKey); }; document.addEventListener('keydown', shiftKeyListener); document.addEventListener('keyup', shiftKeyListener); window.focus(); </script> |
Цитата:
|
danik.js,
а понял сначала нажать Shift до ресайза - если в процессе то никак |
Цитата:
Цитата:
|
Часовой пояс GMT +3, время: 14:48. |