Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Обработка событий мыши при выделении области картинки (https://javascript.ru/forum/dom-window/29815-obrabotka-sobytijj-myshi-pri-vydelenii-oblasti-kartinki.html)

веснушка 12.07.2012 16:53

Обработка событий мыши при выделении области картинки
 
Доброго времени суток, уважаемые!
дали задание выделить область картинки, после выделения, как отпустишь мышку, появляется всплывающее окошко с некоторым текстом.

Поняла, что нужно обработать события onmouseup, onmousedown и onmousemove.

с jscript на "Вы". подскажите, пожалуйста, с чего начать и как быть. буду благодарна за наводки!

да, делается все из студии, на шарпе. не знаю, важно это или нет.

devote 12.07.2012 17:40

<img src="http://files.sagotsky.com/wallpaper/wallpaper_little_big_planet_021.jpg" width="800" height="600" />
<div style="position: relative; top: 20px;">
	<img src="http://t.wallpaperweb.org/wallpaper/animals/1920x1200/Lion_with_cub.jpg" width="800" height="600" />
</div>
<script type="text/javascript">
    (function( window ) {

        var activeImage = null, startX = 0, startY = 0,
            activeSelection = document.createElement( 'div' ),
            html = document.documentElement,
            body = document.body,
            imgs = document.getElementsByTagName('img');

        activeSelection.style.cssText = "position:absolute; line-height:0; font-size:0; z-index: 100;"+
                             "background-color:#0f0; opacity: 0.3; filter:Alpha(opacity=30)";

        function msgBox( content, x, y, w, h ) {
            var img = activeImage,
                rect = img.getBoundingClientRect(),
                 box = document.createElement('div'),
                 bg = document.createElement('div'),
                close = document.createElement('div'),
                win = document.createElement('div');

            box.style.cssText = "z-index: 100; position: absolute; width: " +
                        ( rect.right - rect.left ) + "px; height: " +
                        ( rect.bottom - rect.top ) + "px;" +
                        "top: " + img.offsetTop + "px;"+
                        "left: " + img.offsetLeft + "px";

            bg.style.cssText = "background-color: #000; opacity: 0.3; filter: Alpha(opacity=30);"+
                        "position: absolute; width: 100%; height: 100%;";

            close.style.cssText = "position: absolute; top: 0; right: 0; margin: 2px 7px 0 0; font: 14px Tahoma; "+
                        "color: red; cursor: pointer; font-weight: bold;";
            close.innerHTML = "x";
            close.onclick = function() {
                img.parentNode.removeChild( box );
            }

            win.style.cssText = "padding: 15px; position: absolute; background-color: #fff;"+
                        "left: " + (typeof x =="undefined" ? "50%" : x + "px" ) + "; "+
                        "top: " + (typeof y =="undefined" ? "50%" : y + "px" ) + ";" +
                        "border-radius: 10px; box-shadow: 2px 2px 4px #000;" + 
                        ( w ? 'width: ' + w + 'px;' : '' ) + ( h ? 'height: ' + h + 'px;' : '' );

            win.innerHTML = content;

            win.onclick = function() {
                var image = new Image();
                image.onload = function() {
                    img.parentNode.removeChild( box );
                    img.src = image.src;
                }
                image.src = "http://dreaminginpictures.files.wordpress.com/2010/06/roses.jpg";
            }

            box.appendChild( bg );
            box.appendChild( win );
            win.appendChild( close );
            activeImage.parentNode.insertBefore( box, img );

            var ml = win.offsetWidth / 2;
            var mt = win.offsetHeight / 2;

            ml = win.offsetLeft - ml < 0 ? win.offsetLeft : ml;
            ml = ( win.offsetLeft - ml ) + win.offsetWidth > rect.right - rect.left ?
                  win.offsetWidth - ( rect.right - rect.left - win.offsetLeft ) : ml;

            mt = win.offsetTop - mt < 0 ? win.offsetTop : mt;
            mt = ( win.offsetTop - mt ) + win.offsetHeight > rect.bottom - rect.top ?
                  win.offsetHeight - ( rect.bottom - rect.top - win.offsetTop ) : mt;

            win.style.margin = "-" + mt + "px 0 0 -" + ml + "px";
        }

        function shiftScroll() {
            return {
                X: ( html && html.scrollLeft || body && body.scrollLeft || 0 ),
                Y: ( html && html.scrollTop || body && body.scrollTop || 0 )
            }
        }

        function fixEvent( e ) {

            e = e || window.event;

            if ( e.pageX == null && e.clientX != null ) {
                e.pageX = e.clientX + shiftScroll().X - ( html.clientLeft || 0 );
                e.pageY = e.clientY + shiftScroll().Y - ( html.clientTop || 0 );
            }

            if ( !e.which && e.button ) {
                e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) );
            }

            return e;
        }

        for( var i = 0; i < imgs.length; i++ ) {
            imgs[ i ].onselectstart = imgs[ i ].ondragstart = function() {
                return false;
            }
            imgs[ i ].onmousedown = function( e ) {

                e = fixEvent( e );

                activeImage = e.target || e.srcElement;
                body.insertBefore( activeSelection, body.firstChild );

                startX = e.pageX;
                startY = e.pageY;

                if ( e.preventDefault ) {
                    e.preventDefault();
                }
                e.returnValue = false;
            }
        }

        document.onmouseup = function( e ) {
            if ( activeImage ) {

                e = fixEvent( e );

                var iRect = activeImage.getBoundingClientRect();
                var sRect = activeSelection.getBoundingClientRect();

                var shift = shiftScroll();
                var X = ( sRect.left + shift.X < startX ? sRect.left + shift.X : startX ) - iRect.left - shift.X;
                var Y = ( sRect.top + shift.Y < startY ? sRect.top + shift.Y : startY ) - iRect.top - shift.Y;

                // тут что-то открываем, делаем
                // ....
                msgBox([
                    "src: " + activeImage.src + "<br />",
                    "X: " + X,
                    "Y: " + Y,
                    "W: " + activeSelection.offsetWidth,
                    "H: " + activeSelection.offsetHeight
                ].join("<br />"),
                    startX > e.pageX ? X : X + activeSelection.offsetWidth,
                    startY > e.pageY ? Y : Y + activeSelection.offsetHeight,
                    300
                );
                // ------------------------------

                if ( activeSelection.parentNode ) {
                    activeSelection.parentNode.removeChild( activeSelection );
                    activeSelection.style.width = "0";
                    activeSelection.style.height = "0";
                }
                activeImage = null;
            }
        }
        document.onmousemove = function( e ) {
            if ( activeImage ) {
                e = fixEvent( e );

                var shift = shiftScroll();
                var rect = activeImage.getBoundingClientRect();

                var X = Math.max( e.pageX > startX ? startX : e.pageX, rect.left + shift.X );
                var Y = Math.max( e.pageY > startY ? startY : e.pageY, rect.top + shift.Y );
                var W = Math.min( Math.abs( Math.max( X, e.pageX ) - startX ), rect.right + shift.X - X );
                var H = Math.min( Math.abs( Math.max( Y, e.pageY ) - startY ), rect.bottom + shift.Y - Y );

                activeSelection.style.left = X + "px";
                activeSelection.style.top = Y + "px";
                activeSelection.style.width = W + "px";
                activeSelection.style.height = H + "px";
            }
        }
    })( window );
