Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Затемнение участков картинки (https://javascript.ru/forum/jquery/31973-zatemnenie-uchastkov-kartinki.html)

Glorymirror 27.09.2012 23:36

Затемнение участков картинки
 
Здравствуйте. Хотел узнать, как сделать, так чтобы на картинке, выделялось рамкой определенное место (div'ом конечно), а все остальное затемнялось. Идеи никак не лезут в голову. Максимально додумал что кроме как jquery ничего не поможет :)

melky 28.09.2012 00:56

div + box-shadow (CSS)..

но вообще лучше canvas - он для этих целей сделан.

Aetae 28.09.2012 01:00

Можно и border'ом обойтись.)

Dim@ 28.09.2012 01:01

<head>
        <meta endcoding="windows-1751" />
        <style type="text/css">
            body {
                margin:0px;
                padding:0px;
            }
            .sel {
                position:absolute;
                background-color:rgba(0, 30, 150, 0.3);
                border:1px solid rgba(30, 150, 0, 0.4);
            }
        </style>
        <script type="text/javascript">
            var ctx2;
 
            function selection(elem, drags) {
                if ((typeof elem != "object") || (typeof drags != "object") || (((drags + "") != "[object HTMLDivElement]") && ((drags + "") != "[object]"))) {
                    console.log('selection error');
                    return;
                };
                drags.style.display = "none";
                elem.onmousedown = function (e) {
                    drags.style.display = "block";
                    var e = e || window.event;
                    selection.x = e.pageX;
                    selection.y = e.pageY;
                    drags.style.left = selection.x;
                    drags.style.top = selection.y;
                    selection.drags = drags;
                    selection.e = e;
                    elem.onmousemove = function (e) {
                        var e = e || window.event;
                        if (e.pageX - selection.x > 0) {
                            selection.drags.style.left = selection.x;
                            selection.drags.style.width = e.pageX - selection.x;
                        } else {
                            selection.drags.style.left = e.pageX;
                            selection.drags.style.width = selection.x - e.pageX;
                        }
                        if (e.pageY - selection.y > 0) {
                            selection.drags.style.height = e.pageY - selection.y;
                            selection.drags.style.top = selection.y;
                        } else {
                            selection.drags.style.top = e.pageY;
                            selection.drags.style.height = selection.y - e.pageY;
                        }
                    }
                }
                elem.onmouseup = function () {
                    var cnv2 = document.getElementById("cnv2");
                    cnv2.setAttribute('width', drags.offsetWidth);
                    cnv2.setAttribute('height', drags.offsetHeight);
                    ctx2.drawImage(document.getElementById("cnv"), drags.offsetLeft, drags.offsetTop, drags.offsetWidth, drags.offsetHeight, 0, 0, drags.offsetWidth, drags.offsetHeight);
                    drags.style.display = "none";
                    elem.onmousemove = function () {};
                    drags.style.width = 0;
                    drags.style.height = 0;
                };
            };
            window.onload = function () {
                var sel = document.getElementById("sel");
                selection(document, sel);
                var ctx = document.getElementById("cnv").getContext('2d');
                ctx2 = document.getElementById("cnv2").getContext('2d');
                img = new Image();
                img.src = "http://www.parkhotelbrasilia.com/sites/default/files/lavorazione_vetro_murano.jpg";
                img.onload = function () {
                   document.getElementById("cnv").width = img.width;
                   document.getElementById("cnv").height = img.height;
                   ctx.drawImage(img, 0, 0, img.width, img.height);
                }
            }
        </script>
    </head>
     
    <body onselectstart='return false'>
        <canvas id=cnv width=300 height=140 style='border:1px solid black'></canvas>
        <canvas id=cnv2 width=100 height=120 style='border:1px solid black'></canvas>
        <div id="sel" class="sel"></div>
    </body>

как вариант :haha: http://javascript.ru/forum/project/3...j-ehffekt.html
P.S. код говнецо, но я не гнался за производительностью

melky 28.09.2012 01:01

Цитата:

Сообщение от Aetae (Сообщение 206939)
Можно и border'ом обойтись.)

а, я проспал момент - я думал нужна градиентная изящная рамка.

Glorymirror 28.09.2012 07:34

Нет, не совсем это мне нужно. Я имел ввиду, что есть картинка, и при наведении на нее, появляется окошко, например 20х20 пикс. Остальная же часть картинки затемняется. :)

DjDiablo 28.09.2012 17:47

если без webkit-mask обойтись, то обложи пустое место, вокруг 4мя чёрными частично прозрачными дивами
Тобиш сверху, снизу, слева и справа, между ними всё будет видно (так как там нечего незагараживает нашу выделенную часть) а вокруг затемнёно (так как там наши тёмные дивы)

к примеру
верхний div по x от 0 во всю ширину затемняемого контенера
по y от 0 до начального y требуемого пустого пространства

и ещё три можно найти так же.

думаю более сложные маски можно сделать при помощи PNG с прозрачностью или SVG

Aetae 28.09.2012 18:25

DjDiablo, самый топорный и убогий вариант.

Есть 2 простых кроссбраузерных варианта использующих !1 див:
1. Выделение div'ом, затемение border'ом, с изменяемой общей opacity.
2. Изменение размера div с overflow:hidden в котором находится картинка, с изменением положения этого div'а и положения картинки в нём. Подложка, т.е. рамка в таком случае может быть любой.

И есть множество вариантов с css3 вообще не требующих дополнительного div: box-shadow: inset, градиенты, множественные background'ы и border'ы итд.

В любом случае геморроя, вёркстки и js кода на порядок меньше, а результат производительнее.

DjDiablo 28.09.2012 20:38

про бордер ты уже писал в 3ем посте, решение интересное возможно лучшее, я просто предложил альтернативу.

что касается изменения положения картинки в div с hidden, то есть недостаток, во первых изображение вокруг проблематично затемнить частично. Для эфaекта частичного затемнения придётся иметь затемнённую копию картинки на заднем плане, точнее картинку перекрытую оверлеем. По факту код окажется несколько сложнее чем для 4х дивов.

Aetae 28.09.2012 21:21

Цитата:

Сообщение от DjDiablo (Сообщение 207106)
По факту код окажется несколько сложнее чем для 4х дивов.

2 дива: 1 с картинкой бг, другой внутри него с картинкой внутри.
И код влияющий только на картинку и второй див.

В в случае 4х - придётся проводить расчёты для всех четырёх дивов. Но основная проблема не в этом, а в стилизации затемнения. Если эффект чкть сложнее чем простое затемнение - получим кучу проблем со стыковкой div'ов.

DjDiablo 28.09.2012 21:44

Я не думаю что на 4х дивах вообще что то кроме затемнения можно реализовать )).

