@featherds/ripple
Version:
A wee ripple.
110 lines (109 loc) • 2.9 kB
JavaScript
import { defineComponent, h } from "vue";
import { _clearTimeout, _setTimeout } from "@featherds/utils/setTimeout";
const props = {
center: {
type: Boolean,
default: false
}
};
const _sfc_main = defineComponent({
props,
data() {
return {
pressed: false,
active: false,
styles: {},
failsafe: -1
};
},
computed: {
parent() {
return this.$el.parentNode;
}
},
methods: {
onClick($event) {
this.pressed = false;
this.active = false;
requestAnimationFrame(() => {
const { clientWidth, clientHeight } = this.parent;
const size = Math.round(Math.max(clientWidth, clientHeight));
let position = {
top: "0px",
left: "0px"
};
if (!this.center) {
const rect = this.parent.getBoundingClientRect();
const top = $event.pageY;
const left = $event.pageX;
position = {
top: `${top - rect.top - size / 2 - document.documentElement.scrollTop}px`,
left: `${left - rect.left - size / 2 - document.documentElement.scrollLeft}px`
};
}
this.styles = {
...position,
height: `${size}px`,
width: `${size}px`
};
this.pressed = true;
requestAnimationFrame(() => {
this.active = true;
_clearTimeout(this.failsafe);
this.failsafe = _setTimeout(() => {
this.pressed = false;
this.active = false;
}, 380 + 100 + 20);
});
});
},
cleanupEventListeners() {
if (this.parent) {
this.parent.removeEventListener("click", this.onClick);
}
}
},
render() {
if (this.pressed === false) {
return void 0;
}
return h("div", {
style: { ...this.styles },
class: ["ripple", { active: this.active, center: this.center }],
onTransitionEnd: () => {
this.pressed = false;
this.active = false;
},
onTransitionCancel: () => {
this.pressed = false;
this.active = false;
}
});
},
mounted() {
this.parent.addEventListener("click", this.onClick);
const parentStyles = window.getComputedStyle(this.parent);
this.parent.style.overflow = "hidden";
if (parentStyles.position === "relative" || parentStyles.position === "absolute" || parentStyles.position === "fixed") {
return;
}
this.parent.style.position = "relative";
},
beforeUnmount() {
this.cleanupEventListeners();
},
unmounted() {
this.cleanupEventListeners();
}
});
const _export_sfc = (sfc, props2) => {
const target = sfc.__vccOpts || sfc;
for (const [key, val] of props2) {
target[key] = val;
}
return target;
};
const FeatherRipple = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-bcadad4b"]]);
export {
FeatherRipple
};