Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выделение области картинки с помощью мышки 
:(
    Опции темы
Elfet
  Дата 8.8.2005, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Мне нужно выделить и отметить прямоугольную область на картинке. Не знаю как это сделать! smile


--------------------
PM MAIL WWW Skype   Вверх
Elfet
Дата 8.8.2005, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



У меня не удаётся выделить цветом участок на картинке


--------------------
PM MAIL WWW Skype   Вверх
sergejzr
Дата 8.8.2005, 21:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 10
Всего: 360



Значится так:
Тебе надо разделить процесс.
Отлавливаешь событие ondrag и когда отпустили мышь. По этим координатам вырешиваешь прямоугольник и рисуешь цветной квадрат поверх.

Думаю, должно получится. не знаю правда, возможно ли сделать полупрозрачным квадрат..


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Sardar
Дата 8.8.2005, 21:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Рутинна это, довольно нудная smile

Берём слой на релативной позиции, что бы не париться с координатами. Кладём в него картинку и четыре слоя на абсолютной позиции, в бекграунд которых ложим полупрозрачный(4 пиксельный, 2 прозрачных, 2 нет) .gif. Ловим клик(mousedown), ловим mousemove, считаем координаты(layer(X|Y), ofset(X|Y)). Изменяем размеры слоёв лжащих поверх картинки, так что бы затушевать часть картинки. Красиво будет если задать им бордер dotted 1px #555 у каждого со своей стороны + поставить маленькие квадратные синие слои по углам, как квадаратики. Ловим вхождение мыши на слоях, что бы "сдвигать" селекцию.

Работа над такой фичей, что бы было как в любом сканере/редакторе потребует целого дня, уж больно рутины много.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Elfet
Дата 11.8.2005, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Код

<html>
<head>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#FF00FF" alink="#FF0000">
<script>

var x1=0,y1=0,x2=0,y2=0;
var nomxy=1;

function getxy()
{
 if(nomxy==1)
 {
  document.getElementById('xy1').value=xy_x+"x"+xy_y;
 }
 else if(nomxy==2)
 {
  document.getElementById('xy2').value=xy_x+"x"+xy_y;
  nomxy=0;
 }
  nomxy++;
}



function showwhat(x,y)
{
 if(x1==0&&y1==0&&x2==0&&y2==0)
 {
  x1=document.getElementById('xyimg').style.pixelTop;
  y1=document.getElementById('xyimg').style.pixelLeft;
 }
 else
 {
 
 if(nomxy==1)
 {
  document.getElementById('xyh1').value=xy_x+"x"+xy_y;
  document.getElementById('xyselect').style.top=y;
  document.getElementById('xyselect').style.left=x;
  xy_y=document.getElementById('xyselect').style.pixelTop;
  xy_x=document.getElementById('xyselect').style.pixelLeft;
 }
 else if(nomxy==2)
 {
 // xy_x=x;
 // xy_y=y;
  document.getElementById('xyh2').value=xy_x+"x"+xy_y;
  if(xy_y-document.getElementById('xyselect').style.pixelTop > 10)
  {
   document.getElementById('xyselect').style.height=y-document.getElementById('xyselect').style.pixelTop;
  } 
  if(xy_x-document.getElementById('xyselect').style.pixelLeft > 10)
  {
   document.getElementById('xyselect').style.width=x-document.getElementById('xyselect').style.pixelLeft;
  }  
 }
 
 }
 showred();
}

function showred()
{
 
}

</script>
<div id="xyselect" style="position: absolute;    border: solid 1px red;"></div>
<input type="text" id="xyh1" value="" size="5" disabled><input type="text" id="xyh2" value="" size="5" disabled><br>
<input type="text" id="xy1" value="" size="5"><input type="text" id="xy2" value="" size="5"><br>
<img id="xyimg" onclick="javascript:getxy();" onmousemove="javascript:showwhat(event.x, event.y);"; src="../../../Documents and Settings/Elfet/Ìîè äîêóìåíòû/Ìîè ðèñóíêè/20050309_gruzin_wallpapers_ru_les_1024x768_A(77376)PI.jpg" alt="Âûäåëèòå îáëàñòü" border="0">
</body>
</html>




Ничего у меня не выходит smile Видимо потому что я бнру глобальные координаты. А как получить координаты т начала картинки?


--------------------
PM MAIL WWW Skype   Вверх
Elfet
Дата 12.8.2005, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Как получить координаты мышки относительно начала картинки?


--------------------
PM MAIL WWW Skype   Вверх
Sardar
Дата 12.8.2005, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Под мозиллой это event.layer(X|Y), под ИЕ это event.offset(X|Y).


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Гость_Elfet
  Дата 13.8.2005, 09:23 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Sardar, ага, так работает, но только вот с выделением проблемы smile Вот так я получаю координаты относительно картинки: this.event.offsetX,
Но мне никак не выделить эту облость, у меня выделяется эта облость, но не относительно картинки, а относительно всей страницы: document.getElementById('xyselect').style.pixelLeft=this.event.offsetX;
Что тогда делать? smile
Вот это не помогает: document.getElementById('xyimg').style.pixelLeft - пишет, что 0
  Вверх
Aliance
Дата 15.8.2005, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Elfet
Модератор: Пожалуйста, один топик - один вопрос.
Пользуйся поиском, помню давно была подобная тема. Кажется, там и решение. Если не найдешь - попробую поискать...
PM MAIL WWW ICQ Skype   Вверх
Elfet
Дата 16.8.2005, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Aliance, я посмотрел. Там такая тема есть, но там нет решения. А у меня по прежнему нечего не получается. Помогу плиз!


--------------------
PM MAIL WWW Skype   Вверх
Elfet
Дата 18.8.2005, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Вот, я понял, что нужно брать обе координаты, по картинке и глобальные. но все равно ничего не выходит smile
Может кто видел уже такие скрипты? Где их можно поискать?


--------------------
PM MAIL WWW Skype   Вверх
diam
Дата 18.8.2005, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 348
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: 6
Всего: 16



Такой реализации я не видел. Много реализаций, где просто водишь квадратик над картинкой, и где-нибудь в другом месте на сайте та часть картинки, на которой квадратик, видна у тебя. Но это не то.

Я заинтересовался данной проблемой, попробую написать скрипт в свободное время.

Elfet, если хочешь, можешь написать его быстрее меня smile.

Идея скрипта.
Во-первых, просто так мы не можем выложить картинку и водить по ней мышкой, потому что firefox будет пытаться скопировать ссылку на данную картинку, опера потащит картинку за собой, может быть, ИЕ как-то накосячит (не знаю, не пользуюсь им).
Во-вторых, нам нужен некий элемент прозрачности. Есть такое свойство в CSS: opacity, но оно не работает в Opera. Поэтому, если пользователи этих браузеров нам важны, придётся искать альтернативу. Я её вижу в полупрозрачном маленьком рисунке gif или png, который мы сможем размножить.

Поэтому, предлагаю писать слоями в следующем порядке (относительно нашей конструкции):
1. На самом нижнем слое лежит картинка размерами X на Y.
2. На самом верхнем слое - div размерами X на Y со свойством background-color : transparent. Он будет выполнять роль стекла.
3. Посредине между ними div, размер которого будет меняться скриптом, а свойства фона будут задаваться background-image : url(transparent.gif) и background-repeat : repeat.

Что тогда мы получаем?
Когда кликаем мышкой по картинке (на самом деле, по верхнему диву smile ), мы уже не тащим за собой картинку, потому что она "под стеклом" smile. Мы будем отлавливать событие mousemove при движении по верхнему DIV'у-стеклу, и, исходя из координат начальной точки (получим при mousedown) будем формировать размер среднего дива, тем самым получая нужную нам картину: выделение полупрозрачным цветом. Заодно можем отрисовывать выделенное где-угодно (но это тема для отдельного топика, здесь это оффтоп smile ). Далее, когда отпускаем мышь (событие mouseup), получим координаты конечной точки - выделенный прямоугольник готов. Дальше уже можно действовать по вкусу: спрятать выделение, не прятать, сделать менее прозрачным - в общем, чего душа пожелает.

Итак, это была идея. По моему, должно заработать.
Повторюсь. Времени у меня очень мало, но задача мне очень интересна. Попробую написать. smile

Это сообщение отредактировал(а) diam - 18.8.2005, 20:43
PM MAIL   Вверх
Elfet
Дата 18.8.2005, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Белый и Пушистый
****


Профиль
Группа: Awaiting Authorisation
Сообщений: 3776
Регистрация: 2.4.2003

Репутация: нет
Всего: 16



Цитата(diam @ 18.8.2005, 21:41)
Попробую написать

БЫло бы, здорово! smile Сам я пытался сделать только под ИЕ, но ничего не вышло smile smile


--------------------
PM MAIL WWW Skype   Вверх
diam
Дата 23.10.2005, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 348
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: 6
Всего: 16



Много времени прошло, но тему надо поднять, потому как лучше поздно, чем никогда smile.

Начнём.


Сразу же выложу готовый вариант, что бы понимали, о чём речь.
Логин: vingrad.
Пароль: vingrad.

Что мы имеем?
1. Картинка, область которой нужно выделить.
2. Полупрозрачный слой, который будет располагаться выше выделяемой картинки и будет показывать нам, какую область мы выделяем (или уже выделили).
3. Документ, в котором всё это располагается smile.

Для работы выделим координаты двух крайних точек картинки:
1. Координаты левой верхней точки картинки относительно начала документа (назовём эту точку pp0, а её координаты по осям абциссы и ординаты ppx0 и ppy0 соответственно).
2. Координаты правой нижней точки картинки относительно начала документа (назовём эту точку pp1, а её координаты по осям абциссы и ординаты ppx1 и ppy1 соответственно).

Далее нужно разобраться с полупрозрачным слоем, который будет показывать нам выделенную нами область. Свойством CSS opacity нам не воспользоваться - опера не понимает. Красивыми полупрозрачными png'шками тоже, на этот раз тупит IE. А gif просто не умеет иметь полупрозрачный слой. Он умеет быть или прозрачным совсем (что нам не нужно), или совсем непрозрачным (что нам так же не подходит, так как не будем видеть то, что выделяем).
Выход я нашёл следующий: я создал gif-файл размером 3x3 пикселя, фон у него сделал прозрачным и первый пиксель закрасил в серый цвет. Потом для нашего псевдополупрозрачного слоя применил такие правила CSS:
Код

#divid {
        /* cut */
        position: absolute;
        background : url("./2.gif") repeat;
        border: 1px solid #444;
        /* cut */
}

