我正在使用重新设计的 hoverizr 插件版本,该插件在图像顶部显示画布以进行灰度缩放。
在每个浏览器中它都可以正常工作,甚至是 IE9 ......好吧,除了一个奇怪的问题。
这张照片显示了品牌的外观,每个品牌都调用了插件。(忽略蓝色矩形,那是我在 F12 工具中选择的)
这张照片显示了 IE9 中发生的事情。
现在只有在调用插件时才会发生这种情况,如果不是,那么它们会像第一个镜头一样排列(尽管是全彩色版本)。更烦人的是我不知道如何开始调试它,因为一旦你将鼠标悬停在其中一个品牌上,它就会自行纠正!
查看可怕的 IE F12 工具为您提供的 css 显示悬停前后没有区别。但有些事情正在发生!
那么,关于我如何开始调试这个的任何想法,或者关于它发生了什么的答案?下面是脚本
(function ($) {
$.fn.hoverizr = function (settings) {
var defaults = {
/**
* Is the image tag wrapped in a link?
* If it is we will apply the effect on the
* link becoming active as well
*/
'link' : false,
/**
* What effect do you wish to apply?
* Possible values:
* * grayscale
* * invert
* * blur
* * noise
*/
'effect' : "grayscale",
/**
* How should we show the canvas element?
* "top":
* * Show canvased element by default
* * Show original image upon hover
* "bottom"
* * Show original element by default
* * Show canvased element upon hover
*/
'overlay' : "top",
/**
* What class should we give the container?
* The container is created and wraps the
* new canvas and image element
*/
'container': "overlayed",
/**
* What class should we give the canvas?
*/
'canvas' : "canv",
/**
* What width should we give the canvas?
* Also affects the original image
*/
'width' : "responsive",
/**
* What height should we give the canvas element
* Also affects the original image
*/
'height' : "auto",
/**
* Should we allow the container to stretch to fill
* all available space?
*/
'stretch' : "no",
/**
* How fast should the switch in be?
*/
'speedIn' : "slow",
/**
* How fast should the switch out be?
*/
'speedOut' : "fast"
};
/**
* Merge the defaults and the new settings together to give us
* the user options
*/
var options = $.extend(defaults, settings);
this.each(function () {
var containerOffset;
var imageOffset;
/**
* We use this as a counter all over the place!
*/
var i, j, k = 0;
/**
* Cache the jQuery selector for the image
*/
var $image = $(this);
var rawImage = this;
/**
* Create and cache the jQuery selector for the container
*/
$image.wrap('<div class="'+options.container+'"></div>');
var $container = $image.parent();
/**
* We wrap everything in .load() because we cannot
* access the image data if it's not loaded yet!
*/
$image.load(function () {
/**
* Set's the max-width of the image
* Also, let's store a flag to say whether we
* changed it or not
*/
var maxWidthSet = false;
if ($image.css('maxWidth') != "none") {
maxWidthSet = true;
$image.css('maxWidth', "none")
}
/**
* Calculate the offset difference between the container
* and the image, then we know how to properly position
* the canvas element
*/
containerOffset = $container.offset();
imageOffset = $image.offset();
var position = {
top : imageOffset.top - containerOffset.top,
left: imageOffset.left - containerOffset.left
};
/**
* Create and cache the jQuery selector for the canvas
*/
var $canvas = $('<canvas></canvas>', {class: options.canvas});
var rawCanvas = $canvas.get(0);
$container.append($canvas);
/**
* Let's store the image dimensions too, we will need to
* give those to the canvas element
*/
var dimensions = {
height: $image.height(),
width : $image.width()
};
$canvas.prop(dimensions);
/**
* We need the container to be relative so when we position
* the canvas it is relative to the container
*/
$container.css('position', 'relative');
/**
* Now we position the canvas so it should exactly cover the image
*/
$canvas.css({'position': 'absolute', top: position.top, left: position.left, 'z-index': 10, display: 'block'});
/**
* Now let's set the Z-index so it sits in the right z-plane
* relative to the canvas
* Also, if the canvas is meant to be displayed only on hover
* We might want to hide that too!
*/
if (options.overlay == "top") {
$image.css({'z-index': -1})
} else {
$image.css({'z-index': 1});
$canvas.css({'display': 'none'});
}
/**
* Get the Canvas in a 2d context and draw the image to it
* in the upper left (0,0) hand corner
*/
var rawCanvasContext2d = rawCanvas.getContext('2d');
rawCanvasContext2d.drawImage(rawImage, 0, 0);
/**
* Apart from the noise an blur effects we will need to grab the image data
* netscape has a quirk where you must ask for permission, so if we fail to
* grab the image data we can try that (assuming netscape actually exists)
* and then try again. If that fails then things are kaput and we will die.
*/
if (options.effect != 'noise' && 'blur') {
var canvasImage;
try {
try {
canvasImage = rawCanvasContext2d.getImageData(0, 0, dimensions.width, dimensions.height)
} catch (e) {
if (typeof netscape !== 'undefined') {
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
}
canvasImage = rawCanvasContext2d.getImageData(0, 0, dimensions.width, dimensions.height);
}
} catch (e) {
throw new Error("unable to access image data: " + e)
}
var canvasImageData = canvasImage.data;
}
switch (options.effect) {
case"invert":
for (i = 0; i < canvasImageData.length; i += 4) {
canvasImageData[i] = 255 - canvasImageData[i];
canvasImageData[i + 1] = 255 - canvasImageData[i + 1];
canvasImageData[i + 2] = 255 - canvasImageData[i + 2]
}
break;
case"blur":
var newImage = new Image;
newImage.src = $image.prop('src');
rawCanvasContext2d.globalAlpha = 0.0625;
for (j = -3; j < 3; j += 1) {
for (k = -3; k < 3; k += 1) {
rawCanvasContext2d.drawImage(newImage, k, j)
}
}
rawCanvasContext2d.globalAlpha = 1;
break;
default:
for (i = 0; i < canvasImageData.length; i += 4) {
var effectData = canvasImageData[i] * .3 +
canvasImageData[i + 1] * .59 +
canvasImageData[i + 2] * .11;
canvasImageData[i] = effectData;
canvasImageData[i + 1] = effectData;
canvasImageData[i + 2] = effectData
}
break
}
/**
* Now that we have created the effect apart from blur and noise we need
* to put the data back into the canvas2d context
*/
if (options.effect != ("blur" || "noise")) {
rawCanvasContext2d.putImageData(canvasImage, 0, 0);
}
/**
* Now we can really play around with the positioning
*/
if (options.width == "responsive") {
$canvas.css({'max-width': '100%'});
$image.css({'max-width': '100%'});
$container.css({'width': '100%'})
} else if (options.stretch == "no") {
$container.css({'width': options.width, 'height': options.height, overflow: "hidden"})
} else {
$canvas.css({'width': options.width, 'height': options.height});
$image.css({'width': m.width, 'height': m.height});
$container.css({'width': m.width, 'height': m.height})
}
if (maxWidthSet) {
$image.css('maxWidth', "100%")
}
/**
* And now we can hook up the different events
* We will add two new functions to the canvas element
* so we only have to change them in one place,
* also make the event handlers nicer
*/
$canvas.in = function () {
$canvas.stop(true, true).fadeIn(options.speedIn);
};
$canvas.out = function () {
$canvas.stop(true, true).fadeOut(options.speedOut);
};
if (options.overlay == "top") {
if (options.link) {
$(this).closest('a').on('focus', $canvas.out).on('blur', $canvas.in);
}
$container.hover($canvas.out, $canvas.in);
} else {
if (options.link) {
$(this).closest('a').on('focus', $canvas.in).on('blur', $canvas.out);
}
$container.hover($canvas.in, $canvas.out);
}
});
/**
* We re-assign the image src property because if the image
* was loaded from cache before the plugin was initialized
* the load event is never triggered, this triggers a reload
*/
var src = $image.prop('src');
$image.prop('src', '').prop('src', src);
});
}
})(jQuery);