1 /** 2 * The Render Engine 3 * VirtualHTMLDivContext 4 * 5 * @fileoverview An extension of the HTML div context used to represent a game world larger than 6 * the viewport. 7 * 8 * @author: Brett Fattori (brettf@renderengine.com) 9 * 10 * @author: $Author: bfattori $ 11 * @version: $Revision: 1555 $ 12 * 13 * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com) 14 * 15 * Permission is hereby granted, free of charge, to any person obtaining a copy 16 * of this software and associated documentation files (the "Software"), to deal 17 * in the Software without restriction, including without limitation the rights 18 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 * copies of the Software, and to permit persons to whom the Software is 20 * furnished to do so, subject to the following conditions: 21 * 22 * The above copyright notice and this permission notice shall be included in 23 * all copies or substantial portions of the Software. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 31 * THE SOFTWARE. 32 * 33 */ 34 35 // The class this file defines and its required classes 36 R.Engine.define({ 37 "class":"R.rendercontexts.VirtualHTMLDivContext", 38 "requires":[ 39 "R.rendercontexts.HTMLDivContext", 40 "R.math.Math2D" 41 ] 42 }); 43 44 /** 45 * @class A HTML element render context whose world boundary is larger than the actual 46 * viewport. This allows the world to be rendered as if viewed through a 47 * window into a larger world. You can set the world position with simple 48 * scroll methods, or cause the world to transition to a specific point over 49 * a given duration. 50 * 51 * @constructor 52 * @param name {String} The name of the object 53 * @param windowWidth {Number} The width of the viewable window, in pixels 54 * @param windowHeight {Number} The height of the viewable window, in pixels 55 * @param worldWidth {Number} The width of the world, in pixels 56 * @param worldHeight {Number} The height of the world, in pixels 57 * @extends R.rendercontexts.CanvasContext 58 */ 59 R.rendercontexts.VirtualHTMLDivContext = function () { 60 return R.rendercontexts.HTMLDivContext.extend(/** @scope R.rendercontexts.VirtualHTMLDivContext.prototype */{ 61 62 scrollFromPt:null, 63 scrollToPt:null, 64 moving:false, 65 expireTime:0, 66 duration:0, 67 68 /** @private */ 69 constructor:function (name, windowWidth, windowHeight, worldWidth, worldHeight) { 70 // Create an element for us to use as our window 71 this.base(name || "VirtualHTMLDivContext", windowWidth, windowHeight); 72 this.setWorldBoundary(R.math.Rectangle2D.create(0, 0, worldWidth, worldHeight)); 73 74 // To force the element to have scrollable space, we create a div element 75 // within the context's element which is the size of the world 76 var shim = $("<div></div>").css({ 77 width:worldWidth, 78 height:worldHeight, 79 position:"relative", 80 left:0, 81 top:0 82 }); 83 this.jQ().append(shim); 84 85 this.scrollToPt = R.math.Point2D.create(0, 0); 86 this.scrollFromPt = R.math.Point2D.create(0, 0); 87 this.moving = false; 88 this.expireTime = 0; 89 this.duration = 0; 90 }, 91 92 /** 93 * Set the horizontal world position in pixels. 94 * 95 * @param x {Number} The horizontal scroll in pixels 96 */ 97 setHorizontalScroll:function (x) { 98 var maxX = this.getWorldBoundary().w - this.getViewport().w; 99 x = (x < 0 ? 0 : (x > maxX ? maxX : x)); 100 this.getWorldPosition().setX(x); 101 this.getViewport().getTopLeft().setX(x); 102 this.jQ().scrollLeft(x); 103 }, 104 105 /** 106 * Set the vertical world position in pixels. 107 * 108 * @param y {Number} The vertical scroll in pixels 109 */ 110 setVerticalScroll:function (y) { 111 var maxY = this.getWorldBoundary().h - this.getViewport().h; 112 y = (y < 0 ? 0 : (y > maxY ? maxY : y)); 113 this.getWorldPosition().setY(y); 114 this.getViewport().getTopLeft().setY(y); 115 this.jQ().scrollTop(x); 116 }, 117 118 /** 119 * Set the current world position to a specific point. 120 * @param pt {R.math.Point2D} The point to set the scroll to. 121 */ 122 setScroll:function (pt) { 123 this.setHorizontalScroll(pt.x); 124 this.setVerticalScroll(pt.y); 125 }, 126 127 /** 128 * Scroll to the given point, or location, over the given duration. 129 * @param duration {Number} The number of milliseconds for the transition to occur 130 * @param ptOrX {Number|R.math.Point2D} The X coordinate, or point, to scroll to 131 * @param [y] {Number} The Y coordinate, if <tt>ptOrX</tt> is a number 132 */ 133 scrollTo:function (duration, ptOrX, y) { 134 this.scrollFromPt.set(this.getWorldPosition()); 135 this.scrollToPt.set(ptOrX, y); 136 this.moving = true; 137 this.expireTime = R.Engine.worldTime + duration; 138 this.duration = duration; 139 }, 140 141 /** 142 * Get the horizontal scroll amount in pixels. 143 * @return {Number} The horizontal scroll 144 */ 145 getHorizontalScroll:function () { 146 return this.getWorldPosition().x; 147 }, 148 149 /** 150 * Get the vertical scroll amount in pixels. 151 * @return {Number} The vertical scroll 152 */ 153 getVerticalScroll:function () { 154 return this.getWorldPosition().y; 155 }, 156 157 /** 158 * If a transition was initiated with {@link #scrollTo}, 159 * this will update the viewport accordingly. 160 * 161 * @param worldTime {Number} The current world time 162 * @param dt {Number} The delta between the world time and the last time the world was updated 163 * in milliseconds. 164 */ 165 setupWorld:function (worldTime, dt) { 166 if (this.moving) { 167 if (worldTime < this.expireTime) { 168 // Moving 169 var sc = R.math.Point2D.create(this.scrollToPt).sub(this.scrollFromPt) 170 .mul((this.duration - (this.expireTime - worldTime)) / this.duration), 171 sp = R.math.Point2D.create(this.scrollFromPt).add(sc); 172 this.setScroll(sp); 173 sc.destroy(); 174 sp.destroy(); 175 } else { 176 // Arrived 177 this.moving = false; 178 this.expireTime = 0; 179 this.setScroll(this.scrollToPt); 180 } 181 } 182 this.base(worldTime, dt); 183 } 184 185 }, /** @scope R.rendercontexts.VirtualHTMLDivContext.prototype */ { 186 187 /** 188 * Get the class name of this object 189 * @return {String} The string "R.rendercontexts.VirtualHTMLDivContext" 190 */ 191 getClassName:function () { 192 return "R.rendercontexts.VirtualHTMLDivContext"; 193 } 194 }); 195 196 }; 197