</script>

веснушка 13.07.2012 09:08

спасибо большое!
скажите, а если этот код скопировать в блокнот и сохранить как <name>.html он будет работать как здесь в примере на сайте? а то я так сделала, открываю mozilla, картинка есть, а выделение не происходит(

lord2kim 13.07.2012 09:11

Цитата:

Сообщение от веснушка (Сообщение 188455)
спасибо большое!
скажите, а если этот код скопировать в блокнот и сохранить как <name>.html он будет работать как здесь в примере на сайте? а то я так сделала, открываю mozilla, картинка есть, а выделение не происходит(

все работает, только что проверил...в IE не совсем корректно, а в FireFox и GoogleChrome все летает

веснушка 13.07.2012 09:25

и вы вообще ничего не меняли? просто копи-паст сделали в блокнот и все?

lord2kim 13.07.2012 09:26

Цитата:

Сообщение от веснушка (Сообщение 188459)
и вы вообще ничего не меняли? просто копи-паст сделали в блокнот и все?

так точно) какой у вас браузер? (желательно с версией)

веснушка 13.07.2012 09:28

Mozilla Firefox 13.0.1

lord2kim 13.07.2012 09:33

Цитата:

Сообщение от веснушка (Сообщение 188462)
Mozilla Firefox 13.0.1

да не ну все работает...может вы вместе с цифарками скопировали в начале каждой строки?

веснушка 13.07.2012 09:38

нет, я при удалении цифирок удалила лишнее просто:)
спасибо большое!)

в мозилле и хроме и правда работает. а что не так с explorer? не объясните мне? :-[

lord2kim 13.07.2012 09:40

Цитата:

Сообщение от веснушка (Сообщение 188466)
нет, я при удалении цифирок удалила лишнее просто:)
спасибо большое!)

когда наводите мышкой на фрагмент кода обрамленный тегами [html] или [JS], как у devote, на этом форуме, сверху справа появляется "менюшка", в которой можно отключить эти цифарки (с помощью иконки с единичкой)

веснушка 13.07.2012 10:19