Таким образом, выделяемая область будет выглядеть как рамка с небольшими точками внутри, отдалённо будет напоминать полупрозрачность smile (потом посмОтрите на примере, всё выглядит не так уж плохо smile ).

Теперь о том, что и как мы будем выделять.
Мы будем отлавливать у всего документа события mousedown, mouseup, mousemove. Почему у всего документа? Что бы было удобнее для пользователя выделять (позже объясню почему).
При нажатии на кнопку мыши будет запускаться функция, которая будет проверять, находимся ли мы внутри картинки. Если да, то будет фиксироваться флаг isAllocated, который скажет, что мы сейчас работаем с выделением, и координаты точки, где была опущена кнопка (назовём её ps0).
Когда мы будем водить мышку по картинке с установленным флагом isAllocated, то будем получать ещё одну точку, которую назовём ps1, она то и будет завершать область выделения.
Исходя из двух крайних точек (ps0 и ps1) мы будем знать, где нам расположить полупрозрачный слой и каким размером его сделать.
После выделения мы будем отпускать кнопку мыши, при этом флаг isAllocated будет сброшен, а мы получим готовую выделенную область на картинке.


Вот вроде бы и всё, смотрите код, в нём все более подробно. Можете его скопировать, вставить в файл, и просмотреть в браузере, но тогда вам нужно позаботиться о выделяемой картинке и о gif'ке с фоном.
Код

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251" />
<title>Пример выделения</title>
<style type="text/css">
<!--
// полупрозрачный слой над картинкой
#divid {
        position: absolute;
        // фон  - полупрозрачная gif'ка
        background : url("./2.gif") repeat;
        border: 1px solid #444;
        visibility: hidden;
}

