@@ -157,6 +157,105 @@ var Vector = require('../geometry/Vector');
157157 render . context . scale ( pixelRatio , pixelRatio ) ;
158158 } ;
159159
160+ /**
161+ * Positions and sizes the viewport around the given object bounds.
162+ * Objects must have at least one of the following properties:
163+ * - `object.bounds`
164+ * - `object.position`
165+ * - `object.min` and `object.max`
166+ * - `object.x` and `object.y`
167+ * @method lookAt
168+ * @param {render } render
169+ * @param {object[] } objects
170+ * @param {vector } [padding]
171+ * @param {bool } [center=true]
172+ */
173+ Render . lookAt = function ( render , objects , padding , center ) {
174+ center = typeof center !== 'undefined' ? center : true ;
175+ objects = Common . isArray ( objects ) ? objects : [ objects ] ;
176+
177+ var padding = padding || {
178+ x : 0 ,
179+ y : 0
180+ } ;
181+
182+ // find bounds of all objects
183+ var bounds = {
184+ min : { x : Infinity , y : Infinity } ,
185+ max : { x : - Infinity , y : - Infinity }
186+ } ;
187+
188+ for ( var i = 0 ; i < objects . length ; i += 1 ) {
189+ var object = objects [ i ] ,
190+ min = object . bounds ? object . bounds . min : ( object . min || object . position || object ) ,
191+ max = object . bounds ? object . bounds . max : ( object . max || object . position || object ) ;
192+
193+ if ( min && max ) {
194+ if ( min . x < bounds . min . x )
195+ bounds . min . x = min . x ;
196+
197+ if ( max . x > bounds . max . x )
198+ bounds . max . x = max . x ;
199+
200+ if ( min . y < bounds . min . y )
201+ bounds . min . y = min . y ;
202+
203+ if ( max . y > bounds . max . y )
204+ bounds . max . y = max . y ;
205+ }
206+ }
207+
208+ // find ratios
209+ var width = ( bounds . max . x - bounds . min . x ) + 2 * padding . x ,
210+ height = ( bounds . max . y - bounds . min . y ) + 2 * padding . y ,
211+ viewHeight = render . canvas . height ,
212+ viewWidth = render . canvas . width ,
213+ outerRatio = viewWidth / viewHeight ,
214+ innerRatio = width / height ,
215+ scaleX = 1 ,
216+ scaleY = 1 ;
217+
218+ // find scale factor
219+ if ( innerRatio > outerRatio ) {
220+ scaleY = innerRatio / outerRatio ;
221+ } else {
222+ scaleX = outerRatio / innerRatio ;
223+ }
224+
225+ // enable bounds
226+ render . options . hasBounds = true ;
227+
228+ // position and size
229+ render . bounds . min . x = bounds . min . x ;
230+ render . bounds . max . x = bounds . min . x + width * scaleX ;
231+ render . bounds . min . y = bounds . min . y ;
232+ render . bounds . max . y = bounds . min . y + height * scaleY ;
233+
234+ // center
235+ if ( center ) {
236+ render . bounds . min . x += width * 0.5 - ( width * scaleX ) * 0.5 ;
237+ render . bounds . max . x += width * 0.5 - ( width * scaleX ) * 0.5 ;
238+ render . bounds . min . y += height * 0.5 - ( height * scaleY ) * 0.5 ;
239+ render . bounds . max . y += height * 0.5 - ( height * scaleY ) * 0.5 ;
240+ }
241+
242+ // padding
243+ render . bounds . min . x -= padding . x ;
244+ render . bounds . max . x -= padding . x ;
245+ render . bounds . min . y -= padding . y ;
246+ render . bounds . max . y -= padding . y ;
247+
248+ // update mouse
249+ if ( render . mouse ) {
250+ Mouse . setScale ( render . mouse , {
251+ x : ( render . bounds . max . x - render . bounds . min . x ) / render . canvas . width ,
252+ y : ( render . bounds . max . y - render . bounds . min . y ) / render . canvas . height
253+ } ) ;
254+
255+ Mouse . setOffset ( render . mouse , render . bounds . min ) ;
256+ }
257+ } ;
258+
160259 /**
161260 * Renders the given `engine`'s `Matter.World` object.
162261 * This is the entry point for all rendering and should be called every time the scene changes.
0 commit comments