1 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
2 //>>description: Tizen motion path component for gallery3d
4 //>>group: Tizen:Widgets:Components
6 define( [ ], function ( ) {
7 //>>excludeEnd("jqmBuildExclude");
9 /* ***************************************************************************
10 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included in
20 * all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 * ***************************************************************************
31 * Authors: Hyunsook Park <hyunsook.park@samsung.com>
32 * Wonseop Kim <wonseop.kim@samsung.com>
35 ( function ( $, window, undefined ) {
36 var HALF_PI = Math.PI / 2,
40 arcLength3d = function ( p0, p1 ) {
41 var d = [ p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2] ],
42 value = Math.sqrt( d[0] * d[0] + d[1] * d[1] + d[2] * d[2] );
46 MotionPath.base = function () {};
47 MotionPath.base.prototype = {
52 init: function ( data ) {},
53 calculateLevel: function ( maxLevel ) {},
54 calculateTotalLength: function () {},
55 getPosition: function ( percent ) {},
56 getPercent: function ( start, interval ) {},
57 getAngle: function ( percent ) {}
60 MotionPath.bezier2d = function () {};
61 MotionPath.bezier2d.prototype = $.extend( true, {}, MotionPath.base.prototype, {
62 init: function ( data ) {
63 this.points = data.points;
64 this.step = data.step || DEFAULT_STEP;
65 this.length = this.calculateTotalLength();
66 this.levels = this.calculateLevel( data.maxLevel ) || [];
69 calculateLevel: function ( maxLevel ) {
70 var totalLength = this.length,
71 interval = totalLength / maxLevel,
79 for ( i = 0; i < maxLevel; i += 1 ) {
80 levels[maxLevel - i] = this.getPercent( 0, interval * i );
86 calculateTotalLength: function () {
88 current = this.getPosition( 0 ),
92 for ( percent = step; percent <= 1; percent += step ) {
93 current = this.getPosition( percent );
94 length += arcLength3d( last, current );
100 getPosition: function ( percent ) {
101 var points = this.points,
102 getValue = function ( p1, c1, c2, p2, t ) {
103 return Math.pow(1 - t, 3) * p1 +
104 3 * t * Math.pow( 1 - t, 2 ) * c1 +
105 3 * Math.pow( t, 2 ) * ( 1 - t ) * c2 +
106 Math.pow( t, 3 ) * p2;
109 getValue( points[0][0], points[1][0], points[2][0], points[3][0], percent ),
110 getValue( points[0][2], points[1][2], points[2][2], points[3][2], percent )
112 return [ result[0], 0, result[1] ];
115 getPercent: function ( start, interval ) {
116 var step = this.step,
117 current = this.getPosition( start = start || 0 ),
119 targetLength = start + interval,
123 for ( percent = start + step; percent <= 1; percent += step ) {
124 current = this.getPosition( percent );
125 length += arcLength3d( last, current );
126 if ( length >= targetLength ) {
134 getAngle: function ( percent ) {
135 var points = this.points,
136 getTangent = function ( p1, c1, c2, p2, t ) {
137 return 3 * t * t * ( -p1 + 3 * c1 - 3 * c2 + p2 ) + 6 * t * ( p1 - 2 * c1 + c2 ) + 3 * ( -p1 + c1 );
139 tx = getTangent( points[0][0], points[1][0], points[2][0], points[3][0], percent ),
140 ty = getTangent( points[0][2], points[1][2], points[2][2], points[3][2], percent );
141 return Math.atan2( tx, ty ) - HALF_PI;
146 // clamped cubic B-spline curve
147 // http://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/node17.html
148 // http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve-coef.html
149 MotionPath.bspline = function () {};
150 MotionPath.bspline.prototype = $.extend( true, {}, MotionPath.base.prototype, {
152 _numberOfControls : 0,
156 init: function ( data ) {
157 this.points = data.points;
158 this.step = data.step || DEFAULT_STEP;
159 this._numberOfPoints = this.points.length - 1;
160 this._numberOfKnots = this._numberOfPoints + this._degree + 1;
162 var deltaKnot = 1 / ( this._numberOfKnots - ( 2 * this._degree ) ),
166 while ( i <= this._numberOfKnots ) {
167 if ( i <= this._degree ) {
168 this._knotVectors.push( 0 );
169 } else if ( i < this._numberOfKnots - this._degree + 1 ) {
170 this._knotVectors.push( v );
173 this._knotVectors.push( 1 );
178 this.length = this.calculateTotalLength();
179 this.levels = this.calculateLevel( data.maxLevel ) || [];
182 _Np: function ( percent, i, degree ) {
183 var knots = this._knotVectors,
187 N0 = function ( percent, i ) {
188 return ( ( knots[i] <= percent && percent < knots[i + 1] ) ? 1 : 0 );
191 if ( degree === 1 ) {
192 A = N0( percent, i );
193 B = N0( percent, i + 1 );
195 A = this._Np( percent, i, degree - 1 );
196 B = this._Np( percent, i + 1, degree - 1 );
199 denominator = knots[i + degree] - knots[i];
200 A *= ( denominator !== 0 ) ? ( ( percent - knots[i] ) / denominator ) : 0;
201 denominator = knots[i + degree + 1] - knots[i + 1];
202 B *= ( denominator !== 0 ) ? ( ( knots[i + degree + 1] - percent ) / denominator ) : 0;
207 calculateLevel: function ( maxLevel ) {
208 var totalLength = this.length,
209 interval = totalLength / maxLevel,
217 for ( i = 0; i < maxLevel; i += 1 ) {
218 levels[maxLevel - i] = this.getPercent( 0, interval * i );
223 calculateTotalLength: function () {
224 var step = this.step,
225 current = this.getPosition( 0 ),
229 for ( percent = step; percent <= 1; percent += step ) {
230 current = this.getPosition( percent );
231 length += arcLength3d( last, current );
237 getPosition: function ( percent ) {
238 var result = [], i, j, sum;
239 percent = percent.toFixed( 4 );
240 for ( j = 0; j < 3; j += 1 ) {
242 for ( i = 0; i <= this._numberOfPoints; i += 1 ) {
243 sum += this.points[i][j] * this._Np( percent, i, this._degree );
251 getPercent: function ( start, interval ) {
252 var step = this.step,
253 current = this.getPosition( start = start || 0 ),
255 targetLength = start + interval,
259 for ( percent = start + step; percent <= 1; percent += step ) {
260 current = this.getPosition( percent );
261 length += arcLength3d( last, current );
262 if ( length >= targetLength ) {
270 getAngle: function ( percent ) {
271 var prev = this.getPosition( percent ),
272 next = this.getPosition( percent + 0.001 ),
273 dir = vec3.normalize( vec3.direction( prev, next ) ),
274 cosValue = vec3.dot( dir, [1, 0, 0] );
276 return Math.acos( cosValue ) + Math.PI;
280 $.motionpath = function ( type, data ) {
281 var object = new MotionPath[type]();
285 } ( jQuery, window ) );
287 //>>excludeStart("jqmBuildExclude", pragmas.jqmBuildExclude);
289 //>>excludeEnd("jqmBuildExclude");