// в этот слой помещена картинка
// (картинку так же можно поместить и в табличную ячейку - для архаиков и консерваторов :) )
#owndiv {
        padding: 15px;
        border: 1px solid #aaa;
        background: #eee;
        width: 425px;
}
-->
</style>
</head>
<body>
<!-- Выделяемая картинка внутри слоя -->
<div id="owndiv">
        <img id="imgid" src="./1.gif" alt="" />
</div>

<!-- Псевдополупрозрачный слой -->
<div id="divid"></div>

<script type="text/javascript">
// функция поиска координат объекта относительно начала документа
// (c) Sardar
function getPosition(obj) {
        var x = 0;
        var y = 0;
        var obj = obj || false;
        while (obj) {
                x += obj.offsetLeft;
                y += obj.offsetTop;
                obj = obj.offsetParent;
        }
        return [x, y];
}

// Картинка
var img = document.getElementById("imgid");

// Слой, внутри которого лежит картинка
var owndiv = document.getElementById("owndiv");

// Слой, показывающий нам область выделения
var div = document.getElementById("divid");


// Координаты верхней левой точки картинки (точка pp0)
var ppx0, ppy0;

// Координаты нижней правой точки картинки (точка pp1)
var ppx1, ppy1;

// Координаты точки начала выделяемой области (точка ps0)
var psx0, psy0;

// Флаг, показывающий, что выделение началось
var isAllocated = false;

