【发布时间】:2018-02-19 13:13:48
【问题描述】:
我发现了这个简洁的 CodePen 动画按钮组:
https://codepen.io/Zaku/pen/reGRBg
我正在尝试将它实现到我的 angular 5 项目中。
我已经走得很远了。我可以看到 svg 发生了一些事情,但它没有过渡,它是一个黑色阴影:
以下是我所做的更改:
mycomponent.ts:
import {Component, ElementRef, OnInit} from '@angular/core';
@Component({
selector: 'app-mycomponent',
templateUrl: './mycomponent.html',
styleUrls: ['./mycomponent.scss']
})
export class myComponent implements OnInit {
pathLength = 68 * 2 + 200;
group;
buttons;
svg;
path;
currentPath;
currentIndex;
constructor(private elRef:ElementRef) {}
ngOnInit() {
this.group = this.elRef.nativeElement.querySelector('.btn-group');
this.buttons = Array.prototype.slice.call(
this.group.querySelectorAll(".btn")
);
console.log(this.buttons);
this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
this.svg.setAttribute(
"viewbox",
`-1 -1 ${160 * this.buttons.length + 2} 42`
);
this.path = document.createElementNS("http://www.w3.org/2000/svg", "path");
this.currentPath = "M -80, 40";
this.currentIndex = -1;
this.activateIndex(
this.buttons.indexOf(this.group.querySelector(".active"))
);
this.group.appendChild(this.svg);
this.svg.appendChild(this.path);
this.refreshPath();
}
onClick(e) {
const index = this.buttons.indexOf(e.srcElement || e.target);
this.activateIndex(index);
}
refreshPath() {
this.path.setAttributeNS(null, "d", this.currentPath);
this.path.style.strokeDashoffset =
(-this.path.getTotalLength() + this.pathLength) * 0.9965;
}
center(index) {
return index * 160 + 80;
}
removeClass(str) {
if (this.buttons[this.currentIndex]) {
this.buttons[this.currentIndex].classList.remove(str);
}
}
addClass(str) {
if (this.buttons[this.currentIndex]) {
this.buttons[this.currentIndex].classList.add(str);
}
}
activateIndex(index) {
const lastCenter = this.center(this.currentIndex);
const nextCenter = this.center(index);
const offset = index < this.currentIndex ? -50 : 50;
const curve = index < this.currentIndex ? -30 : 30;
this.currentPath += `
L ${lastCenter + offset}, 40
C ${lastCenter + offset + curve}, 40
${lastCenter + offset + curve}, 0
${lastCenter + offset}, 0
L ${lastCenter - offset}, 0
C ${lastCenter - offset - curve}, 0
${lastCenter - offset - curve}, 40
${lastCenter - offset}, 40
L ${nextCenter + offset}, 40
C ${nextCenter + offset + curve}, 40
${nextCenter + offset + curve}, 0
${nextCenter + offset}, 0
L ${nextCenter - offset}, 0
C ${nextCenter - offset - curve}, 0
${nextCenter - offset - curve}, 40
${nextCenter - offset}, 40
L ${nextCenter}, 40`;
this.removeClass("active");
this.currentIndex = index;
this.addClass("active");
this.refreshPath();
}
}
mycomponent.html :(你会注意到我添加了 angular click watchers 来代替处理动作)
<div class="container">
<div class="btn-group">
<div (click)="onClick($event)" class="btn">First</div>
<div (click)="onClick($event)" class="btn active">Middle</div>
<div (click)="onClick($event)" class="btn">Last</div>
</div>
</div>
mycomponent.scss:
$easing: cubic-bezier(0, 0.8, 0.2, 1);
$duration: 1s;
.container {
color: #19cc95;
text-align: center;
}
.btn-group {
position: relative;
display: inline-block;
.btn {
cursor: pointer;
float: left;
height: 40px;
width: 160px;
line-height: 40px;
text-align: center;
-webkit-user-select: none;
transition: font-size 0.3s ease;
&:active {
font-size: 0.8em;
}
}
svg {
z-index: -1;
top: 0;
left: 0;
position: absolute;
width: 100%;
height: 100%;
overflow: visible;
}
path {
fill: none;
stroke: #19cc95;
stroke-dasharray: 334.9, 99999;
transition: stroke-dashoffset 1s cubic-bezier(0, 0.8, 0.2, 1);
stroke-width: 1;
}
}
以上内容还不错。点击时正确设置了“活动”类。并且 svg 黑色阴影发生变化。
显然 svg 应该被覆盖在菜单上,而这并没有发生。
我错过了什么?
【问题讨论】:
-
黑色阴影,是错误出现还是您的要求?在 codepen 中看不到它们。
-
他们错误地出现了;你试过点击codepen中的按钮吗?那条在按钮周围滑动并在它们周围形成以指示它们的活动状态的线就是我所追求的。