К сожалению в заголовке темы не смог охватить всю глубину и суть проблемы.
Есть два рабочих скрипта.
Первый увеличивает картинку по нажатию. Алгоритм заключается в присвоении src картинки новому пустому img позиционированному по центру на переднем плане:
<img src="test.jpg" />
<table id="FixedBlack" style="position: fixed; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.50); display: none; opacity: 0; z-index:100000;">
<tr>
<td style="text-align: center;">
<img src="" id="big_pic" style="position: relative; background: #fff; box-shadow: 0 0 10px white; border: 5px solid #fff; border-radius: 6px;" />
</td>
</tr>
</table>
<script type="text/javascript">
$(document).ready(function () {
$(document).on("click", ".colorup", function () {
if ($(this).attr("src") != "") {
$("#big_pic").attr("src", $(this).attr("src"));
$("#FixedBlack").show().fadeTo(200, 1);
$("#big_pic").show().fadeTo(0.5, 1);
}
});
$(document).on("click", "#FixedBlack", function () {
$("#big_pic").hide();
$("#FixedBlack").stop(true).fadeTo(200, 0, function () {
$("#FixedBlack").hide();
});
});
});
</script>
Второй нужен для применения цветового фильтра к картинке. Алгоритм его заключается в создании обработанной копии картинки на месте самой картинки, и добавления прозрачности при наведении на копию. Таким образом получаем плавный переход между копией и оригиналом.
<img src="test.jpg" speed="200" class="colorup" inverse="true" effect="sepia" />
jQuery.fn.colorUp = function () {
$(window).load(function () {
$('.colorup').each(function () {
var curImg = $(this).wrap('<span />');
var newImg = curImg.clone().css({ "position": "absolute", "z-index": "98", "opacity": "0" }).insertBefore(curImg);
newImg.attr("src", grayImage(this, curImg.attr("effect")));
newImg.addClass('colorUpped').animate({ opacity: getInv(curImg) ? 1 : 0 }, getSpeed(curImg));
});
$('.colorUpped').mouseover(function () {
$(this).stop().animate({ opacity: getInv($(this)) ? 0 : 1 }, getSpeed($(this)),"swing",function(){alert("all done");});
})
$('.colorUpped').mouseout(function () {
$(this).stop().animate({ opacity: getInv($(this)) ? 1 : 0 }, getSpeed($(this)));
});
});
function getSpeed(elem) {
return (elem.attr("speed")) ? parseInt(elem.attr("speed")) : 1000;
}
function getInv(elem) {
return (elem.attr("inverse") && (elem.attr("inverse") === "true")) ? true : false;
}
function grayImage(image, effect) {
var myCnv = document.createElement("canvas");
var myCtx = myCnv.getContext("2d");
myCnv.width = image.width;
myCnv.height = image.height;
myCtx.drawImage(image, 0, 0);
var imgData = myCtx.getImageData(0, 0, myCnv.width, myCnv.height);
for (var y = 0; y < imgData.height; y++) {
for (var x = 0; x < imgData.width; x++) {
var pos = (y * 4) * imgData.width + (x * 4);
switch (effect) {
case ("sepia"):
var mono = imgData.data[pos] * 0.32 + imgData.data[pos + 1] * 0.5 + imgData.data[pos + 2] * 0.18;
imgData.data[pos] = mono + 50;
imgData.data[pos + 1] = mono;
imgData.data[pos + 2] = mono - 50;
break;
case ("negative"):
imgData.data[pos] = 255 - imgData.data[pos];
imgData.data[pos + 1] = 255 - imgData.data[pos + 1];
imgData.data[pos + 2] = 255 - imgData.data[pos + 2];
break;
case ("light"):
imgData.data[pos] = imgData.data[pos] + 80;
imgData.data[pos + 1] = imgData.data[pos + 1] + 80;
imgData.data[pos + 2] = imgData.data[pos + 2] + 80;
break;
case ("dark"):
imgData.data[pos] = imgData.data[pos] - 80;
imgData.data[pos + 1] = imgData.data[pos + 1] - 80;
imgData.data[pos + 2] = imgData.data[pos + 2] - 80;
break;
case ("noise"):
var noise = (0.5 - Math.random()) * 160;
imgData.data[pos] = imgData.data[pos] + noise;
imgData.data[pos + 1] = imgData.data[pos + 1] + noise;
imgData.data[pos + 2] = imgData.data[pos + 2] + noise;
break;
default:
imgData.data[pos] = imgData.data[pos + 1] = imgData.data[pos + 2] = imgData.data[pos] * 0.32 + imgData.data[pos + 1] * 0.5 + imgData.data[pos + 2] * 0.18
}
}
}
myCtx.putImageData(imgData, 0, 0, 0, 0, imgData.width, imgData.height);
return myCnv.toDataURL();
}
};
$.fn.colorUp();
Как я уже сказал - каждый из скриптов великолепно работает по отдельности, но при попытки их объединить возникает закономерная проблема - нажимаем на изображение, а увеличивается не оригинал (как задумано), а копия оригинала обработанная в соответствующем цвете. Это закономерно - ведь на переднем плане по z-index находиться копия.
Думая что самый умный, я попробовал изменять z-index копии при наведении на нее мышки, добавив это в функции изменения прозрачности второго скрипта:
$('.colorUpped').mouseover(function () {
$(this).stop().animate({ opacity: getInv($(this)) ? 0 : 1 }, getSpeed($(this)));
$(this).css( "z-index:1;" );
})
$('.colorUpped').mouseout(function () {
$(this).stop().animate({ opacity: getInv($(this)) ? 1 : 0 }, getSpeed($(this)));
$(this).css( "z-index:98;" );
})
И столкнулся с новой проблемой - как только z-index становиться равен 1 сразу же срабатывает функция .mouseout и z-index возвращает свое значение в 98.
В итоге я решил что наверное проще во втором скрипте сделать функцию увеличения картинки по клику используя следующий алгоритм:
сохраняю в отдельную переменную src оригинала и потом пытаюсь ее передать элементу "FixedBlack" из первого примера. Но не тут то было - это не работает. У меня есть подозрение что это из-за того, что скрипт я располагаю в самом начале в head и элемент просто еще не существует, но я это так и не проверил (идея появилась только сейчас пока писал это).
Собственно вопросы:
1) Может можно проще, а я просто перемудрил?
2) Как можно на чистом jquery увеличить картинку поставив её на передний план (может опять же можно проще?).
3) .mouseover .mouseout и .hover одинаково ли работают или возможно есть подводные камни?