// Функция на событие mousedown, устанавливающая флаг isAllocated
function mDown (evt) {
        // Ловим координаты точек pp0 и pp1 картинки.
        // Ловим каждый раз, поскольку документ может изменяться
        var imgPosition = getPosition(img);
        ppx0 = imgPosition[0];
        ppy0 = imgPosition[1];
        ppx1 = ppx0 + img.width;
        ppy1 = ppy0 + img.height;

        // Вычисляем координаты точки ps0 - откуда начинается выделяемая область.
        // Кроме clientX|clientY используем pageXOffset|pageYOffset
        // (document.body.parentNode.scrollLeft|document.body.parentNode.scrollTop)
        if (evt && evt.stopPropagation) {
                psx0 = evt.clientX + pageXOffset;
                psy0 = evt.clientY + pageYOffset;

                // предотвращаем таскание картинки за мышкой Opera'ой и FF.
                evt.preventDefault();
        } else if (window.event) {
                psx0 = event.clientX + document.body.parentNode.scrollLeft;
                psy0 = event.clientY + document.body.parentNode.scrollTop;

                // предотвращаем таскание картинки за мышкой IE
                img.setCapture(false);
        }

        // Проверяем, находимся ли мы при нажатии на кнопку мышки на картинке
        if (psx0 < ppx0 || psx0 > ppx1 || psy0 < ppy0 || psy0 > ppy1) return;

        // Мы на картинке.
        //Устанавливаем флаг и задаём новые свойства полупрозрачному слою
        isAllocated = true;
        div.style.visibility = 'visible';
        div.style.top = psy0 + 'px';
        div.style.left = psx0 + 'px';
        div.style.width = '0px';
        div.style.height = '0px';
}

// функция на событие mouseup, сбрасывающая флаг isAllocated
function mUp (evt) {
        if (!isAllocated) return;
        isAllocated = false;

        // Если выделение по размерам 0x0 пикселей - просто скрыть его с глаз
        if (div.style.width == '0px' && div.style.height == '0px') div.style.visibility = 'hidden';
}

// функция на событие mousemove, изменяющая размер и положение
// полупрозрачного слоя
function mMove (evt) {
        if (!isAllocated) return;
        if (evt && evt.stopPropagation) {
                var psx1 = evt.clientX + pageXOffset;
                var psy1 = evt.clientY + pageYOffset;
        } else if (window.event) {
                var psx1 = event.clientX + document.body.parentNode.scrollLeft;
                var psy1 = event.clientY + document.body.parentNode.scrollTop;
        }

        // Проверяем, не зашли ли мы за края картинки
        if (psx1 < ppx0) psx1 = ppx0;
        else if (psx1 > ppx1) psx1 = ppx1;
        if (psy1 < ppy0) psy1 = ppy0;
        else if (psy1 > ppy1) psy1 = ppy1;

        // Устанавливаем размеры выделяемой области в DIV'е
        if (psx1 > psx0) {
                div.style.left = psx0 + 'px';
                div.style.width = (psx1 - psx0) + 'px';
        } else {
                div.style.left = psx1 + 'px';
                div.style.width = (psx0 - psx1) + 'px';
        }
        if (psy1 > psy0) {
                div.style.top = psy0 + 'px';
                div.style.height = (psy1 - psy0) + 'px';
        } else {
                div.style.top = psy1 + 'px';
                div.style.height = (psy0 - psy1) + 'px';
        }
}

// Устанавливаем обработчики событий.
// Можно, конечно, установить не на весь документ, а только на объект,
// внутри которого находится картинка, но работать будет уже далеко не так удобно.
// Попробуйте заменить document на owndiv и вы поймёте, почему.
if (document.addEventListener) {
        document.addEventListener("mousedown", mDown, true);
        document.addEventListener("mouseup", mUp, true);
        document.addEventListener("mousemove", mMove, true);
} else if (document.attachEvent) {
        document.attachEvent("onmousedown", mDown);
        document.attachEvent("onmouseup", mUp);
        document.attachEvent("onmousemove", mMove);
}
</script>
</body>
</html>


Работает в следующих браузерах:
  • FF 1.7.10
  • IE 6.0.2900.2180
  • Opera 8.02
Пользуйтесь на здоровье smile (можно ещё в "наши скрипты" поместить, если модераторы не против).


З.Ы. У меня просьба к модераторам: нельзя ли файл с примером поместить на vingrad, а то у меня машинка периодически перезагружается smile.

Это сообщение отредактировал(а) diam - 23.10.2005, 21:04
PM MAIL   Вверх
diam
Дата 23.10.2005, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 348
Регистрация: 23.1.2005
Где: Екатеринбург

Репутация: 6
Всего: 16



Для данной реализации только что обнаружил баг, он касается всех тех, кто сидит в Windows и пользуется IE.

Если Вы загрузите страничку и выделите какую-нибудь область на картинке, IE не даст Вам нажать ни одной кнопки в меню, пока окно не потеряет фокус, а потом снова его не поймает!

Данный баг обнаружен на Windows XP SP2, запущенного под эмуляцией VMWare во FreeBSD (думаю, что баг останется, даже если загрузиться в винду без всяких эмуляторов).

Правда, запустил IE через wine, такого бага обнаружено не было.

Это сообщение отредактировал(а) diam - 23.10.2005, 01:44
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1147 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.