检测鼠标悬停在哪个元素上并传递给函数
Detect which element is moused over and pass to function
我正在使用 greensock 为 svg 剪辑路径设置动画,它非常适合使用一个剪辑路径和硬编码变量。现在我需要添加更多的剪辑路径,并且我需要每一个都独立地制作动画。所以我需要构建某种函数来检测哪个圆被鼠标悬停/移出,然后调用时间轴,向它传递正确的参数(剪辑路径和覆盖圆)。我确定我可以用 'this' 做到这一点,但我仍然处于 'this' 让我的大脑融化的地步。这是我正在使用的代码笔。
http://codepen.io/kathryncrawford/pen/JYvdzx
HTML
<svg class="svg-graphic" width="500" height="500" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="clippath">
<circle id="clip1" cx="200" cy="200" r="2.5"/>
<circle id="clip2" cx="400" cy="200" r="3.2"/>
</clipPath>
</defs>
<image class="svg-image1" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="80" y="80"/>
<circle id="circle1" fill="#CC66FF" cx="200" cy="200" r="30"/>
<image class="svg-image2" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="380" y="80"/>
<circle id="circle2" fill="#CC66FF" cx="400" cy="200" r="30"/>
JS
var clip = document.getElementById("clip1");
var circles = document.getElementById("circle1");
circles.addEventListener("mouseenter", expand);
circles.addEventListener("mouseleave", contract);
var tl = new TimelineMax({paused: true});
tl.to(clip, 0.5, {
attr: {
r: 120
},
transformOrigin: "50% 50%",
ease: Power4.easeInOut
})
.to(circles, 0.5, {alpha:0, ease:Power4.easeInOut}, '-0.1');
function expand() {
tl.play();
}
function contract() {
tl.reverse();
}
好吧,this 是我分叉你的笔所创造的。
变化如下:
- 在 HTML 中,我删除了每个
circle
[=115] 上设置的唯一 ID =] 元素存在于 clipPath
HTML 元素中,即 clipPath
的子元素。相反,我给所有这些 circle
标签一个 clip
class.
- 作为所述
clipPath
兄弟姐妹的其他 circle
元素,即与 clipPath
元素处于同一级别的元素,已被赋予 circle
class.
- 至于
image
元素,我也做过类似的事情。从它们中删除了唯一的 ID,而是给它们一个通用的 svg-image
class.
- 这 HTML 完成了。
- 在 HTML 中,因为唯一的 ID 已被删除,例如
#circle1
、#circle2
、#svg-image1
和 #svg-image2
,我也从 CSS 中删除了它们,而是应用了与新创建的 classes 完全相同的规则,即 .circle
和 .svg-image
分别。
- 在JavaScript中,
clip
和circle
元素以及clip
个元素的总数在前分别存储在变量 clips
、circles
和 numClips
中。
- 最初创建的
timelines
也是一个空数组。
- 然后会启动一个循环,它会一直上升到
numClips
的长度,它会做两件事:
createTimeline
顾名思义,应该创建一个 TimelineMax
实例,它看起来类似于您之前拥有的实例,即它添加了两个补间,一个用于动画 opacity
当前 circle
元素(记住,我们在一个循环中,我们通过使用 circles[i]
获得当前 circle
元素的引用),另一个用于动画 r
当前 clip
元素。
assignListeners
用于监听每个 circle
元素上的 mouseenter
和 mouseleave
事件。
- 最后,
expand
和 collapse
方法用于播放或倒转当前时间轴实例。 (同样,我们有 timeline
的参考,应该在悬停或离开时使用 timelines[i]
参考播放。
HTML:
<svg class="svg-graphic" width="500" height="500" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="clippath">
<circle class="clip" cx="200" cy="200" r="20" />
<circle class="clip" cx="400" cy="200" r="20" />
<circle class="clip" cx="600" cy="200" r="20" />
</clipPath>
</defs>
<image class="svg-image" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="80" y="80" />
<circle class="circle" fill="#CC66FF" cx="200" cy="200" r="20" />
<image class="svg-image" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="380" y="80" />
<circle class="circle" fill="#CC66FF" cx="400" cy="200" r="20" />
<image class="svg-image" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="680" y="80" />
<circle class="circle" fill="#CC66FF" cx="600" cy="200" r="20" />
</svg>
CSS:
*{
box-sizing: border-box;
}
body{
margin: 0;
padding: 0
}
.circle{
position: absolute;
margin: 0;
z-index: 1;
clip-path: url("#clippath");
}
.svg-image {
z-index: 3;
clip-path: url(#clippath);
}
svg{
overflow: visible;
}
.svg-graphic {
position: absolute;
}
.imgContainer {
position: relative;
width: 800px;
height: 800px;
}
JavaScript:
var clips = document.getElementsByClassName('clip');
var circles = document.getElementsByClassName('circle');
var numClips = clips.length;
var timelines = [];
for (var i = 0; i < numClips; i += 1) {
createTimeline(i);
assignListeners(i);
}
function createTimeline(i) {
var timeline = new TimelineMax({ paused: true });
timeline.to(circles[i], 0.6, { opacity: 0, ease: Expo.easeInOut }, 0);
timeline.to(clips[i], 0.6, {
attr: { r: 120 },
transformOrigin: '50% 50%',
ease: Expo.easeInOut
}, 0.1);
timelines[i] = timeline;
}
function assignListeners(i) {
(function(i) {
circles[i].addEventListener('mouseenter', function(e) { expand(e, i); }, false);
circles[i].addEventListener('mouseleave', function(e) { contract(e, i); }, false);
}(i));
}
function expand(e, i) { timelines[i].play(); }
function contract(e, i) { timelines[i].reverse(); }
希望对您有所帮助。
我正在使用 greensock 为 svg 剪辑路径设置动画,它非常适合使用一个剪辑路径和硬编码变量。现在我需要添加更多的剪辑路径,并且我需要每一个都独立地制作动画。所以我需要构建某种函数来检测哪个圆被鼠标悬停/移出,然后调用时间轴,向它传递正确的参数(剪辑路径和覆盖圆)。我确定我可以用 'this' 做到这一点,但我仍然处于 'this' 让我的大脑融化的地步。这是我正在使用的代码笔。
http://codepen.io/kathryncrawford/pen/JYvdzx
HTML
<svg class="svg-graphic" width="500" height="500" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="clippath">
<circle id="clip1" cx="200" cy="200" r="2.5"/>
<circle id="clip2" cx="400" cy="200" r="3.2"/>
</clipPath>
</defs>
<image class="svg-image1" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="80" y="80"/>
<circle id="circle1" fill="#CC66FF" cx="200" cy="200" r="30"/>
<image class="svg-image2" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="380" y="80"/>
<circle id="circle2" fill="#CC66FF" cx="400" cy="200" r="30"/>
JS
var clip = document.getElementById("clip1");
var circles = document.getElementById("circle1");
circles.addEventListener("mouseenter", expand);
circles.addEventListener("mouseleave", contract);
var tl = new TimelineMax({paused: true});
tl.to(clip, 0.5, {
attr: {
r: 120
},
transformOrigin: "50% 50%",
ease: Power4.easeInOut
})
.to(circles, 0.5, {alpha:0, ease:Power4.easeInOut}, '-0.1');
function expand() {
tl.play();
}
function contract() {
tl.reverse();
}
好吧,this 是我分叉你的笔所创造的。
变化如下:
- 在 HTML 中,我删除了每个
circle
[=115] 上设置的唯一 ID =] 元素存在于clipPath
HTML 元素中,即clipPath
的子元素。相反,我给所有这些circle
标签一个clip
class. - 作为所述
clipPath
兄弟姐妹的其他circle
元素,即与clipPath
元素处于同一级别的元素,已被赋予circle
class. - 至于
image
元素,我也做过类似的事情。从它们中删除了唯一的 ID,而是给它们一个通用的svg-image
class. - 这 HTML 完成了。
- 在 HTML 中,因为唯一的 ID 已被删除,例如
#circle1
、#circle2
、#svg-image1
和#svg-image2
,我也从 CSS 中删除了它们,而是应用了与新创建的 classes 完全相同的规则,即.circle
和.svg-image
分别。 - 在JavaScript中,
clip
和circle
元素以及clip
个元素的总数在前分别存储在变量clips
、circles
和numClips
中。 - 最初创建的
timelines
也是一个空数组。 - 然后会启动一个循环,它会一直上升到
numClips
的长度,它会做两件事:createTimeline
顾名思义,应该创建一个TimelineMax
实例,它看起来类似于您之前拥有的实例,即它添加了两个补间,一个用于动画opacity
当前circle
元素(记住,我们在一个循环中,我们通过使用circles[i]
获得当前circle
元素的引用),另一个用于动画r
当前clip
元素。assignListeners
用于监听每个circle
元素上的mouseenter
和mouseleave
事件。
- 最后,
expand
和collapse
方法用于播放或倒转当前时间轴实例。 (同样,我们有timeline
的参考,应该在悬停或离开时使用timelines[i]
参考播放。
HTML:
<svg class="svg-graphic" width="500" height="500" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" version="1.1">
<defs>
<clipPath id="clippath">
<circle class="clip" cx="200" cy="200" r="20" />
<circle class="clip" cx="400" cy="200" r="20" />
<circle class="clip" cx="600" cy="200" r="20" />
</clipPath>
</defs>
<image class="svg-image" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="80" y="80" />
<circle class="circle" fill="#CC66FF" cx="200" cy="200" r="20" />
<image class="svg-image" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="380" y="80" />
<circle class="circle" fill="#CC66FF" cx="400" cy="200" r="20" />
<image class="svg-image" xlink:href="http://lorempixel.com/300/300/" width="300" height="300" x="680" y="80" />
<circle class="circle" fill="#CC66FF" cx="600" cy="200" r="20" />
</svg>
CSS:
*{
box-sizing: border-box;
}
body{
margin: 0;
padding: 0
}
.circle{
position: absolute;
margin: 0;
z-index: 1;
clip-path: url("#clippath");
}
.svg-image {
z-index: 3;
clip-path: url(#clippath);
}
svg{
overflow: visible;
}
.svg-graphic {
position: absolute;
}
.imgContainer {
position: relative;
width: 800px;
height: 800px;
}
JavaScript:
var clips = document.getElementsByClassName('clip');
var circles = document.getElementsByClassName('circle');
var numClips = clips.length;
var timelines = [];
for (var i = 0; i < numClips; i += 1) {
createTimeline(i);
assignListeners(i);
}
function createTimeline(i) {
var timeline = new TimelineMax({ paused: true });
timeline.to(circles[i], 0.6, { opacity: 0, ease: Expo.easeInOut }, 0);
timeline.to(clips[i], 0.6, {
attr: { r: 120 },
transformOrigin: '50% 50%',
ease: Expo.easeInOut
}, 0.1);
timelines[i] = timeline;
}
function assignListeners(i) {
(function(i) {
circles[i].addEventListener('mouseenter', function(e) { expand(e, i); }, false);
circles[i].addEventListener('mouseleave', function(e) { contract(e, i); }, false);
}(i));
}
function expand(e, i) { timelines[i].play(); }
function contract(e, i) { timelines[i].reverse(); }
希望对您有所帮助。