UNPKG

dragonbones-runtime

Version:

the tools to build dragonbones file for diffrent framework

529 lines (498 loc) 20.5 kB
////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2014-present, Egret Technology. // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of the Egret nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ////////////////////////////////////////////////////////////////////////////////////// namespace eui.sys { /** * @private */ export const enum RangeKeys{ maximum, maxChanged, minimum, minChanged, value, changedValue, valueChanged, snapInterval, snapIntervalChanged, explicitSnapInterval } } namespace eui { /** * The Range class holds a value and an allowed range for that * value, defined by <code>minimum</code> and <code>maximum</code> properties. * * The <code>value</code> property * is always constrained to be between the current <code>minimum</code> and * <code>maximum</code>, and the <code>minimum</code>, * and <code>maximum</code> are always constrained * to be in the proper numerical order, such that * <code>(minimum <= value <= maximum)</code> is <code>true</code>. * * If the value of the <code>snapInterval</code> property is not 0, * then the <code>value</code> property is also constrained to be a multiple of * <code>snapInterval</code>. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @includeExample extension/eui/components/supportClasses/RangeExample.ts * @language en_US */ /** * 范围选取组件,该组件包含一个值和这个值所允许的最大最小约束范围。 * * <code>value</code>属性的值永远被限制于当前的<code>minimum</code>和 * <code>maximum</code>之间,并且<code>minimum</code>和 <code>maximum</code>永远按照固定的顺序排列, * 即<code>(minimum <= value <= maximum)</code> 为真。 * * 如果<code>snapInterval</code>属性的值不是0,那么<code>value</code>的值也会被<code>snapInterval</code>所约束。 * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @includeExample extension/eui/components/supportClasses/RangeExample.ts * @language zh_CN */ export class Range extends Component { /** * Constructor. * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 创建一个 Range 实例。 * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public constructor() { super(); this.$Range = { 0: 100, //maximum 1: false, //maxChanged 2: 0, //minimum 3: false, //minChanged 4: 0, //value 5: 0, //changedValue 6: false, //valueChanged 7: 1, //snapInterval 8: false, //snapIntervalChanged 9: false, //explicitSnapInterval }; } /** * @private */ $Range:Object; /** * The maximum valid <code>value</code>.<p/> * * Changes to the value property are constrained * by <code>commitProperties()</code> to be less than or equal to * maximum with the <code>nearestValidValue()</code> method. * * @default 100 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 最大有效值。<p/> * * 规定<code>value</code>属性的值不能够超过的最大值。该修正过程 * 将在<code>nearestValidValue()</code>方法中进行。 * * @default 100 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get maximum():number { return this.$Range[sys.RangeKeys.maximum]; } public set maximum(value:number) { value = +value || 0; let values = this.$Range; if (value === values[sys.RangeKeys.maximum]) return; values[sys.RangeKeys.maximum] = value; values[sys.RangeKeys.maxChanged] = true; this.invalidateProperties(); this.invalidateDisplayList(); } /** * The minimum valid <code>value</code>.<p/> * * Changes to the value property are constrained * by <code>commitProperties()</code> to be greater than or equal to * minimum with the <code>nearestValidValue()</code> method. * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 最小有效值<p/> * * 规定<code>value</code>属性的值不能够低于的最小值。该修正过程 * 将在<code>nearestValidValue()</code>方法中进行。 * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get minimum():number { return this.$Range[sys.RangeKeys.minimum]; } public set minimum(value:number) { value = +value || 0; let values = this.$Range; if (value === values[sys.RangeKeys.minimum]) return; values[sys.RangeKeys.minimum] = value; values[sys.RangeKeys.minChanged] = true; this.invalidateProperties(); this.invalidateDisplayList(); } /** * The current value for this range.<p/> * * Changes to the value property are constrained * by <code>commitProperties()</code> to be greater than or equal to * the <code>minimum</code> property, less than or equal to the <code>maximum</code> property, and a * multiple of <code>snapInterval</code> with the <code>nearestValidValue()</code> * method. * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 此范围的当前值。<p/> * * 改变的<code>value</code>属性将在<code>commitProperties()</code>方法中被<code>minimum</code>属性 * 和<code>minimum</code>属性所限制。此修正过程将在<code>nearestValidValue()</code>方法中进行。 * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get value():number { let values = this.$Range; return values[sys.RangeKeys.valueChanged] ? values[sys.RangeKeys.changedValue] : values[sys.RangeKeys.value]; } public set value(newValue:number) { newValue = +newValue || 0; this.$setValue(newValue); } /** * @private * * @param newValue */ $setValue(newValue:number):boolean { if (newValue === this.value) return false; let values = this.$Range; values[sys.RangeKeys.changedValue] = newValue; values[sys.RangeKeys.valueChanged] = true; this.invalidateProperties(); return true; } /** * The snapInterval property controls the valid values of the <code>value</code> property. * * If nonzero, valid values are the sum of the <code>minimum</code> and integer multiples * of this property, for all sums that are less than or equal to the <code>maximum</code>.<p/> * * For example, if <code>minimum</code> is 10, <code>maximum</code> is 20, and this property is 3, then the * valid values of this Range are 10, 13, 16, 19, and 20.<p/> * * If the value of this property is zero, then valid values are only constrained * to be between minimum and maximum inclusive. * * @default 1 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * snapInterval 属性定义 value 属性的有效值。 * 如果为非零,则有效值为 minimum 与此属性的整数倍数之和,且小于或等于 maximum。</p> * * 例如,如果 minimum 为 10,maximum 为 20,而此属性为 3,则可能的有效值为 10、13、16、19 和 20.</p> * * 如果此属性的值为零,则仅会将有效值约束到介于 minimum 和 maximum 之间(包括两者)。 * * @default 1 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get snapInterval():number { return this.$Range[sys.RangeKeys.snapInterval]; } public set snapInterval(value:number) { let values = this.$Range; values[sys.RangeKeys.explicitSnapInterval] = true; value = +value || 0; if (value === values[sys.RangeKeys.snapInterval]) return; if (isNaN(value)) { values[sys.RangeKeys.snapInterval] = 1; values[sys.RangeKeys.explicitSnapInterval] = false; } else { values[sys.RangeKeys.snapInterval] = value; } values[sys.RangeKeys.snapIntervalChanged] = true; this.invalidateProperties(); } /** * Processes the properties set on the component. * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 处理对组件设置的属性 * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected commitProperties():void { super.commitProperties(); let values = this.$Range; if (values[sys.RangeKeys.minimum] > values[sys.RangeKeys.maximum]) { if (!values[sys.RangeKeys.maxChanged]) values[sys.RangeKeys.minimum] = values[sys.RangeKeys.maximum]; else values[sys.RangeKeys.maximum] = values[sys.RangeKeys.minimum]; } if (values[sys.RangeKeys.valueChanged] || values[sys.RangeKeys.maxChanged] || values[sys.RangeKeys.minChanged] || values[sys.RangeKeys.snapIntervalChanged]) { let currentValue = values[sys.RangeKeys.valueChanged] ? values[sys.RangeKeys.changedValue] : values[sys.RangeKeys.value]; values[sys.RangeKeys.valueChanged] = false; values[sys.RangeKeys.maxChanged] = false; values[sys.RangeKeys.minChanged] = false; values[sys.RangeKeys.snapIntervalChanged] = false; this.setValue(this.nearestValidValue(currentValue, values[sys.RangeKeys.snapInterval])); } } /** * @private * 修正size到最接近snapInterval的整数倍 */ private nearestValidSize(size:number):number { let interval:number = this.snapInterval; if (interval == 0) return size; let validSize:number = Math.round(size / interval) * interval; return (Math.abs(validSize) < interval) ? interval : validSize; } /** * Returns the sum of the minimum with an integer multiple of <code>interval</code> that's * closest to <code>value</code>, unless <code>value</code> is closer to the maximum limit, * in which case the maximum is returned.<p/> * * If <code>interval</code> is equal to 0, the value is clipped to the minimum and maximum * limits.<p/> * * The valid values for a range are defined by the sum of the <code>minimum</code> property * with multiples of the <code>interval</code> and also defined to be less than or equal to the * <code>maximum</code> property. * The maximum need not be a multiple of <code>snapInterval</code>.<p/> * * For example, if <code>minimum</code> is equal to 1, <code>maximum</code> is equal to 6, * and <code>snapInterval</code> is equal to 2, the valid * values for the Range are 1, 3, 5, 6. * * Similarly, if <code>minimum</code> is equal to 2, <code>maximum</code> is equal to 9, * and <code>snapInterval</code> is equal to 1.5, the valid * values for the Range are 2, 3.5, 5, 6.5, 8, and 9. * * @param value The input value. * @param interval The value of snapInterval or an integer multiple of snapInterval. * @return The valid value that's closest to the input. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 返回 <code>minimum</code> 与最接近 <code>value</code> 的 <code>interval</code> 的整数倍数之和, * 除非 <code>value</code> 接近最大值限制的时候会返回 maximum。<p/> * * 如果 <code>interval</code> 等于 0,则会将该值剪裁到限制的最小值和最大值。<p/> * * 范围的有效值由 <code>minimum</code> 属性与 <code>interval</code> 的倍数之和决定, * 与此同时也要小于等于 <code>maximum</code> 属性。 * 最大值不能是 <code>snapInterval</code> 属性的倍数。<p/> * * 例如,如果 <code>minimum</code> 等于 1,<code>maximum</code> 等于 6,且 <code>snapInterval</code> 等于 3, * 则 Range 的有效值有 1、2、5、6。 * * 类似地,如果 <code>minimum</code> 等于 2,<code>maximum</code> 等于 9, * 且 <code>snapInterval</code> 等于 1.5,则 Range 的有效值有 2、3.5、5、6.5、8 和 9。 * * * @param value 输入值。 * @param interval snapInterval 的值,或 snapInterval 的整数倍数。 * @return 最近接输入值的有效值。 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected nearestValidValue(value:number, interval:number):number { let values = this.$Range; if (interval == 0) return Math.max(values[sys.RangeKeys.minimum], Math.min(values[sys.RangeKeys.maximum], value)); let maxValue = values[sys.RangeKeys.maximum] - values[sys.RangeKeys.minimum]; let scale = 1; value -= values[sys.RangeKeys.minimum]; if (interval != Math.round(interval)) { let parts = ((1 + interval).toString()).split("."); scale = Math.pow(10, parts[1].length); maxValue *= scale; value = Math.round(value * scale); interval = Math.round(interval * scale); } let lower = Math.max(0, Math.floor(value / interval) * interval); let upper = Math.min(maxValue, Math.floor((value + interval) / interval) * interval); let validValue = ((value - lower) >= ((upper - lower) / 2)) ? upper : lower; return (validValue / scale) + values[sys.RangeKeys.minimum]; } /** * Sets the current value for the <code>value</code> property.<p/> * * This method assumes that the caller has already used the <code>nearestValidValue()</code> method * to constrain the value parameter * * @param value The new value of the <code>value</code> property. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 设置当前值。<p/> * * 此方法假定调用者已经使用了 nearestValidValue() 方法来约束 value 参数。 * * @param value value属性的新值 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected setValue(value:number):void { let values = this.$Range; if (values[sys.RangeKeys.value] === value) return; if (values[sys.RangeKeys.maximum] > values[sys.RangeKeys.minimum]) values[sys.RangeKeys.value] = Math.min(values[sys.RangeKeys.maximum], Math.max(values[sys.RangeKeys.minimum], value)); else values[sys.RangeKeys.value] = value; values[sys.RangeKeys.valueChanged] = false; this.invalidateDisplayList(); PropertyEvent.dispatchPropertyEvent(this,PropertyEvent.PROPERTY_CHANGE,"value"); } /** * Draws the object and/or sizes and positions its children. * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 绘制对象和/或设置其子项的大小和位置 * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected updateDisplayList(w:number, h:number):void { super.updateDisplayList(w, h); this.updateSkinDisplayList(); } /** * Update size and visible of skin parts.<p/> * Subclasses override this method to update skin parts display based on <code>minimum</code>, <code>maximum</code> * and <code>value</code> properties. * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 更新皮肤部件(通常为滑块)的大小和可见性。<p/> * 子类覆盖此方法以基于 minimum、maximum 和 value 属性更新滑块的大小、位置和可见性。 * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected updateSkinDisplayList():void { } } registerBindable(Range.prototype,"value"); }