Помоему чуток не так.
контейнер с фоном, оверлей который затемнит фон, и квадрат, который содержит в себе картинку. 1)Позиционируем квадратик, 2)позиционируем картинку, 3) делаем квадратик видимым, 4) затемняем фон.

Конечно больше фич, можно масштабирывать картинку в квадрате к примеру.

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

Aetae 28.09.2012 21:52

Картинка то по сути одна, на такие случаи должно быть всё оптимизировано.)

Меня радует в ff такая фича:

<div id="id" style="float:left;border:1px solid #000;width:400px;height:100px;background: url(http://javascript.ru/forum/images/ca_serenity/misc/logo.gif) 100% 100% no-repeat;">
выдели меня
</div>
<div style="float:left;border:1px solid #000;width:400px;height:100px;background:-moz-element(#id);"></div>

DjDiablo 28.09.2012 22:13

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

думаю можно двигать много дивов на 1 пиксель
для первого эксперемента в них видна картинка целиком(без масштабирования),
для второго эксперемента в квадратиках большая картинка +она немного масштабированная и видно только её часть.

Если содержимое дива берётся из кэша то за один отрезок времени в обоих случаях пройденное расстояние будет примерно одинаковое.

дивы недолжны уходить за экран, значит им придётся бегать слева направо и справо на лево, минут по 10 допустим.
интересно сравнить также с пустыми дивами.

возможно сенсаций и небудет, но пока непопробуем наверняка не узнаем)


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