1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | var animationId;
|
7 | var lastTime = null;
|
8 |
|
9 | function linear(t) {
|
10 | return t;
|
11 | }
|
12 |
|
13 | function animate(duration, component) {
|
14 | lastTime = component.progress <= 1 ? performance.now() : lastTime;
|
15 | var animation = function (t) {
|
16 | var progress = (t - lastTime) / duration;
|
17 | if (progress >= 1) {
|
18 | window.cancelAnimationFrame(animationId);
|
19 | component.clickProgress = 1;
|
20 | component.progress = 1;
|
21 | return;
|
22 | }
|
23 | component.progress = component.easing(progress);
|
24 | animationId = window.requestAnimationFrame(animation);
|
25 | };
|
26 | animationId = window.requestAnimationFrame(animation);
|
27 | }
|
28 |
|
29 | function calculatePosition(
|
30 | pointDown,
|
31 | progress,
|
32 | lastClickProgress,
|
33 | height,
|
34 | viewBoxCenterY
|
35 | ) {
|
36 | var progressWithClick =
|
37 | lastClickProgress === 1 ? progress : progress + (1 - lastClickProgress);
|
38 |
|
39 | if (progressWithClick >= 1) {
|
40 | progressWithClick = 1;
|
41 | }
|
42 |
|
43 | var topY = viewBoxCenterY + height / 2 - progressWithClick * height;
|
44 | var bottomY = viewBoxCenterY - height / 2 + progressWithClick * height;
|
45 |
|
46 | return pointDown ? topY : bottomY;
|
47 | }
|
48 |
|
49 | var index = {
|
50 | name: "VueChevron",
|
51 | props: {
|
52 | pointDown: {
|
53 | type: Boolean,
|
54 | default: true
|
55 | },
|
56 | duration: {
|
57 | type: Number,
|
58 | default: 500
|
59 | },
|
60 | thickness: {
|
61 | type: Number,
|
62 | default: 4
|
63 | },
|
64 | angle: {
|
65 | type: Number,
|
66 | default: 40
|
67 | },
|
68 | roundEdges: {
|
69 | type: Boolean,
|
70 | default: true
|
71 | },
|
72 | easing: {
|
73 | type: Function,
|
74 | default: linear
|
75 | }
|
76 | },
|
77 | data: function data() {
|
78 | return {
|
79 | progress: 1,
|
80 | clickProgress: 1,
|
81 | reverse: false,
|
82 | lineLength: 30
|
83 | };
|
84 | },
|
85 | computed: {
|
86 | path: function path() {
|
87 | var progress = this.progress;
|
88 | var ref = this.triangleSideLengths;
|
89 | var width = ref.width;
|
90 | var height = ref.height;
|
91 | var ref$1 = this.viewBoxCenter;
|
92 | var x = ref$1.x;
|
93 | var y = ref$1.y;
|
94 | var clickProgress = this.clickProgress;
|
95 |
|
96 | var sidesY = calculatePosition(
|
97 | this.pointDown,
|
98 | progress,
|
99 | clickProgress,
|
100 | height,
|
101 | y
|
102 | );
|
103 | var centerY = calculatePosition(
|
104 | !this.pointDown,
|
105 | progress,
|
106 | clickProgress,
|
107 | height,
|
108 | y
|
109 | );
|
110 | return ("M" + (x - width) + "," + sidesY + ", " + x + "," + centerY + " " + (x + width) + "," + sidesY);
|
111 | },
|
112 | triangleSideLengths: function triangleSideLengths() {
|
113 | var height = this.lineLength * Math.sin(this.angle * (Math.PI / 180));
|
114 | var width = this.lineLength * Math.cos(this.angle * (Math.PI / 180));
|
115 | return {
|
116 | width: width,
|
117 | height: height
|
118 | };
|
119 | },
|
120 | viewBoxCenter: function viewBoxCenter() {
|
121 | var ref = this.viewBoxSize;
|
122 | var width = ref.width;
|
123 | var height = ref.height;
|
124 | return { x: width / 2, y: height / 2 };
|
125 | },
|
126 | viewBoxSize: function viewBoxSize() {
|
127 | var lineLength = this.lineLength;
|
128 | var thickness = this.thickness;
|
129 |
|
130 | var width = Math.ceil(lineLength * 2 + thickness * 2);
|
131 | var height = Math.ceil(
|
132 | lineLength * 2 * Math.sin(this.angle * (Math.PI / 180)) + thickness * 2
|
133 | );
|
134 | return { width: width, height: height };
|
135 | }
|
136 | },
|
137 | watch: {
|
138 | pointDown: function() {
|
139 | this.clickProgress = this.progress;
|
140 | this.progress = 0;
|
141 | window.cancelAnimationFrame(animationId);
|
142 | animate(this.duration, this);
|
143 | }
|
144 | },
|
145 | render: function render(h) {
|
146 | var lineCapAndJoin = this.roundEdges ? "round" : "square";
|
147 | var ref = this.viewBoxSize;
|
148 | var width = ref.width;
|
149 | var height = ref.height;
|
150 |
|
151 | return h(
|
152 | "svg",
|
153 | {
|
154 | attrs: {
|
155 | height: 32,
|
156 | width: 32,
|
157 | xmlns: "http://www.w3.org/2000/svg",
|
158 | viewBox: ("0 0 " + width + " " + height)
|
159 | }
|
160 | },
|
161 | [
|
162 | h("title", "vue-chevron"),
|
163 | h("path", {
|
164 | attrs: {
|
165 | d: this.path,
|
166 | fill: "none",
|
167 | "stroke-linecap": lineCapAndJoin,
|
168 | "stroke-width": this.thickness,
|
169 | "stroke-linejoin": lineCapAndJoin,
|
170 | stroke: "currentColor"
|
171 | }
|
172 | })
|
173 | ]
|
174 | );
|
175 | }
|
176 | };
|
177 |
|
178 | export default index;
|