提交 4b33ffda 编写于 作者: 郭胜强

feat: 完成组件movable-area、movable-view基础功能

上级 2deea6b5
<template>
<uni-movable-area/>
</template>
<script>
function calc (e) {
return Math.sqrt(e.x * e.x + e.y * e.y)
}
export default {
name: 'MovableArea'
name: 'MovableArea',
props: {
scaleArea: {
type: Boolean,
default: false
}
},
data () {
return {
width: 0,
height: 0,
items: []
}
},
created: function () {
this.gapV = {
x: null,
y: null
}
this.pinchStartLen = null
},
mounted: function () {
this._getWH()
this.items.forEach(function (item, index) {
item.componentInstance.setParent()
})
},
methods: {
_find (target, items = this.items) {
var root = this.$el
function get (node) {
for (let i = 0; i < items.length; i++) {
const item = items[i]
if (node === item.componentInstance.$el) {
return item
}
}
if (node === root || node === document.body || node === document) {
return null
}
return get(node.parentNode)
}
return get(target)
},
_touchstart (t) {
var i = t.touches
if (i) {
if (i.length > 1) {
var r = {
x: i[1].pageX - i[0].pageX,
y: i[1].pageY - i[0].pageY
}
this.pinchStartLen = calc(r)
this.gapV = r
if (!this.scaleArea) {
var touch0 = this._find(i[0].target)
var touch1 = this._find(i[1].target)
this._scaleMovableView = touch0 && touch0 === touch1 ? touch0 : null
}
}
}
},
_touchmove (t) {
var n = t.touches
if (n) {
if (n.length > 1) {
t.preventDefault()
var i = {
x: n[1].pageX - n[0].pageX,
y: n[1].pageY - n[0].pageY
}
if (this.gapV.x !== null && this.pinchStartLen > 0) {
var r = calc(i) / this.pinchStartLen
this._updateScale(r)
}
this.gapV = i
}
}
},
_touchend (e) {
var t = e.touches
if (!(t && t.length)) {
if (e.changedTouches) {
this.gapV.x = 0
this.gapV.y = 0
this.pinchStartLen = null
if (this.scaleArea) {
this.items.forEach(function (item) {
item.componentInstance._endScale()
})
} else {
if (this._scaleMovableView) {
this._scaleMovableView.componentInstance._endScale()
}
}
}
}
},
_updateScale (e) {
if (e && e !== 1) {
if (this.scaleArea) {
this.items.forEach(function (item) {
item.componentInstance._setScale(e)
})
} else {
if (this._scaleMovableView) {
this._scaleMovableView.componentInstance._setScale(e)
}
}
}
},
_getWH () {
var style = window.getComputedStyle(this.$el)
var rect = this.$el.getBoundingClientRect()
this.width = rect.width - ['Left', 'Right'].reduce(function (all, item) {
return all + parseFloat(style['border' + item + 'Width']) + parseFloat(style['padding' + item])
}, 0)
this.height = rect.height - ['Top', 'Bottom'].reduce(function (all, item) {
return all + parseFloat(style['border' + item + 'Width']) + parseFloat(style['padding' + item])
}, 0)
}
},
render (createElement) {
var items = []
if (this.$slots.default) {
this.$slots.default.forEach(vnode => {
if (vnode.componentOptions && vnode.componentOptions.tag === 'v-uni-movable-view') {
items.push(vnode)
}
})
}
this.items = items
var $listeners = Object.assign({}, this.$listeners)
var events = ['touchstart', 'touchmove', 'touchend']
events.forEach(event => {
var existing = $listeners[event]
var ours = this[`_${event}`]
$listeners[event] = existing ? [].concat(existing, ours) : ours
})
return createElement(
'uni-movable-area',
{
on: $listeners
}, items)
}
}
</script>
<style>
uni-movable-area {
display: block;
position: relative;
width: 10px;
height: 10px;
}
uni-movable-area[hidden] {
display: none;
}
</style>
<template>
<uni-movable-view/>
<uni-movable-view v-on="$listeners">
<slot/>
</uni-movable-view>
</template>
<script>
import touchtrack from 'uni-mixins/touchtrack'
import {
N,
I,
O
} from './utils'
var requesting = false
function _requestAnimationFrame (e) {
if (!requesting) {
requesting = true
requestAnimationFrame(function () {
e()
requesting = false
})
}
}
function p (t, n) {
if (t === n) {
return 0
}
var i = t.offsetLeft
return t.offsetParent ? (i += p(t.offsetParent, n)) : 0
}
function f (t, n) {
if (t === n) {
return 0
}
var i = t.offsetTop
return t.offsetParent ? (i += f(t.offsetParent, n)) : 0
}
function v (a, b) {
return +((1000 * a - 1000 * b) / 1000).toFixed(1)
}
function g (e, t, n) {
var i = function (e) {
if (e && e.id) {
cancelAnimationFrame(e.id)
}
if (e) {
e.cancelled = true
}
}
var r = {
id: 0,
cancelled: false
}
function fn (n, i, r, o) {
if (!n || !n.cancelled) {
r(i)
var a = e.done()
if (!a) {
if (!n.cancelled) {
(n.id = requestAnimationFrame(fn.bind(null, n, i, r, o)))
}
}
if (a && o) {
o(i)
}
}
}
fn(r, e, t, n)
return {
cancel: i.bind(null, r),
model: e
}
}
export default {
name: 'MovableView'
name: 'MovableView',
mixins: [touchtrack],
props: {
direction: {
type: String,
default: 'none'
},
inertia: {
type: [Boolean, String],
default: false
},
outOfBounds: {
type: [Boolean, String],
default: false
},
x: {
type: [Number, String],
default: 0
},
y: {
type: [Number, String],
default: 0
},
damping: {
type: [Number, String],
default: 20
},
friction: {
type: [Number, String],
default: 2
},
disabled: {
type: [Boolean, String],
default: false
},
scale: {
type: [Boolean, String],
default: false
},
scaleMin: {
type: [Number, String],
default: 0.5
},
scaleMax: {
type: [Number, String],
default: 10
},
scaleValue: {
type: [Number, String],
default: 1
}
},
data () {
return {
xSync: this._getPx(this.x),
ySync: this._getPx(this.y),
scaleValueSync: Number(this.scaleValue) || 1,
width: 0,
height: 0,
minX: 0,
minY: 0,
maxX: 0,
maxY: 0
}
},
computed: {
dampingNumber () {
var val = Number(this.damping)
return isNaN(val) ? 20 : val
},
frictionNumber () {
var val = Number(this.friction)
return isNaN(val) || val <= 0 ? 2 : val
},
scaleMinNumber () {
var val = Number(this.scaleMin)
return isNaN(val) ? 0.5 : val
},
scaleMaxNumber () {
var val = Number(this.scaleMax)
return isNaN(val) ? 10 : val
},
xMove () {
return this.direction === 'all' || this.direction === 'horizontal'
},
yMove () {
return this.direction === 'all' || this.direction === 'vertical'
}
},
watch: {
x (val) {
this.xSync = this._getPx(val)
},
xSync (val) {
this._setX(val)
},
y (val) {
this.ySync = this._getPx(val)
},
ySync (val) {
this._setY(val)
},
scaleValue (val) {
this.scaleValueSync = Number(val) || 0
},
scaleValueSync (val) {
this._setScaleValue(val)
},
scaleMinNumber () {
this._setScaleMinOrMax()
},
scaleMaxNumber () {
this._setScaleMinOrMax()
}
},
created: function () {
this._offset = {
x: 0,
y: 0
}
this._scaleOffset = {
x: 0,
y: 0
}
this._translateX = 0
this._translateY = 0
this._scale = 1
this._oldScale = 1
this._STD = new O(1, 9 * Math.pow(this.dampingNumber, 2) / 40, this.dampingNumber)
this._friction = new I(1, this.frictionNumber)
this._declineX = new N()
this._declineY = new N()
this.__touchInfo = {
historyX: [0, 0],
historyY: [0, 0],
historyT: [0, 0]
}
},
mounted: function () {
this.touchtrack(this.$el, '_onTrack')
if (this.$parent._isMounted) {
this.setParent()
}
this._friction.reconfigure(1, this.frictionNumber)
this._STD.reconfigure(1, 9 * Math.pow(this.dampingNumber, 2) / 40, this.dampingNumber)
this.$el.style.transformOrigin = 'center'
},
methods: {
_getPx (val) {
if (/\d+[ur]px$/i.test(val)) {
return uni.upx2px(parseFloat(val))
}
return Number(val) || 0
},
_setX: function (val) {
if (this.xMove) {
if (val + this._scaleOffset.x === this._translateX) {
return this._translateX
} else {
if (this._SFA) {
this._SFA.cancel()
}
this._animationTo(val + this._scaleOffset.x, this.ySync + this._scaleOffset.y, this._scale)
}
}
return val
},
_setY: function (val) {
if (this.yMove) {
if (val + this._scaleOffset.y === this._translateY) {
return this._translateY
} else {
if (this._SFA) {
this._SFA.cancel()
}
this._animationTo(this.xSync + this._scaleOffset.x, val + this._scaleOffset.y, this._scale)
}
}
return val
},
_setScaleMinOrMax: function () {
if (!this.scale) {
return false
}
this._updateScale(this._scale, true)
this._updateOldScale(this._scale)
},
_setScaleValue: function (scale) {
if (!this.scale) {
return false
}
scale = this._adjustScale(scale)
this._updateScale(scale, true)
this._updateOldScale(scale)
return scale
},
__handleTouchStart: function () {
if (!this._isScaling) {
if (!this.disabled) {
if (this._FA) {
this._FA.cancel()
}
if (this._SFA) {
this._SFA.cancel()
}
this.__touchInfo.historyX = [0, 0]
this.__touchInfo.historyY = [0, 0]
this.__touchInfo.historyT = [0, 0]
if (this.xMove) {
this.__baseX = this._translateX
}
if (this.yMove) {
this.__baseY = this._translateY
}
this.$el.style.willChange = 'transform'
this._checkCanMove = null
this._firstMoveDirection = null
this._isTouching = true
}
}
},
__handleTouchMove: function (event) {
var self = this
if (!this._isScaling && !this.disabled && this._isTouching) {
let x = this._translateX
let y = this._translateY
if (this._firstMoveDirection === null) {
this._firstMoveDirection = Math.abs(event.detail.dx / event.detail.dy) > 1 ? 'htouchmove' : 'vtouchmove'
}
if (this.xMove) {
x = event.detail.dx + this.__baseX
this.__touchInfo.historyX.shift()
this.__touchInfo.historyX.push(x)
if (!this.yMove) {
if (!null !== this._checkCanMove) {
if (Math.abs(event.detail.dx / event.detail.dy) > 1) {
this._checkCanMove = false
} else {
this._checkCanMove = true
}
}
}
}
if (this.yMove) {
y = event.detail.dy + this.__baseY
this.__touchInfo.historyY.shift()
this.__touchInfo.historyY.push(y)
if (!this.xMove) {
if (!null !== this._checkCanMove) {
if (Math.abs(event.detail.dy / event.detail.dx) > 1) {
this._checkCanMove = false
} else {
this._checkCanMove = true
}
}
}
}
this.__touchInfo.historyT.shift()
this.__touchInfo.historyT.push(event.detail.timeStamp)
if (!this._checkCanMove) {
event.preventDefault()
let source = 'touch'
if (x < this.minX) {
if (this.outOfBounds) {
source = 'touch-out-of-bounds'
x = this.minX - this._declineX.x(this.minX - x)
} else {
x = this.minX
}
} else if (x > this.maxX) {
if (this.outOfBounds) {
source = 'touch-out-of-bounds'
x = this.maxX + this._declineX.x(x - this.maxX)
} else {
x = this.maxX
}
}
if (y < this.minY) {
if (this.outOfBounds) {
source = 'touch-out-of-bounds'
y = this.minY - this._declineY.x(this.minY - y)
} else {
y = this.minY
}
} else {
if (y > this.maxY) {
if (this.outOfBounds) {
source = 'touch-out-of-bounds'
y = this.maxY + this._declineY.x(y - this.maxY)
} else {
y = this.maxY
}
}
}
_requestAnimationFrame(function () {
self._setTransform(x, y, self._scale, source)
})
}
}
},
__handleTouchEnd: function () {
var self = this
if (!this._isScaling && !this.disabled && this._isTouching) {
this.$el.style.willChange = 'auto'
this._isTouching = false
if (!this._checkCanMove && !this._revise('out-of-bounds') && this.inertia) {
let xv = 1000 * (this.__touchInfo.historyX[1] - this.__touchInfo.historyX[0]) / (this.__touchInfo.historyT[1] - this.__touchInfo.historyT[0])
let yv = 1000 * (this.__touchInfo.historyY[1] - this.__touchInfo.historyY[0]) / (this.__touchInfo.historyT[1] - this.__touchInfo.historyT[0])
this._friction.setV(xv, yv)
this._friction.setS(this._translateX, this._translateY)
let x0 = this._friction.delta().x
let y0 = this._friction.delta().y
let x = x0 + this._translateX
let y = y0 + this._translateY
if (x < this.minX) {
x = this.minX
y = this._translateY + (this.minX - this._translateX) * y0 / x0
} else {
if (x > this.maxX) {
x = this.maxX
y = this._translateY + (this.maxX - this._translateX) * y0 / x0
}
}
if (y < this.minY) {
y = this.minY
x = this._translateX + (this.minY - this._translateY) * x0 / y0
} else {
if (y > this.maxY) {
y = this.maxY
x = this._translateX + (this.maxY - this._translateY) * x0 / y0
}
}
this._friction.setEnd(x, y)
this._FA = g(this._friction, function () {
var t = self._friction.s()
var x = t.x
var y = t.y
self._setTransform(x, y, self._scale, 'friction')
}, function () {
self._FA.cancel()
})
}
}
},
_onTrack: function (event) {
switch (event.detail.state) {
case 'start':
this.__handleTouchStart()
break
case 'move':
this.__handleTouchMove(event)
break
case 'end':
this.__handleTouchEnd()
}
},
_getLimitXY: function (x, y) {
var outOfBounds = false
if (x > this.maxX) {
x = this.maxX
outOfBounds = true
} else {
if (x < this.minX) {
x = this.minX
outOfBounds = true
}
}
if (y > this.maxY) {
y = this.maxY
outOfBounds = true
} else {
if (y < this.minY) {
y = this.minY
outOfBounds = true
}
}
return {
x,
y,
outOfBounds
}
},
setParent: function () {
if (this._FA) {
this._FA.cancel()
}
if (this._SFA) {
this._SFA.cancel()
}
var scale = this.scale ? this.scaleValueSync : 1
this._updateOffset()
this._updateWH(scale)
this._updateBoundary()
this._translateX = this.xSync + this._scaleOffset.x
this._translateY = this.ySync + this._scaleOffset.y
var limitXY = this._getLimitXY(this._translateX, this._translateY)
var x = limitXY.x
var y = limitXY.y
this._setTransform(x, y, scale, '', true)
this._updateOldScale(scale)
},
_updateOffset: function () {
this._offset.x = p(this.$el, this.$parent.$el)
this._offset.y = f(this.$el, this.$parent.$el)
},
_updateWH: function (scale) {
scale = scale || this._scale
scale = this._adjustScale(scale)
var rect = this.$el.getBoundingClientRect()
this.height = rect.height / this._scale
this.width = rect.width / this._scale
var height = this.height * scale
var width = this.width * scale
this._scaleOffset.x = (width - this.width) / 2
this._scaleOffset.y = (height - this.height) / 2
},
_updateBoundary: function () {
var x = 0 - this._offset.x + this._scaleOffset.x
var width = this.$parent.width - this.width - this._offset.x - this._scaleOffset.x
this.minX = Math.min(x, width)
this.maxX = Math.max(x, width)
var y = 0 - this._offset.y + this._scaleOffset.y
var height = this.$parent.height - this.height - this._offset.y - this._scaleOffset.y
this.minY = Math.min(y, height)
this.maxY = Math.max(y, height)
},
_beginScale: function () {
this._isScaling = true
},
_endScale: function () {
this._isScaling = false
this._updateOldScale(this._scale)
},
_setScale: function (scale) {
if (this.scale) {
scale = this._adjustScale(scale)
scale = this._oldScale * scale
this._beginScale()
this._updateScale(scale)
}
},
_updateScale: function (scale, animat) {
var self = this
if (this.scale) {
scale = this._adjustScale(scale)
this._updateWH(scale)
this._updateBoundary()
let limitXY = this._getLimitXY(this._translateX, this._translateY)
let x = limitXY.x
let y = limitXY.y
if (animat) {
this._animationTo(x, y, scale, '', true, true)
} else {
_requestAnimationFrame(function () {
self._setTransform(x, y, scale, '', true, true)
})
}
}
},
_updateOldScale: function (scale) {
this._oldScale = scale
},
_adjustScale: function (scale) {
scale = Math.max(0.5, this.scaleMinNumber, scale)
scale = Math.min(10, this.scaleMaxNumber, scale)
return scale
},
_animationTo: function (x, y, scale, source, r, o) {
var self = this
if (this._FA) {
this._FA.cancel()
}
if (this._SFA) {
this._SFA.cancel()
}
if (!this.xMove) {
x = this._translateX
}
if (!this.yMove) {
y = this._translateY
}
if (!this.scale) {
scale = this._scale
}
var limitXY = this._getLimitXY(x, y)
x = limitXY.x
y = limitXY.y
this._STD._springX._solution = null
this._STD._springY._solution = null
this._STD._springScale._solution = null
this._STD._springX._endPosition = this._translateX
this._STD._springY._endPosition = this._translateY
this._STD._springScale._endPosition = this._scale
this._STD.setEnd(x, y, scale, 1)
this._SFA = g(this._STD, function () {
var data = self._STD.x()
var x = data.x
var y = data.y
var scale = data.scale
self._setTransform(x, y, scale, source, r, o)
}, function () {
self._SFA.cancel()
})
},
_revise: function (source) {
var limitXY = this._getLimitXY(this._translateX, this._translateY)
var x = limitXY.x
var y = limitXY.y
var outOfBounds = limitXY.outOfBounds
if (outOfBounds) {
this._animationTo(x, y, this._scale, source)
}
return outOfBounds
},
_setTransform: function (x, y, scale, source = '', r, o) {
if (!(x !== null && x.toString() !== 'NaN' && typeof x === 'number')) {
x = this._translateX || 0
}
if (!(y !== null && y.toString() !== 'NaN' && typeof y === 'number')) {
y = this._translateY || 0
}
x = Number(x.toFixed(1))
y = Number(y.toFixed(1))
scale = Number(scale.toFixed(1))
if (!(this._translateX === x && this._translateY === y)) {
if (!r) {
this.$trigger('change', {}, {
x: v(x, this._scaleOffset.x),
y: v(y, this._scaleOffset.y),
source: source
})
}
}
if (!this.scale) {
scale = this._scale
}
scale = this._adjustScale(scale)
scale = +scale.toFixed(3)
if (o && scale !== this._scale) {
this.$trigger('scale', {}, {
scale: scale
})
}
var transform = 'translateX(' + x + 'px) translateY(' + y + 'px) translateZ(0px) scale(' + scale + ')'
this.$el.style.transform = transform
this.$el.style.webkitTransform = transform
this._translateX = x
this._translateY = y
this._scale = scale
}
}
}
</script>
<style>
uni-movable-view {
display: inline-block;
width: 10px;
height: 10px;
top: 0px;
left: 0px;
position: absolute;
}
uni-movable-view[hidden] {
display: none;
}
</style>
function e (e, t, n) {
return e > t - n && e < t + n
}
function t (t, n) {
return e(t, 0, n)
}
export function N () { }
N.prototype.x = function (e) {
return Math.sqrt(e)
}
export function I (e, t) {
this._m = e
this._f = 1e3 * t
this._startTime = 0
this._v = 0
}
I.prototype.setV = function (x, y) {
var n = Math.pow(Math.pow(x, 2) + Math.pow(y, 2), 0.5)
this._x_v = x
this._y_v = y
this._x_a = -this._f * this._x_v / n
this._y_a = -this._f * this._y_v / n
this._t = Math.abs(x / this._x_a) || Math.abs(y / this._y_a)
this._lastDt = null
this._startTime = (new Date()).getTime()
}
I.prototype.setS = function (x, y) {
this._x_s = x
this._y_s = y
}
I.prototype.s = function (t) {
if (undefined === t) {
t = ((new Date()).getTime() - this._startTime) / 1e3
}
if (t > this._t) {
t = this._t
this._lastDt = t
}
var x = this._x_v * t + 0.5 * this._x_a * Math.pow(t, 2) + this._x_s
var y = this._y_v * t + 0.5 * this._y_a * Math.pow(t, 2) + this._y_s
if ((this._x_a > 0 && x < this._endPositionX) || (this._x_a < 0 && x > this._endPositionX)) {
x = this._endPositionX
}
if ((this._y_a > 0 && y < this._endPositionY) || (this._y_a < 0 && y > this._endPositionY)) {
y = this._endPositionY
}
return {
x,
y
}
}
I.prototype.ds = function (t) {
if (undefined === t) {
t = ((new Date()).getTime() - this._startTime) / 1e3
}
if (t > this._t) {
t = this._t
}
return {
dx: this._x_v + this._x_a * t,
dy: this._y_v + this._y_a * t
}
}
I.prototype.delta = function () {
return {
x: -1.5 * Math.pow(this._x_v, 2) / this._x_a || 0,
y: -1.5 * Math.pow(this._y_v, 2) / this._y_a || 0
}
}
I.prototype.dt = function () {
return -this._x_v / this._x_a
}
I.prototype.done = function () {
var t = e(this.s().x, this._endPositionX) || e(this.s().y, this._endPositionY) || this._lastDt === this._t
this._lastDt = null
return t
}
I.prototype.setEnd = function (x, y) {
this._endPositionX = x
this._endPositionY = y
}
I.prototype.reconfigure = function (m, f) {
this._m = m
this._f = 1e3 * f
}
export function R (m, k, c) {
this._m = m
this._k = k
this._c = c
this._solution = null
this._endPosition = 0
this._startTime = 0
}
R.prototype._solve = function (e, t) {
var n = this._c
var i = this._m
var r = this._k
var o = n * n - 4 * i * r
if (o === 0) {
let a = -n / (2 * i)
let s = e
let l = t / (a * e)
return {
x: function (e) {
return (s + l * e) * Math.pow(Math.E, a * e)
},
dx: function (e) {
var t = Math.pow(Math.E, a * e)
return a * (s + l * e) * t + l * t
}
}
}
if (o > 0) {
let c = (-n - Math.sqrt(o)) / (2 * i)
let u = (-n + Math.sqrt(o)) / (2 * i)
let d = (t - c * e) / (u - c)
let h = e - d
return {
x: function (e) {
var t
var n
if (e === this._t) {
t = this._powER1T
n = this._powER2T
}
this._t = e
if (!t) {
t = this._powER1T = Math.pow(Math.E, c * e)
}
if (!n) {
n = this._powER2T = Math.pow(Math.E, u * e)
}
return h * t + d * n
},
dx: function (e) {
var t
var n
if (e === this._t) {
t = this._powER1T
n = this._powER2T
}
this._t = e
if (!t) {
t = this._powER1T = Math.pow(Math.E, c * e)
}
if (!n) {
n = this._powER2T = Math.pow(Math.E, u * e)
}
return h * c * t + d * u * n
}
}
}
var p = Math.sqrt(4 * i * r - n * n) / (2 * i)
var f = -n / 2 * i
var v = e
var g = (t - f * e) / p
return {
x: function (e) {
return Math.pow(Math.E, f * e) * (v * Math.cos(p * e) + g * Math.sin(p * e))
},
dx: function (e) {
var t = Math.pow(Math.E, f * e)
var n = Math.cos(p * e)
var i = Math.sin(p * e)
return t * (g * p * n - v * p * i) + f * t * (g * i + v * n)
}
}
}
R.prototype.x = function (e) {
if (undefined === e) {
e = ((new Date()).getTime() - this._startTime) / 1e3
}
return this._solution ? this._endPosition + this._solution.x(e) : 0
}
R.prototype.dx = function (e) {
if (undefined === e) {
e = ((new Date()).getTime() - this._startTime) / 1e3
}
return this._solution ? this._solution.dx(e) : 0
}
R.prototype.setEnd = function (e, n, i) {
if (!i) {
i = (new Date()).getTime()
}
if (e !== this._endPosition || !t(n, 0.1)) {
n = n || 0
var r = this._endPosition
if (this._solution) {
if (t(n, 0.1)) {
n = this._solution.dx((i - this._startTime) / 1e3)
}
r = this._solution.x((i - this._startTime) / 1e3)
if (t(n, 0.1)) {
n = 0
}
if (t(r, 0.1)) {
r = 0
}
r += this._endPosition
}
if (!(this._solution && t(r - e, 0.1) && t(n, 0.1))) {
this._endPosition = e
this._solution = this._solve(r - this._endPosition, n)
this._startTime = i
}
}
}
R.prototype.snap = function (e) {
this._startTime = (new Date()).getTime()
this._endPosition = e
this._solution = {
x: function () {
return 0
},
dx: function () {
return 0
}
}
}
R.prototype.done = function (n) {
if (!n) {
n = (new Date()).getTime()
}
return e(this.x(), this._endPosition, 0.1) && t(this.dx(), 0.1)
}
R.prototype.reconfigure = function (m, t, c) {
this._m = m
this._k = t
this._c = c
if (!this.done()) {
this._solution = this._solve(this.x() - this._endPosition, this.dx())
this._startTime = (new Date()).getTime()
}
}
R.prototype.springConstant = function () {
return this._k
}
R.prototype.damping = function () {
return this._c
}
R.prototype.configuration = function () {
function e (e, t) {
e.reconfigure(1, t, e.damping())
}
function t (e, t) {
e.reconfigure(1, e.springConstant(), t)
}
return [{
label: 'Spring Constant',
read: this.springConstant.bind(this),
write: e.bind(this, this),
min: 100,
max: 1e3
}, {
label: 'Damping',
read: this.damping.bind(this),
write: t.bind(this, this),
min: 1,
max: 500
}]
}
export function O (e, t, n) {
this._springX = new R(e, t, n)
this._springY = new R(e, t, n)
this._springScale = new R(e, t, n)
this._startTime = 0
}
O.prototype.setEnd = function (e, t, n, i) {
var r = (new Date()).getTime()
this._springX.setEnd(e, i, r)
this._springY.setEnd(t, i, r)
this._springScale.setEnd(n, i, r)
this._startTime = r
}
O.prototype.x = function () {
var e = ((new Date()).getTime() - this._startTime) / 1e3
return {
x: this._springX.x(e),
y: this._springY.x(e),
scale: this._springScale.x(e)
}
}
O.prototype.done = function () {
var e = (new Date()).getTime()
return this._springX.done(e) && this._springY.done(e) && this._springScale.done(e)
}
O.prototype.reconfigure = function (e, t, n) {
this._springX.reconfigure(e, t, n)
this._springY.reconfigure(e, t, n)
this._springScale.reconfigure(e, t, n)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册