Hoverizr – jQuery 插件的深度视图

已发表: 2015-10-19

作为一名网页设计师,您有时可能需要让灰度图像在鼠标悬停时淡入颜色。 所以典型的解决方案是让每个图像去饱和以在 Photoshop 中实现灰度效果。 然后,您必须在标记中添加一些额外的 div 和图像标签,然后添加一些 jQuery 魔术来淡入淡出图像。 或者,您可以将两个图像合并为一个高度加倍的较大图像,并在 CSS 和 Javascript 文件中使用背景定位。


让我们来看看这两种解决方案的优缺点:

优点:

  • 如果您使用图像精灵(两个图像在一个文件中),那么您对每个图像的 HTTP 请求就会减少。

缺点:

  • 您必须单独操作每个图像,这意味着客户端可能无法动态更新具有该效果的图像,这是一个耗时的过程。
  • 如果您使用两个图像,那么您将有许多 HTTP 请求。 无论哪种方式,如果图像很大,网站就会变得非常缓慢。
  • 您需要为悬停和淡入淡出效果编写 jQuery 代码。

每次都必须这样做真的让我很吃惊,所以我搜索了一种方法来为每个图像动态地执行此操作,而无需丢失语义标记并且不必处理每个图像。

输入画布元素。 随着 HTML5 的引入,canvas 元素在社区中变得越来越突出。 你们中的大多数人已经听说过画布的作用,所以我不会在这里深入探讨。 我需要 canvas 的图像处理能力。 您可以在画布中导入图像并操作每个像素的值。

这几乎就是我开发 Hoverizr 插件所需要的。 一个 jQuery 插件,可为目标图像动态添加效果(灰度、模糊或颜色反转),并包括鼠标悬停时的淡出/淡入效果。 并且,跟随网页设计趋势,它是完全响应的。

这就是我们将在顶部的操纵版本中很好地淡出所实现的效果:

您可以在此处查看实时示例以及 Hoverizr 的其他效果的演示。

现在让我们开始吧。

悬浮液

Hoverizr 分为三个部分。

  1. 初始化并创建所需的元素。
  2. 创建画布元素并添加效果。
  3. 为目标图像元素添加悬停淡入/淡出效果。

Hoverizr 采用像这样的简单标记......

 <img class="classname" src="image-file" />

......并输出这样的东西......

 <div class="hoverizr-container">
	<img class="classname" src="image-file" />
	<canvas class=".canv"></canvas>
</div>

第 1 部分。初始化和创建所需的元素

为了实现这个标记并在画布、图像和 div 容器上添加基本样式,我在.each()函数中使用了下面的 jQuery 来影响所有目标图像:

 $(this).wrap('<div class="hoverizr-container" />');
$(this).parent('.hoverizr-container').css({'position':'relative'});
$(this).parent('.hoverizr-container').append('<canvas class="canv"></canvas>');
$(this).next('.canv').css({'position':'absolute','top':'0','left':'0','z-index':10});

$(this)指的是我们的代码在初始化时针对的每个图像。 我们创建一个包装目标图像元素的 div,我们将其位置设置为相对,以使图像和画布彼此重叠。 然后我们在图像元素下方创建画布元素,最后添加一些样式以将画布准确定位在图像顶部。

当然,在插件的代码中有些部分是不同的。

第 2 部分。创建画布元素并添加效果

在第二部分,我们将初始化画布并执行图像操作。 出于本教程的目的,我将只解释灰度效果。

首先,我们获取两个变量的宽度和高度,以便在画布初始化时使用它们。 同样, $(this)指的是插件目标的每个图像。

 var 宽度 = $(this).width();
var 高度 = $(this).height();

让我们创建我们的画布:

 $(this).next('.canv').attr({"width": width ,"height": height});
var canvas = $(this).next('.canv').get(0);
var context = canvas.getContext("2d");
var image = $(this).get(0);
context.drawImage(图像, 0, 0);

所以我们设置画布的宽度和高度,我们将元素获取到变量,获取上下文,最后将我们的图像添加到上下文中。

现在为图像处理魔法!

 尝试 {
      尝试 { 
	var imgd = context.getImageData(0, 0, 宽度, 高度)  
      } 抓住 (e) { 
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
	var imgd = context.getImageData(0, 0, 宽度, 高度) 
      } 						 
} 抓住 (e) {
throw new Error("无法访问图像数据:" + e)
} 
						
var pix = imgd.data;

整个尝试和捕获部分是为某些具有额外安全措施的浏览器启用特权(当然没有关键)。 我们有一个新的imgd变量来存储图像数据,然后我们将其作为数组保存在pix变量中。

现在灰度效果:

 for (var i = 0, n = pix.length; i < n; i += 4) {
	var 灰度 = pix[i] * .3 + pix[i+1] * .59 + pix[i+2] * .11; 
	pix[i] = 灰度; // 红色的
	pix[i+1] = 灰度; // 绿色
	pix[i+2] = 灰度; // 蓝色
	// i+3 是 alpha(第四个元素)
}
context.putImageData(imgd, 0, 0);

我们这里有一个重复的模式。 pix数组的每四个值代表一个像素的红色、绿色、蓝色和 alpha 值。 显然我们不想更改 alpha,所以我们将其省略。 我不只是获取三个颜色通道的平均值,而是使用从一个很好的教程 HTML5 Canvas Image Effects: Black & White 中得到的一个很好的公式。 最后,我们将新的图像数据放回画布上。

第 3 部分。为目标图像元素添加悬停淡入/淡出效果

这是最后的部分,也可能是最简单的部分。 当鼠标悬停在画布上时,使画布淡出以显示下方的原始图像。

 this.parent('.hoverizr-container').hover(function() {
	$(this).children('.canv').stop(true,true).fadeOut("fast");
	},功能() {
	$(this).children('.canv').stop(true,true).fadeIn("slow");
});

这又代表目标图像元素。 悬停功能几乎是不言自明的。 我们所做的就是瞄准画布,停止任何排队的动画并将其退出。 速度设置为“快”,但可以设置为“慢”或以毫秒为单位的编号值。 当悬停完成时,第二个功能发生,再次淡入画布。

已知问题

如果您尝试使用来自其他域的图像,则可能会出现浏览器的安全措施。 不幸的是,目前我们无能为力。 图片需要托管在与您的页面相同的域中。

Hoverizr 与本教程

Hoverizr 是一个插件,它已经拥有实现此效果所需的一切以及模糊和颜色反转效果。 它有很多自定义选项,包括宽度和高度设置、淡入淡出速度设置等等。 本教程的目的只是展示 Hoverizr 的一些更好的部分是如何工作的。 该代码将无法按原样工作,因为它是插件的一部分 - 剥离了基础知识 -。

如果您对使用 Hoverizr 感兴趣,对其进行改进或给我任何建议,请随时在此处查看:Hoverizr jQuery 插件。