我正在使用 greensock 来制作 svg 剪辑路径的动画,它非常适合一个剪辑路径和硬编码变量。现在我需要添加更多剪辑路径,并且需要每个剪辑路径独立地设置动画。因此,我需要构建某种函数来检测哪个圆圈被鼠标悬停/鼠标移出,然后调用时间线,向其传递正确的参数(剪辑路径和覆盖圆圈)。我确信我可以用“这个”来做到这一点,但我仍然处于“这个”让我的大脑融化的地步。这是我正在开发的代码笔。
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 是我通过 fork 你的笔能够创建的。
以下是发生的变化:
- 在 HTML 中,我删除了
clipPath
内每个circle
HTML 元素上设置的唯一 ID> HTML 元素,即clipPath
的子元素。相反,我为所有这些circle
标签赋予了一个clip
类。 - 其他
circle
元素是所述clipPath
的同级元素,即与clipPath
元素位于同一级别,已被赋予圆
类。 - 至于
image
元素,我也做了类似的事情。从中删除了唯一的ID,并为它们提供了一个通用的svg-image
类。 - 这是 HTML 完成的。
- 在 HTML 中,由于唯一的 ID 已被删除,例如
#circle1
、#circle2
、#svg-image1
和#svg-image2
,我也将它们从 CSS 中删除,并在新创建的类(即)上应用了完全相同的规则。分别是 Circle
和.svg-image
。 - 在 JavaScript 中,首先是
clip
和circle
元素以及clip
元素的总数分别存储在变量clips
、circles
和numClips
中。 - 最初还创建了一个空的
时间线
数组。 - 然后将启动一个循环,该循环一直持续到
numClips
的长度,并执行以下两件事:createTimeline
顾名思义,应该创建一个TimelineMax
实例,它看起来与您之前的实例类似,即它添加了两个补间,一个用于为制作动画当前
(请记住,我们处于循环内部,并且通过使用circle
元素上的 >opacitycircles 获得了当前
),另一个用于为当前circle
元素的引用[i]clip
元素的r
制作动画。assignListeners
用于监听每个circle
元素上的mouseenter
和mouseleave
事件。
- 最后,
expand
和collapse
方法用于播放或反转当前时间轴实例。 (同样,我们使用timelines[i]
引用来获取悬停或移出时应播放的timeline
的引用)。
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(); }
希望这有帮助。
关于javascript - 检测鼠标悬停在哪个元素上并传递给函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33423170/