这是一个特殊的网页设计技巧,它总是能吸引人们的眼球!我不知道是谁最先想到这个想法,以及所有这些事情的历史,但我确实知道,这些年来我见过许多此类效果的实现。我想在这里总结一些。
Noel Delagado
查看 CodePen 上 Noel Delgado (@noeldelgado) 编写的笔 方向感知 3D 悬停效果(概念)。
此处的检测通过跟踪 mouseover
和 mouseout
事件上的鼠标位置并计算跨越的哪一侧来完成。这是一小段巧妙的 JavaScript 代码,其核心是找出该方向。
var getDirection = function (ev, obj) {
var w = obj.offsetWidth,
h = obj.offsetHeight,
x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)),
y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)),
d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4;
return d;
};
然后根据该方向应用类名以触发方向性 CSS 动画。
Fabrice Weinberg
查看 CodePen 上 Fabrice Weinberg (@FWeinb) 编写的笔 方向感知悬停纯 CSS。
Fabrice 这里只使用纯 CSS。他们没有检测传出的方向,但他们确实通过四个隐藏的可悬停框检测传入的方向,每个框都旋转以覆盖一个三角形。像这样
Codrops
在 Mary Lou 于 2012 年在 Codrops 上发表的一篇文章中,使用 CSS3 和 jQuery 实现方向感知悬停效果,检测也是在 JavaScript 中完成的。这是插件的这部分代码
_getDir: function (coordinates) {
// the width and height of the current div
var w = this.$el.width(),
h = this.$el.height(),
// calculate the x and y to get an angle to the center of the div from that x and y.
// gets the x value relative to the center of the DIV and "normalize" it
x = (coordinates.x - this.$el.offset().left - (w / 2)) * (w > h ? (h / w) : 1),
y = (coordinates.y - this.$el.offset().top - (h / 2)) * (h > w ? (w / h) : 1),
// the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123);
// first calculate the angle of the point,
// add 180 deg to get rid of the negative values
// divide by 90 to get the quadrant
// add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/
direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
return direction;
},
不过,从技术上讲,CSS 负责执行动画,因为根据需要将内联样式应用于元素。
John Stewart
查看 CodePen 上 John Stewart (@johnstew) 编写的笔 方向感知悬停效果。
John 依靠 Greensock 来完成此处的所有检测和动画工作。与所有示例一样,它也有自己的几何数学来计算元素悬停的方向。
// Detect Closest Edge
function closestEdge(x,y,w,h) {
var topEdgeDist = distMetric(x,y,w/2,0);
var bottomEdgeDist = distMetric(x,y,w/2,h);
var leftEdgeDist = distMetric(x,y,0,h/2);
var rightEdgeDist = distMetric(x,y,w,h/2);
var min = Math.min(topEdgeDist,bottomEdgeDist,leftEdgeDist,rightEdgeDist);
switch (min) {
case leftEdgeDist:
return "left";
case rightEdgeDist:
return "right";
case topEdgeDist:
return "top";
case bottomEdgeDist:
return "bottom";
}
}
// Distance Formula
function distMetric(x,y,x2,y2) {
var xDiff = x - x2;
var yDiff = y - y2;
return (xDiff * xDiff) + (yDiff * yDiff);
}
Gabrielle Wee
查看 CodePen 上 Gabrielle Wee ✨ (@gabriellewee) 编写的笔 纯 CSS 方向感知立方体链接。
Gabrielle 完全通过 CSS 完成了这项工作,方法是定位四个可悬停的子元素,这些元素根据悬停的哪个元素来触发兄弟元素(立方体)上的动画。这里有一些棘手的东西涉及到 clip-path
和转换,我承认我并不完全理解。可悬停区域似乎不像您预期的那样是三角形,而是覆盖一半区域的矩形。看起来它们会无效地重叠,但它们似乎没有。我认为这可能是因为它们稍微悬挂在边缘上,从而形成了一个悬停区域,允许每个边缘具有完整的边缘覆盖范围。
Elmer Balbin
查看 CodePen 上 Elmer Balbin (@elmzarnsi) 编写的笔 使用 clip-path 纯 CSS 实现方向感知图块。
Elmer 这里也使用了 clip-path,但四个可悬停元素被剪裁成三角形。您可以看到它们中的每一个都在 50% 50%(正方形的中心)处有一个点,并且还有另外两个角点。
clip-path: polygon(0 0, 100% 0, 50% 50%)
clip-path: polygon(100% 0, 100% 100%, 50% 50%);
clip-path: polygon(0 100%, 50% 50%, 100% 100%);
clip-path: polygon(0 0, 50% 50%, 0 100%);
Nigel O Toole
原始 JavaScript 为 Nigel 的此处演示提供动力,该演示已全部现代化,可以使用 npm 和模块以及所有这些内容。不过,计算方式很熟悉。
const _getDirection = function (e, item) {
// Width and height of current item
let w = item.offsetWidth;
let h = item.offsetHeight;
let position = _getPosition(item);
// Calculate the x/y value of the pointer entering/exiting, relative to the center of the item.
let x = (e.pageX - position.x - (w / 2) * (w > h ? (h / w) : 1));
let y = (e.pageY - position.y - (h / 2) * (h > w ? (w / h) : 1));
// Calculate the angle the pointer entered/exited and convert to clockwise format (top/right/bottom/left = 0/1/2/3). See https://stackoverflow.com/a/3647634 for a full explanation.
let d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4;
// console.table([x, y, w, h, e.pageX, e.pageY, item.offsetLeft, item.offsetTop, position.x, position.y]);
return d;
};
JavaScript 最终应用类,这些类根据一些 花哨的 Sass 生成的动画在 CSS 中进行动画处理。
Giana
一个纯 CSS 实现,可以很好地处理传出的方向!
查看 CodePen 上 Giana (@giana) 编写的笔 纯 CSS 方向感知悬停。
您是否在其他地方见过?您是否在构建的某些内容中使用过此功能?
喜欢纯 CSS 版本。非常巧妙。
我在 2013 年做了一个纯 CSS 版本,它类似于上面的第一个示例,但动画效果是相同的文字而不是 4 个不同的文字。
现在我再看一遍,发现它需要整理很多地方 :)
可惜只有一个对非鼠标/触控板用户来说是可用的:Nigel O Toole 的,它可以很好地处理键盘导航。Gabrielle Wee 的可以通过键盘提供视觉反馈,但每个元素下方的多个链接意味着需要反复按 Tab 键才能跳过每个链接。
其余的从“你为什么生气?我们给你留下了默认的模糊蓝色轮廓”到“哈哈,我们甚至把它去掉了!键盘用户滚粗!悬停至上!”刻意破坏默认浏览器行为。
我喜欢这些东西,并认为它们很漂亮且很聪明,但是,如果您要积极地使互联网对我们中很大一部分人无法使用,请停止。
嗨,匿名柏林人,
我非常喜欢你的回答。早些时候,我经常访问这样的画廊,从中挑选出一堆有趣的解决方案。但很长一段时间以来,我停止实施低质量的解决方案。糟糕的可用性或无障碍性就是低质量。测试需要花费大量时间。我认为现在它已经不值得了。要找到一个可访问的解决方案需要进行如此多的测试,以至于从一开始就自己做会更省事。
因此,我感谢你进行了测试,并感谢 Paul O`Brien 展示了他自己的带有键盘支持的纯 CSS 解决方案!Nigel 和 Paul 为这组想法添加了很棒的作品。谢谢!
关于无障碍性:很高兴看到,我不是唯一一个。所有不可访问的示例都是很好的灵感,说明它可能是什么样子。快速和粗糙的原型是可以接受的。我认为代码本身仅仅是一个草稿——在最好的情况下。无论如何,它并非一无是处。它可以用作我自己的工作的起点或用于教学的“不要这样做”示例。 ;-)
只是很可惜,无障碍性似乎仍然不是大多数网站质量保证流程的一部分。人们可能会认为,每个开发人员都应该听说过它以及它为什么重要。对于那些不在乎的开发人员,这说明了什么?
我脑子里没有好话来形容这种行为。我希望 CSS Tricks 将在未来的帖子中引入标签或其他东西来突出显示可用的解决方案。
我真的很感激这一点,这样的画廊也会变得更有意思!
感谢这篇文章,它不仅给我们提供了一些有趣的信息,还提供了很多灵感。
这是我谦卑的示例(纯 CSS 解决方案)
https://codepen.io/Konrud/embed/XZMPyg?height=700
感谢 Chris 将我的插件包含在这个列表中,我已经访问这个网站多年了,所以很高兴我的作品能被推荐。也要感谢 Anonymous Berlinerin,我一直努力让我的作品易于访问,很高兴这一点得到了认可。我刚刚更新了插件,以获得更好的移动设备支持和新的动画,请查看一下。 https://nigelotoole.github.io/direction-reveal/