UNPKG

vue-pose

Version:

A declarative animation library for Vue

314 lines (305 loc) 8.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var tslib_1 = require('tslib'); var Vue = _interopDefault(require('vue')); var poseFactory = _interopDefault(require('popmotion-pose')); var heyListen = require('hey-listen'); var supportedElements = [ 'a', 'article', 'aside', 'audio', 'b', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'data', 'datalist', 'dialog', 'div', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'i', 'iframe', 'img', 'input', 'label', 'legend', 'li', 'nav', 'object', 'ol', 'option', 'p', 'param', 'picture', 'pre', 'progress', 'q', 'section', 'select', 'span', 'strong', 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time', 'title', 'tr', 'ul', 'video', 'circle', 'clipPath', 'defs', 'ellipse', 'g', 'image', 'line', 'linearGradient', 'mask', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'svg', 'text', 'tspan' ]; var PoserMap = new WeakMap(); var props = { pose: { type: String, default: 'init' }, preEnterPose: { type: String, default: undefined }, poseKey: { type: [String, Number], default: undefined }, onValueChange: { type: Object, default: undefined }, onPoseComplete: { type: Function, default: undefined }, withParent: { type: Boolean, default: true } }; var watch = { $attrs: function (newAttrs) { this.poser.setProps(newAttrs); }, pose: function (newPose, oldPose) { if (newPose !== oldPose) this.setPose(newPose); }, poseKey: function (newPoseKey, oldPoseKey) { if (newPoseKey !== oldPoseKey) this.setPose(this.pose); } }; function destroyed() { if (!this.poser || !this._poseDestroyOnUnmount) return; if (this._poseOnChildUnmount) this._poseOnChildUnmount(this.poser); PoserMap.delete(this.$el); this.poser.destroy(); } var methods = { getInitialPose: function () { var _a = this.$props, preEnterPose = _a.preEnterPose, pose = _a.pose; return this._poseGetInitialPoseFromParent ? this._poseGetInitialPoseFromParent() : preEnterPose || pose; }, getFirstPoseToSet: function () { var _a = this.$props, preEnterPose = _a.preEnterPose, pose = _a.pose; return preEnterPose ? pose : false; }, initPoser: function (poser) { this.poser = poser; this.flushChildren(); PoserMap.set(this.$el, poser); var firstPose = this.getFirstPoseToSet(); if (firstPose) this.setPose(firstPose); }, setPose: function (pose) { var _this = this; this.poser.set(pose).then(function () { return _this.$emit('poseComplete', pose); }); }, flushChildren: function () { var _this = this; if (!this.children) return; this.children.forEach(function (_a) { var element = _a.element, config = _a.config, onRegistered = _a.onRegistered; onRegistered(_this.poser.addChild(element, tslib_1.__assign({}, config, { initialPose: _this.getInitialPose() }))); }); this.children.clear(); }, getPoserProps: function () { return tslib_1.__assign({}, this.$attrs); } }; function provide() { var parent = this; return { _poseRegisterChild: function (child) { parent.children = parent.children || new Set(); parent.children.add(child); if (parent.poser) parent.flushChildren(); }, _poseOnChildUnmount: function (poser) { parent.poser.removeChild(poser); } }; } var inject = { _poseRegisterChild: { default: false }, _poseOnChildUnmount: { default: false }, _poseGetInitialPoseFromParent: { default: false }, _poseDestroyOnUnmount: { default: true } }; var createPosedComponentFactory = function (el) { return function (config) { if (config === void 0) { config = {}; } return Vue.extend({ props: props, provide: provide, inject: inject, mounted: function () { var _this = this; heyListen.invariant(typeof this.$el !== 'undefined', "No DOM element found."); var poserConfig = tslib_1.__assign({}, config, { initialPose: this.getInitialPose(), onDragStart: this.$listeners['drag-start'] ? function (e) { return _this.$emit('drag-start', e); } : undefined, onDragEnd: this.$listeners['drag-end'] ? function (e) { return _this.$emit('drag-end', e); } : undefined, onPressStart: this.$listeners['press-start'] ? function (e) { return _this.$emit('press-start', e); } : undefined, onPressEnd: this.$listeners['press-end'] ? function (e) { return _this.$emit('press-end', e); } : undefined, onChange: this.$props.onValueChange, props: this.getPoserProps() }); if (!this.$props.withParent || !this._poseRegisterChild) { this.initPoser(poseFactory(this.$el, poserConfig)); } else { this._poseRegisterChild({ element: this.$el, config: poserConfig, onRegistered: function (poser) { return _this.initPoser(poser); } }); } }, watch: watch, methods: methods, destroyed: destroyed, render: function (createElement) { return createElement(el, {}, [this.$slots.default]); } }); }; }; var posed = supportedElements.reduce(function (acc, el) { acc[el] = createPosedComponentFactory(el); return acc; }, {}); var setPoserTo = function (fromPose, toPose, defaultConfig, that) { return function (el, done) { if (!PoserMap.has(el)) { PoserMap.set(el, poseFactory(el, tslib_1.__assign({}, defaultConfig, { initialPose: fromPose }))); } PoserMap.get(el) .set(toPose) .then(function () { that.$emit('poseComplete', toPose); done(); }); }; }; var initPoser = function (setPrePose, initialPose) { return function () { return setPrePose(initialPose); }; }; var PoseTransition = Vue.extend({ props: { enterPose: { type: String, default: 'enter' }, exitPose: { type: String, default: 'exit' } }, provide: function () { var parent = this; return { _poseGetInitialPoseFromParent: function () { return parent.prePose; }, _poseDestroyOnUnmount: false }; }, created: function () { var _this = this; var _a; var _b = this.$props, enterPose = _b.enterPose, exitPose = _b.exitPose; var appear = this.$attrs.appear; var defaultConfig = (_a = {}, _a[enterPose] = { opacity: 1 }, _a[exitPose] = { opacity: 0 }, _a); var setPrePose = function (pose) { return (_this.prePose = pose); }; this.on = { beforeEnter: initPoser(setPrePose, exitPose), beforeLeave: initPoser(setPrePose, enterPose), enter: setPoserTo(exitPose, enterPose, defaultConfig, this), leave: setPoserTo(enterPose, exitPose, defaultConfig, this) }; if (appear !== undefined) { this.on.appear = setPoserTo(exitPose, enterPose, defaultConfig, this); this.on.beforeAppear = initPoser(setPrePose, exitPose); } }, render: function (createElement) { return createElement('transition', { props: tslib_1.__assign({ css: false }, this.$attrs), on: this.on }, [this.$slots.default]); } }); exports.default = posed; exports.PoseTransition = PoseTransition;