1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
\r
2 //>>description: Tizen motion path component for gallery3d
\r
3 //>>label: Motion path
\r
4 //>>group: Tizen:Widgets:Components
\r
6 define( [ ], function ( ) {
\r
7 //>>excludeEnd("jqmBuildExclude");
\r
9 /* ***************************************************************************
\r
10 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
\r
12 * Permission is hereby granted, free of charge, to any person obtaining a
\r
13 * copy of this software and associated documentation files (the "Software"),
\r
14 * to deal in the Software without restriction, including without limitation
\r
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
\r
16 * and/or sell copies of the Software, and to permit persons to whom the
\r
17 * Software is furnished to do so, subject to the following conditions:
\r
19 * The above copyright notice and this permission notice shall be included in
\r
20 * all copies or substantial portions of the Software.
\r
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
\r
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
\r
28 * DEALINGS IN THE SOFTWARE.
\r
29 * ***************************************************************************
\r
31 * Authors: Hyunsook Park <hyunsook.park@samsung.com>
\r
32 * Wonseop Kim <wonseop.kim@samsung.com>
\r
35 ( function ( $, window, undefined ) {
\r
36 var HALF_PI = Math.PI / 2,
\r
37 DEFAULT_STEP = 0.001,
\r
40 arcLength2d = function ( p0, p1 ) {
\r
41 var d = [ p1[0] - p0[0], p1[1] - p0[1] ],
\r
42 value = Math.sqrt( d[0] * d[0] + d[1] * d[1] );
\r
45 arcLength3d = function ( p0, p1 ) {
\r
46 var d = [ p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2] ],
\r
47 value = Math.sqrt( d[0] * d[0] + d[1] * d[1] + d[2] * d[2] );
\r
51 MotionPath.base = function () {};
\r
52 MotionPath.base.prototype = {
\r
57 init: function ( data ) {},
\r
58 calculateLevel: function ( maxLevel ) {},
\r
59 calculateTotalLength: function () {},
\r
60 getPosition: function ( percent ) {},
\r
61 getPercent: function ( start, interval ) {},
\r
62 getAngle: function ( percent ) {}
\r
65 MotionPath.bezier2d = function () {};
\r
66 MotionPath.bezier2d.prototype = $.extend( true, {}, MotionPath.base.prototype, {
\r
67 init: function ( data ) {
\r
68 this.points = data.points;
\r
69 this.step = data.step || DEFAULT_STEP;
\r
70 this.length = this.calculateTotalLength();
\r
71 this.levels = this.calculateLevel( data.maxLevel ) || [];
\r
74 calculateLevel: function ( maxLevel ) {
\r
75 var totalLength = this.length,
\r
76 interval = totalLength / maxLevel,
\r
84 for ( i = 0; i < maxLevel; i += 1 ) {
\r
85 levels[maxLevel - i] = this.getPercent( 0, interval * i );
\r
91 calculateTotalLength: function () {
\r
92 var step = this.step,
\r
93 current = this.getPosition( 0 ),
\r
97 for ( percent = step; percent <= 1; percent += step ) {
\r
98 current = this.getPosition( percent );
\r
99 length += arcLength2d( last, current );
\r
105 getPosition: function ( percent ) {
\r
106 var points = this.points,
\r
107 getValue = function ( p1, c1, c2, p2, t ) {
\r
108 return Math.pow(1 - t, 3) * p1 +
\r
109 3 * t * Math.pow( 1 - t, 2 ) * c1 +
\r
110 3 * Math.pow( t, 2 ) * ( 1 - t ) * c2 +
\r
111 Math.pow( t, 3 ) * p2;
\r
114 getValue( points[0][0], points[1][0], points[2][0], points[3][0], percent ),
\r
115 getValue( points[0][1], points[1][1], points[2][1], points[3][1], percent )
\r
120 getPercent: function ( start, interval ) {
\r
121 var step = this.step,
\r
122 current = this.getPosition( start = start || 0 ),
\r
124 targetLength = start + interval,
\r
128 for ( percent = start + step; percent <= 1; percent += step ) {
\r
129 current = this.getPosition( percent );
\r
130 length += arcLength2d( last, current );
\r
131 if ( length >= targetLength ) {
\r
139 getAngle: function ( percent ) {
\r
140 var points = this.points,
\r
141 getTangent = function ( p1, c1, c2, p2, t ) {
\r
142 return 3 * t * t * ( -p1 + 3 * c1 - 3 * c2 + p2 ) + 6 * t * ( p1 - 2 * c1 + c2 ) + 3 * ( -p1 + c1 );
\r
144 tx = getTangent( points[0][0], points[1][0], points[2][0], points[3][0], percent ),
\r
145 ty = getTangent( points[0][1], points[1][1], points[2][1], points[3][1], percent );
\r
146 return Math.atan2( tx, ty ) - HALF_PI;
\r
151 // clamped cubic B-spline curve
\r
152 // http://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/node17.html
\r
153 // http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve-coef.html
\r
154 MotionPath.bspline = function () {};
\r
155 MotionPath.bspline.prototype = $.extend( true, {}, MotionPath.base.prototype, {
\r
157 _numberOfControls : 0,
\r
161 init: function ( data ) {
\r
162 this.points = data.points;
\r
163 this.step = data.step || DEFAULT_STEP;
\r
164 this._numberOfPoints = this.points.length - 1;
\r
165 this._numberOfKnots = this._numberOfPoints + this._degree + 1;
\r
167 var deltaKnot = 1 / ( this._numberOfKnots - ( 2 * this._degree ) ),
\r
171 while ( i <= this._numberOfKnots ) {
\r
172 if ( i <= this._degree ) {
\r
173 this._knotVectors.push( 0 );
\r
174 } else if ( i < this._numberOfKnots - this._degree + 1 ) {
\r
175 this._knotVectors.push( v );
\r
178 this._knotVectors.push( 1 );
\r
183 this.length = this.calculateTotalLength();
\r
184 this.levels = this.calculateLevel( data.maxLevel ) || [];
\r
187 _Np: function ( percent, i, degree ) {
\r
188 var knots = this._knotVectors,
\r
192 N0 = function ( percent, i ) {
\r
193 return ( ( knots[i] <= percent && percent < knots[i + 1] ) ? 1 : 0 );
\r
196 if ( degree === 1 ) {
\r
197 A = N0( percent, i );
\r
198 B = N0( percent, i + 1 );
\r
200 A = this._Np( percent, i, degree - 1 );
\r
201 B = this._Np( percent, i + 1, degree - 1 );
\r
204 denominator = knots[i + degree] - knots[i];
\r
205 A *= ( denominator !== 0 ) ? ( ( percent - knots[i] ) / denominator ) : 0;
\r
206 denominator = knots[i + degree + 1] - knots[i + 1];
\r
207 B *= ( denominator !== 0 ) ? ( ( knots[i + degree + 1] - percent ) / denominator ) : 0;
\r
212 calculateLevel: function ( maxLevel ) {
\r
213 var totalLength = this.length,
\r
214 interval = totalLength / maxLevel,
\r
222 for ( i = 0; i < maxLevel; i += 1 ) {
\r
223 levels[maxLevel - i] = this.getPercent( 0, interval * i );
\r
228 calculateTotalLength: function () {
\r
229 var step = this.step,
\r
230 current = this.getPosition( 0 ),
\r
234 for ( percent = step; percent <= 1; percent += step ) {
\r
235 current = this.getPosition( percent );
\r
236 length += arcLength3d( last, current );
\r
242 getPosition: function ( percent ) {
\r
243 var result = [], i, j, sum;
\r
244 percent = percent.toFixed( 4 );
\r
245 for ( j = 0; j < 3; j += 1 ) {
\r
247 for ( i = 0; i <= this._numberOfPoints; i += 1 ) {
\r
248 sum += this.points[i][j] * this._Np( percent, i, this._degree );
\r
256 getPercent: function ( start, interval ) {
\r
257 var step = this.step,
\r
258 current = this.getPosition( start = start || 0 ),
\r
260 targetLength = start + interval,
\r
264 for ( percent = start + step; percent <= 1; percent += step ) {
\r
265 current = this.getPosition( percent );
\r
266 length += arcLength3d( last, current );
\r
267 if ( length >= targetLength ) {
\r
275 getAngle: function ( percent ) {
\r
276 var prev = this.getPosition( percent ),
\r
277 next = this.getPosition( percent + 0.001 ),
\r
278 dir = vec3.normalize( vec3.direction( prev, next ) ),
\r
279 cosValue = vec3.dot( dir, [1, 0, 0] );
\r
281 return Math.acos( cosValue ) + Math.PI;
\r
285 $.motionpath = function ( type, data ) {
\r
286 var object = new MotionPath[type]();
\r
287 object.init( data );
\r
290 } ( jQuery, window ) );
\r
292 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
\r
294 //>>excludeEnd("jqmBuildExclude");
\r