@crystal-creations/pulsating-circle
Version:
A pulsating circle wrapped in a Vue component based on a [codepen](https://codepen.io/eereeska/pen/gOPdBZg) by eereeska
265 lines (244 loc) • 15.3 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var vuePropertyDecorator = require('vue-property-decorator');
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
/**
* A pulsating circle icon.
*/
var PulsatingCircleIcon = /** @class */ (function (_super) {
__extends(PulsatingCircleIcon, _super);
function PulsatingCircleIcon() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(PulsatingCircleIcon.prototype, "pulsatingCircleStyle", {
/**
* Returns the style used for the outer div.
*/
get: function () {
var outerSize = this.size * 2 + "px;";
return ("height: " +
outerSize +
"width: " +
outerSize +
"min-height: " +
outerSize +
"min-width: " +
outerSize);
},
enumerable: false,
configurable: true
});
__decorate([
vuePropertyDecorator.Prop({ default: "white" })
], PulsatingCircleIcon.prototype, "color", void 0);
__decorate([
vuePropertyDecorator.Prop({ default: 16 })
], PulsatingCircleIcon.prototype, "size", void 0);
PulsatingCircleIcon = __decorate([
vuePropertyDecorator.Component
], PulsatingCircleIcon);
return PulsatingCircleIcon;
}(vuePropertyDecorator.Vue));
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
}
// Vue.extend constructor export interop.
const options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
let hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
const originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
const existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return script;
}
const isOldIE = typeof navigator !== 'undefined' &&
/msie [6-9]\\b/.test(navigator.userAgent.toLowerCase());
function createInjector(context) {
return (id, style) => addStyle(id, style);
}
let HEAD;
const styles = {};
function addStyle(id, css) {
const group = isOldIE ? css.media || 'default' : id;
const style = styles[group] || (styles[group] = { ids: new Set(), styles: [] });
if (!style.ids.has(id)) {
style.ids.add(id);
let code = css.source;
if (css.map) {
// https://developer.chrome.com/devtools/docs/javascript-debugging
// this makes source maps inside style tags work properly in Chrome
code += '\n/*# sourceURL=' + css.map.sources[0] + ' */';
// http://stackoverflow.com/a/26603875
code +=
'\n/*# sourceMappingURL=data:application/json;base64,' +
btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) +
' */';
}
if (!style.element) {
style.element = document.createElement('style');
style.element.type = 'text/css';
if (css.media)
style.element.setAttribute('media', css.media);
if (HEAD === undefined) {
HEAD = document.head || document.getElementsByTagName('head')[0];
}
HEAD.appendChild(style.element);
}
if ('styleSheet' in style.element) {
style.styles.push(code);
style.element.styleSheet.cssText = style.styles
.filter(Boolean)
.join('\n');
}
else {
const index = style.ids.size - 1;
const textNode = document.createTextNode(code);
const nodes = style.element.childNodes;
if (nodes[index])
style.element.removeChild(nodes[index]);
if (nodes.length)
style.element.insertBefore(textNode, nodes[index]);
else
style.element.appendChild(textNode);
}
}
}
/* script */
const __vue_script__ = PulsatingCircleIcon;
/* template */
var __vue_render__ = function () {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c(
"div",
{ staticClass: "pulsating-circle", style: _vm.pulsatingCircleStyle },
[
_c("div", { staticClass: "pulse", class: _vm.color }),
_vm._v(" "),
_c("div", { staticClass: "circle", class: _vm.color }),
]
)
};
var __vue_staticRenderFns__ = [];
__vue_render__._withStripped = true;
/* style */
const __vue_inject_styles__ = function (inject) {
if (!inject) return
inject("data-v-51775d52_0", { source: ".pulsating-circle[data-v-51775d52] {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n@keyframes pulse-data-v-51775d52 {\n0% {\n transform: scale(0.33);\n}\n80%, 100% {\n opacity: 0;\n}\n}\n@keyframes circle-data-v-51775d52 {\n0% {\n transform: scale(0.8);\n}\n50% {\n transform: scale(1);\n}\n100% {\n transform: scale(0.8);\n}\n}\n.pulsating-circle .pulse[data-v-51775d52] {\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n animation: pulse-data-v-51775d52 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;\n}\n.pulsating-circle .circle[data-v-51775d52] {\n position: absolute;\n width: 50%;\n height: 50%;\n border-radius: 50%;\n animation: circle-data-v-51775d52 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;\n}\n\n/*# sourceMappingURL=PulsatingCircle.vue.map */", map: {"version":3,"sources":["/home/runner/work/pulsating-circle/pulsating-circle/src/PulsatingCircle.vue","PulsatingCircle.vue"],"names":[],"mappings":"AAqEA;EAsBA,kBAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;ACzFA;ADiEA;AACA;IACA,sBAAA;AC/DE;ADiEF;IAEA,UAAA;AChEE;AACF;ADkEA;AACA;IACA,qBAAA;AChEE;ADkEF;IACA,mBAAA;AChEE;ADkEF;IACA,qBAAA;AChEE;AACF;ADwEA;EACA,kBAAA;EACA,WAAA;EACA,YAAA;EACA,kBAAA;EACA,mFAAA;ACtEA;ADyEA;EACA,kBAAA;EACA,UAAA;EACA,WAAA;EACA,kBAAA;EACA,8FAAA;ACvEA;;AAEA,8CAA8C","file":"PulsatingCircle.vue","sourcesContent":["<!--\nCopyright (c) 2022 by Crystal Creations GbR and Johannes Huther\nCopyright (c) 2020 by eereeska (https://codepen.io/eereeska/pen/gOPdBZg)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and\nassociated documentation files (the \"Software\"), to deal in the Software without restriction,\nincluding without limitation the rights to use, copy, modify, merge, publish, distribute,\nsublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,\nINCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR\nTHE USE OR OTHER DEALINGS IN THE SOFTWARE.\n -->\n<template>\n <div class=\"pulsating-circle\" :style=\"pulsatingCircleStyle\">\n <div class=\"pulse\" :class=\"color\"></div>\n <div class=\"circle\" :class=\"color\"></div>\n </div>\n</template>\n\n<script lang=\"ts\">\nimport { Component, Prop, Vue } from \"vue-property-decorator\";\n\n/**\n * A pulsating circle icon.\n */\n@Component\nexport default class PulsatingCircleIcon extends Vue {\n /**\n * The color of the circle and the pulse.\n *\n * Use color class in combination with \"lighten-x\" to access modified colors.\n *\n * If not set, it will be white.\n */\n @Prop({ default: \"white\" }) color!: string;\n\n /**\n * The size of the inner circle in pixels.\n *\n * The pulse (and the whole component) is 200% as big.\n */\n @Prop({ default: 16 }) size!: number;\n\n /**\n * Returns the style used for the outer div.\n */\n get pulsatingCircleStyle(): string {\n const outerSize = this.size * 2 + \"px;\";\n return (\n \"height: \" +\n outerSize +\n \"width: \" +\n outerSize +\n \"min-height: \" +\n outerSize +\n \"min-width: \" +\n outerSize\n );\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.pulsating-circle {\n @keyframes pulse {\n 0% {\n transform: scale(0.33);\n }\n 80%,\n 100% {\n opacity: 0;\n }\n }\n @keyframes circle {\n 0% {\n transform: scale(0.8);\n }\n 50% {\n transform: scale(1);\n }\n 100% {\n transform: scale(0.8);\n }\n }\n\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n\n .pulse {\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n animation: pulse 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;\n }\n\n .circle {\n position: absolute;\n width: 50%;\n height: 50%;\n border-radius: 50%;\n animation: circle 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;\n }\n}\n</style>\n",".pulsating-circle {\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n@keyframes pulse {\n 0% {\n transform: scale(0.33);\n }\n 80%, 100% {\n opacity: 0;\n }\n}\n@keyframes circle {\n 0% {\n transform: scale(0.8);\n }\n 50% {\n transform: scale(1);\n }\n 100% {\n transform: scale(0.8);\n }\n}\n.pulsating-circle .pulse {\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n animation: pulse 1.25s cubic-bezier(0.215, 0.61, 0.355, 1) infinite;\n}\n.pulsating-circle .circle {\n position: absolute;\n width: 50%;\n height: 50%;\n border-radius: 50%;\n animation: circle 1.25s cubic-bezier(0.455, 0.03, 0.515, 0.955) -0.4s infinite;\n}\n\n/*# sourceMappingURL=PulsatingCircle.vue.map */"]}, media: undefined });
};
/* scoped */
const __vue_scope_id__ = "data-v-51775d52";
/* module identifier */
const __vue_module_identifier__ = undefined;
/* functional template */
const __vue_is_functional_template__ = false;
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__ = /*#__PURE__*/normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
createInjector,
undefined,
undefined
);
exports.PulsatingCircle = __vue_component__;
//# sourceMappingURL=index.js.map