UNPKG

vue-chevron

Version:

Animated chevron toggle component

187 lines (173 loc) 4.51 kB
/*! * vue-chevron v0.1.0 * (c) 2017-present Ispal <irpa.oss@gmail.com> * Released under the MIT License. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.VueChevron = factory()); }(this, (function () { 'use strict'; var animationId; var lastTime = null; function linear(t) { return t; } function animate(duration, component) { lastTime = component.progress <= 1 ? performance.now() : lastTime; var animation = function (t) { var progress = (t - lastTime) / duration; if (progress >= 1) { window.cancelAnimationFrame(animationId); component.clickProgress = 1; component.progress = 1; return; } component.progress = component.easing(progress); animationId = window.requestAnimationFrame(animation); }; animationId = window.requestAnimationFrame(animation); } function calculatePosition( pointDown, progress, lastClickProgress, height, viewBoxCenterY ) { var progressWithClick = lastClickProgress === 1 ? progress : progress + (1 - lastClickProgress); if (progressWithClick >= 1) { progressWithClick = 1; } var topY = viewBoxCenterY + height / 2 - progressWithClick * height; var bottomY = viewBoxCenterY - height / 2 + progressWithClick * height; return pointDown ? topY : bottomY; } var index = { name: "VueChevron", props: { pointDown: { type: Boolean, default: true }, duration: { type: Number, default: 500 }, thickness: { type: Number, default: 4 }, angle: { type: Number, default: 40 }, roundEdges: { type: Boolean, default: true }, easing: { type: Function, default: linear } }, data: function data() { return { progress: 1, clickProgress: 1, reverse: false, lineLength: 30 }; }, computed: { path: function path() { var progress = this.progress; var ref = this.triangleSideLengths; var width = ref.width; var height = ref.height; var ref$1 = this.viewBoxCenter; var x = ref$1.x; var y = ref$1.y; var clickProgress = this.clickProgress; var sidesY = calculatePosition( this.pointDown, progress, clickProgress, height, y ); var centerY = calculatePosition( !this.pointDown, progress, clickProgress, height, y ); return ("M" + (x - width) + "," + sidesY + ", " + x + "," + centerY + " " + (x + width) + "," + sidesY); }, triangleSideLengths: function triangleSideLengths() { var height = this.lineLength * Math.sin(this.angle * (Math.PI / 180)); var width = this.lineLength * Math.cos(this.angle * (Math.PI / 180)); return { width: width, height: height }; }, viewBoxCenter: function viewBoxCenter() { var ref = this.viewBoxSize; var width = ref.width; var height = ref.height; return { x: width / 2, y: height / 2 }; }, viewBoxSize: function viewBoxSize() { var lineLength = this.lineLength; var thickness = this.thickness; var width = Math.ceil(lineLength * 2 + thickness * 2); var height = Math.ceil( lineLength * 2 * Math.sin(this.angle * (Math.PI / 180)) + thickness * 2 ); return { width: width, height: height }; } }, watch: { pointDown: function() { this.clickProgress = this.progress; this.progress = 0; window.cancelAnimationFrame(animationId); animate(this.duration, this); } }, render: function render(h) { var lineCapAndJoin = this.roundEdges ? "round" : "square"; var ref = this.viewBoxSize; var width = ref.width; var height = ref.height; return h( "svg", { attrs: { height: 32, width: 32, xmlns: "http://www.w3.org/2000/svg", viewBox: ("0 0 " + width + " " + height) } }, [ h("title", "vue-chevron"), h("path", { attrs: { d: this.path, fill: "none", "stroke-linecap": lineCapAndJoin, "stroke-width": this.thickness, "stroke-linejoin": lineCapAndJoin, stroke: "currentColor" } }) ] ); } }; return index; })));