в мозилле и хроме и правда работает. а что не так с explorer? не объясните мне? :-[

lord2kim 13.07.2012 10:21

Цитата:

Сообщение от веснушка (Сообщение 188475)
в мозилле и хроме и правда работает. а что не так с explorer? не объясните мне? :-[

в Mozilla и Chrome нужно нажать и удерживать пока не выделишь...
в IE нужно нажать, отпустить, выделить и еще раз нажать...вроде так...

Deff 13.07.2012 10:40

Цитата:

Сообщение от веснушка
а что не так с explorer?

В ИE7 всё работает! (*В конце растяжения делаем клик

веснушка 13.07.2012 10:46

у меня вот 6я версия explorer(собственно какая стояла по дефолту в винде) и там что-то вообще не выделяется область.

а, разобралась. он с глюками, но работает. спасибо всем:)

devote 13.07.2012 17:01

Для ИЕ просто нужно немного доработать, добавить запрет событий выделения, и dragdrop тоесть внутрь for() засунуть:
imgs[ i ].onselectstart = imgs[ i ].ondragstart = function() {
	return false;
}
и добавить в стиль выделяющего элемента пару параметров:
line-height: 0; font-size: 0;

devote 13.07.2012 17:03

я подправил код в своем примере на первой странице темы. Должно работать корректно и в ИЕ

веснушка 17.07.2012 13:01

скажите пожалуйста, а как ограничить область выделения размером картинки?
чтобы выделение не выезжало за саму картинку

devote 17.07.2012 14:37

веснушка,
я дописал функционал в своем первом посте

веснушка 17.07.2012 14:50

спасибо! очень помогло!

веснушка 20.07.2012 09:04

а вы не объясните мне за что какой див отвечает в msgBox? ну кроме close)
просто мне нужно на onmouseup сделать переход на картинку, а никак не получается. может, подскажете, в чем дело?
box.onmouseup = function() { this.style.display = 'none';
                    var img_map = document.createElement('img');
                    img_map.style.width = '700px';
                    img_map.style.height = '250px';
                    img_map.style.borderWidth = '0px';
                    img_map.source = '" + ResolveUrl("~/App_Themes/default/wallpaper.jpg") + @"';
                    box.appendChild(img_map);
                    
                };

devote 20.07.2012 10:23

веснушка,
посмотрите первый мой пост, так вы хотите? или я что-то не понял?

веснушка 20.07.2012 10:46

да!
объясните, если можно, зачем нам столько дивов?
box = document.createElement('div'),
 bg = document.createElement('div'),
close = document.createElement('div'),
win = document.createElement('div');

и почему обработка загрузки картинки на win а не на box?

devote 20.07.2012 10:48

box - дивак просто является контейнером для всех остальных диваков
bg - задний фон, если вы не заметили, то при появлении окна картинка немного затемняется, вот это он и делает.
close - кнопка закрытия окна
win - само окно в котором текст

веснушка 20.07.2012 10:55

ясно. а можно же задать размеры загружаемой картинки?
win.onclick = function() {
	                var image = new Image();
	                image.onload = function() {
	                    img.parentNode.removeChild( box );
                            img.width=image.width;
                            img.height=image.height;
	                    img.src = image.src;
	                }
                    image.width='600px';
                    image.height='400px';
	                image.src = 'http://dreaminginpictures.files.wordpress.com/2010/06/roses.jpg';
                }

вот так не работает, картинка не грузится

devote 20.07.2012 10:59

win.onclick = function() {
    var image = new Image();
    image.onload = function() {
        img.parentNode.removeChild( box );
                         
        img.style.width = '600px';
        img.style.height = '400px';

        img.src = image.src;
    }
    image.src = 'http://dreaminginpictures.files.wordpress.com/2010/06/roses.jpg';
}

веснушка 20.07.2012 11:04

а можно на заново загруженной картинке запретить всплывающее окно?
просто перешли на новую картинку и все.

devote 20.07.2012 11:06

img.onmousedown = null;

веснушка 20.07.2012 11:22

о. и, надеюсь, последний вопрос :-[
а можно изображение поставить так, чтобы оно рисовалось на всю возможную область, а не ту, на которой первая картинка была?

devote 20.07.2012 11:24

img.style.width = '100%';
img.style.height = '100%';

веснушка 23.07.2012 16:42

скажите, пожалуйста, а как убрать крестик из первого выпадающего окна?
я просто убрала close, но место для него осталось смотрится странно. и можно ли сделать так, чтобы картинка, загруженная по клику мыши, загружалась в подобное выпадающее окно с крестиком, а исходная картинка при этом не пропадала?

веснушка 24.07.2012 10:09

devote, отзовитесь, пожалуйста, как сможете! очень нужна помощь.

devote 24.07.2012 11:04

Цитата:

Сообщение от веснушка
я просто убрала close, но место для него осталось смотрится странно.

видимо не все убрали.

Цитата:

Сообщение от веснушка
и можно ли сделать так, чтобы картинка, загруженная по клику мыши, загружалась в подобное выпадающее окно с крестиком, а исходная картинка при этом не пропадала?

ну тут нужно переделать скрипт, сейчас у меня пока нет свободного времени. Может кто сделает пока я этого не могу. А я смогу сделать не раньше чем завтра скорее.. Сегодня я перегружен сильно.

веснушка 24.07.2012 11:10

ну я сама сегодня переделываю и завтра все равно нужен скрипт будет нужен.

веснушка 25.07.2012 14:30

devote,
а вы не подскажите, как быть с позицией выпадающего окна?
у меня изображение скроллится и при выделении большой области окно "прячется". . .


Часовой пояс GMT +3, время: 16:00.