UNPKG

60.8 kBHTMLView Raw
1<!DOCTYPE html>
2
3<html lang="en">
4<head>
5 <meta charset="utf-8">
6 <meta name="viewport" content="width=device-width">
7 <title>CrossBrowdy API documentation Source: CrossBase/audiovisual/image/canvas/CB_Canvas.js</title>
8
9 <!--[if lt IE 9]>
10 <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
11 <![endif]-->
12 <link type="text/css" rel="stylesheet" href="styles/sunlight.default.css">
13
14 <link type="text/css" rel="stylesheet" href="styles/site.cosmo.css">
15
16</head>
17
18<body style="min-width:800px; overflow-wrap:break-word; word-wrap:break-word; word-break:break-word; line-break:strict; hyphens:none; -webkit-hyphens:none; -moz-hyphens:none;">
19
20<div class="navbar navbar-default navbar-fixed-top ">
21<div class="container">
22 <div class="navbar-header">
23 <a class="navbar-brand" href="index.html">CrossBrowdy API documentation</a>
24 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target="#topNavigation">
25 <span class="icon-bar"></span>
26 <span class="icon-bar"></span>
27 <span class="icon-bar"></span>
28 </button>
29 </div>
30 <div class="navbar-collapse collapse" id="topNavigation">
31 <ul class="nav navbar-nav">
32
33 <li class="dropdown">
34 <a href="namespaces.list.html" class="dropdown-toggle" data-toggle="dropdown">Namespaces<b class="caret"></b></a>
35 <ul class="dropdown-menu inline">
36 <li><a href="CB_Arrays.html">CB_Arrays</a></li><li><a href="CB_AudioDetector.html">CB_AudioDetector</a></li><li><a href="CB_baseSymbols.html">CB_baseSymbols</a></li><li><a href="CB_Client.html">CB_Client</a></li><li><a href="CB_Collisions.html">CB_Collisions</a></li><li><a href="CB_Configuration.html">CB_Configuration</a></li><li><a href="CB_Configuration.CrossBase.html">CB_Configuration.CrossBase</a></li><li><a href="CB_Configuration.CrossBrowdy.html">CB_Configuration.CrossBrowdy</a></li><li><a href="CB_Controllers.html">CB_Controllers</a></li><li><a href="CB_Controllers_Proprietary.html">CB_Controllers_Proprietary</a></li><li><a href="CB_Controllers_Proprietary.WII.html">CB_Controllers_Proprietary.WII</a></li><li><a href="CB_Controllers_Proprietary.WII_U.html">CB_Controllers_Proprietary.WII_U</a></li><li><a href="CB_Device.html">CB_Device</a></li><li><a href="CB_Device.AmbientLight.html">CB_Device.AmbientLight</a></li><li><a href="CB_Device.Battery.html">CB_Device.Battery</a></li><li><a href="CB_Device.Location.html">CB_Device.Location</a></li><li><a href="CB_Device.Motion.html">CB_Device.Motion</a></li><li><a href="CB_Device.Orientation.html">CB_Device.Orientation</a></li><li><a href="CB_Device.Proximity.html">CB_Device.Proximity</a></li><li><a href="CB_Device.Vibration.html">CB_Device.Vibration</a></li><li><a href="CB_Elements.html">CB_Elements</a></li><li><a href="CB_Events.html">CB_Events</a></li><li><a href="CB_Keyboard.html">CB_Keyboard</a></li><li><a href="CB_Keyboard.chars.html">CB_Keyboard.chars</a></li><li><a href="CB_Keyboard.extended.html">CB_Keyboard.extended</a></li><li><a href="CB_Keyboard.keys.html">CB_Keyboard.keys</a></li><li><a href="CB_Modules.html">CB_Modules</a></li><li><a href="CB_Mouse.html">CB_Mouse</a></li><li><a href="CB_Mouse.CursorImage.html">CB_Mouse.CursorImage</a></li><li><a href="CB_Net.html">CB_Net</a></li><li><a href="CB_Net.Fetch.html">CB_Net.Fetch</a></li><li><a href="CB_Net.REST.html">CB_Net.REST</a></li><li><a href="CB_Net.Sockets.html">CB_Net.Sockets</a></li><li><a href="CB_Net.Sockets.SockJS.html">CB_Net.Sockets.SockJS</a></li><li><a href="CB_Net.XHR.html">CB_Net.XHR</a></li><li><a href="CB_Pointer.html">CB_Pointer</a></li><li><a href="CB_Screen.html">CB_Screen</a></li><li><a href="CB_Speaker.html">CB_Speaker</a></li><li><a href="CB_Touch.html">CB_Touch</a></li>
37 </ul>
38 </li>
39
40 <li class="dropdown">
41 <a href="classes.list.html" class="dropdown-toggle" data-toggle="dropdown">Classes<b class="caret"></b></a>
42 <ul class="dropdown-menu inline">
43 <li><a href="CB_AudioFile.html">CB_AudioFile</a></li><li><a href="CB_AudioFile_API.AAPI.html">CB_AudioFile_API.AAPI</a></li><li><a href="CB_AudioFile_API.ACMP.html">CB_AudioFile_API.ACMP</a></li><li><a href="CB_AudioFile_API.SM2.html">CB_AudioFile_API.SM2</a></li><li><a href="CB_AudioFile_API.WAAPI.html">CB_AudioFile_API.WAAPI</a></li><li><a href="CB_AudioFileCache.html">CB_AudioFileCache</a></li><li><a href="CB_AudioFileSprites.html">CB_AudioFileSprites</a></li><li><a href="CB_AudioFileSpritesPool.html">CB_AudioFileSpritesPool</a></li><li><a href="CB_Canvas.html">CB_Canvas</a></li><li><a href="CB_GraphicSprites.html">CB_GraphicSprites</a></li><li><a href="CB_GraphicSpritesScene.html">CB_GraphicSpritesScene</a></li>
44 </ul>
45 </li>
46
47 <li class="dropdown">
48 <a href="global.html" class="dropdown-toggle" data-toggle="dropdown">Global<b class="caret"></b></a>
49 <ul class="dropdown-menu inline">
50 <li><a href="global.html#CB_addCredits">CB_addCredits</a></li><li><a href="global.html#CB_BASE_NAME">CB_BASE_NAME</a></li><li><a href="global.html#CB_baseToBase">CB_baseToBase</a></li><li><a href="global.html#CB_baseToInt">CB_baseToInt</a></li><li><a href="global.html#CB_br2nl">CB_br2nl</a></li><li><a href="global.html#CB_brToNl">CB_brToNl</a></li><li><a href="global.html#CB_combineArraysOrObjects">CB_combineArraysOrObjects</a></li><li><a href="global.html#CB_combineAutomatically">CB_combineAutomatically</a></li><li><a href="global.html#CB_combineJSON">CB_combineJSON</a></li><li><a href="global.html#CB_combineURIParameters">CB_combineURIParameters</a></li><li><a href="global.html#CB_combineURLParameters">CB_combineURLParameters</a></li><li><a href="global.html#CB_console">CB_console</a></li><li><a href="global.html#CB_copyObject">CB_copyObject</a></li><li><a href="global.html#CB_countDecimalDigits">CB_countDecimalDigits</a></li><li><a href="global.html#CB_countDecimalPart">CB_countDecimalPart</a></li><li><a href="global.html#CB_countDecimals">CB_countDecimals</a></li><li><a href="global.html#CB_countIntegerDigits">CB_countIntegerDigits</a></li><li><a href="global.html#CB_countIntegerPart">CB_countIntegerPart</a></li><li><a href="global.html#CB_credits">CB_credits</a></li><li><a href="global.html#CB_CREDITS_DEFAULT">CB_CREDITS_DEFAULT</a></li><li><a href="global.html#CB_forceString">CB_forceString</a></li><li><a href="global.html#CB_forEach">CB_forEach</a></li><li><a href="global.html#CB_getBase64StringObject">CB_getBase64StringObject</a></li><li><a href="global.html#CB_getCookie">CB_getCookie</a></li><li><a href="global.html#CB_getDatum">CB_getDatum</a></li><li><a href="global.html#CB_getJSONPropertyValue">CB_getJSONPropertyValue</a></li><li><a href="global.html#CB_getLZStringObject">CB_getLZStringObject</a></li><li><a href="global.html#CB_getValueIndex">CB_getValueIndex</a></li><li><a href="global.html#CB_getValuePath">CB_getValuePath</a></li><li><a href="global.html#CB_includeJSFile">CB_includeJSFile</a></li><li><a href="global.html#CB_indexOf">CB_indexOf</a></li><li><a href="global.html#CB_init">CB_init</a></li><li><a href="global.html#CB_intToBase">CB_intToBase</a></li><li><a href="global.html#CB_isArray">CB_isArray</a></li><li><a href="global.html#CB_isEmail">CB_isEmail</a></li><li><a href="global.html#CB_isFileLocal">CB_isFileLocal</a></li><li><a href="global.html#CB_isString">CB_isString</a></li><li><a href="global.html#CB_lastIndexOf">CB_lastIndexOf</a></li><li><a href="global.html#CB_ltrim">CB_ltrim</a></li><li><a href="global.html#CB_NAME">CB_NAME</a></li><li><a href="global.html#CB_nl2br">CB_nl2br</a></li><li><a href="global.html#CB_nlToBr">CB_nlToBr</a></li><li><a href="global.html#CB_numberFormat">CB_numberFormat</a></li><li><a href="global.html#CB_numberOfDecimalDigits">CB_numberOfDecimalDigits</a></li><li><a href="global.html#CB_numberOfDecimals">CB_numberOfDecimals</a></li><li><a href="global.html#CB_numberOfIntegerDigits">CB_numberOfIntegerDigits</a></li><li><a href="global.html#CB_OPTIONS">CB_OPTIONS</a></li><li><a href="global.html#CB_parseJSON">CB_parseJSON</a></li><li><a href="global.html#CB_parseString">CB_parseString</a></li><li><a href="global.html#CB_regularExpressionString">CB_regularExpressionString</a></li><li><a href="global.html#CB_renderString">CB_renderString</a></li><li><a href="global.html#CB_replaceAll">CB_replaceAll</a></li><li><a href="global.html#CB_rtrim">CB_rtrim</a></li><li><a href="global.html#CB_scriptPath">CB_scriptPath</a></li><li><a href="global.html#CB_scriptPathCalculate">CB_scriptPathCalculate</a></li><li><a href="global.html#CB_setCookie">CB_setCookie</a></li><li><a href="global.html#CB_setDatum">CB_setDatum</a></li><li><a href="global.html#CB_sizeof">CB_sizeof</a></li><li><a href="global.html#CB_sizeOf">CB_sizeOf</a></li><li><a href="global.html#CB_stringifyJSON">CB_stringifyJSON</a></li><li><a href="global.html#CB_symmetricCall">CB_symmetricCall</a></li><li><a href="global.html#CB_symmetricCallClear">CB_symmetricCallClear</a></li><li><a href="global.html#CB_this">CB_this</a></li><li><a href="global.html#CB_trim">CB_trim</a></li><li><a href="global.html#CB_VERSION">CB_VERSION</a></li>
51 </ul>
52 </li>
53
54 </ul>
55
56 <div class="col-sm-3 col-md-3">
57 <form class="navbar-form" role="search">
58 <div class="input-group">
59 <input type="text" class="form-control" placeholder="Search" name="q" id="search-input">
60 <div class="input-group-btn">
61 <button class="btn btn-default" id="search-submit"><i class="glyphicon glyphicon-search"></i></button>
62 </div>
63 </div>
64 </form>
65 </div>
66
67 </div>
68
69</div>
70</div>
71
72
73<div class="container" id="toc-content" style="width:100%;">
74<div class="row" style="width:100%;">
75
76
77 <div class="col-md-12">
78
79 <div id="main">
80
81
82 <h1 class="page-title">Source: CrossBase/audiovisual/image/canvas/CB_Canvas.js</h1>
83
84<section>
85 <article>
86 <pre
87 class="sunlight-highlight-javascript linenums">/**
88 * @file Canvas management (including emulation fallbacks). Contains the {@link CB_Canvas} class.
89 * @author Joan Alba Maldonado &lt;workindalian@gmail.com>
90 * @license Creative Commons Attribution 4.0 International. See more at {@link https://crossbrowdy.com/about#what_is_the_crossbrowdy_copyright_and_license}.
91 */
92
93
94/**
95 * Class to manage a canvas.
96 * @class
97 * @classdesc Class to manage a canvas. For clients which do not support native [canvas]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas}, it provides [Adobe Flash (formerly Macromedia Flash)]{@link https://en.wikipedia.org/wiki/Adobe_Flash_Player} emulation with [FlashCanvas]{@link https://github.com/everlaat/flashcanvas}, Microsoft Silverlight emulation with [SLCanvas]{@link https://slcanvas.codeplex.com/}, VML emulation with [ExplorerCanvas]{@link https://github.com/arv/explorercanvas} (reinforced with [canvas-text]{@link https://github.com/PhenX/canvas-text}) and DHTML (DOM elements) emulation with [CanBox]{@link https://github.com/robertinglin/CanBox}.
98 NOTE:
99 To make the VML emulation work without errors (using [ExplorerCanvas]{@link https://github.com/arv/explorercanvas}), it is recommended to always load [FlashCanvas]{@link https://github.com/everlaat/flashcanvas} (which already includes [ExplorerCanvas]{@link https://github.com/arv/explorercanvas}) in your HTML code (without using lazy-load, as [ExplorerCanvas]{@link https://github.com/arv/explorercanvas} does not support it). This is recommended even when we are not going to use [Adobe Flash (formerly Macromedia Flash)]{@link https://en.wikipedia.org/wiki/Adobe_Flash_Player} emulation with [FlashCanvas]{@link https://github.com/everlaat/flashcanvas}.
100 This is an example (should be placed before loading the main "CrossBrowdy" script):
101 &amp;lt;!-- Loads FlashCanvas (Flash emulation) before CrossBrowdy. Needed also to use ExplorerCanvas (VML emulation) without problems: --&amp;gt;
102 &amp;lt;script type="text/javascript" src="CrossBrowdy/CrossBase/audiovisual/image/canvas/FlashCanvas/pro/bin/flashcanvas.js"&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;!-- FlashCanvas/ExplorerCanvas do not support lazy load. --&amp;gt;
103 * @param {string} canvasId - The desired ID for the canvas.
104 * @param {('2d'|'webgl'|'experimental-webgl'|'webgl2'|'experimental-webgl2'|'bitmaprenderer')} [contextType='2d'] - The contextType desired by default. More information: [HTMLCanvasElement.getContext]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext}. Note that most emulation methods will only support "2d".
105 * @param {integer} [canvasWidth={@link CB_Canvas.WIDTH_DEFAULT}] - The desired width (horizontal size) in pixels for the canvas.
106 * @param {integer} [canvasHeight={@link CB_Canvas.HEIGHT_DEFAULT}] - The desired height (vertical size) in pixels for the canvas.
107 * @param {function} [onLoad] - Callback function that will be called when the canvas is finally loaded. It will not receive parameters, being "this" the {@link CB_Canvas} object itself.
108 * @param {function} [onError] - Callback function that will be called when there is an error creating or loading the canvas. Being "this" the {@link CB_Canvas} object itself, the unique parameter received will be a string describing the error (if it could be determined).
109 * @param {Element} [canvasParent=document.body] - The parent element desired to adopt the canvas.
110 * @param {array} [alternativeCanvasEmulationPreferredOrder={@link CB_Configuration.CrossBase.CB_Canvas_PREFERRED_EMULATION_METHODS}] - Numeric array listing the desired alternative emulation methods for rendering the canvas, in order of preference. Supported emulation methods: "FLASH", "VML", "DHTML" and "SILVERLIGHT".
111 * @param {boolean} [forceFirstEmulationMethod=false] - If set to true, it will force to use the first alternative emulation method desired (even when this alternative emulation method could be not supported and even when native [canvas]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas} support could be supported).
112 * @param {boolean} [addOtherMethods=true] - If set to true, it will add other alternative methods (if any is missing) at the end of the desired alternative emulation methods so they will also be checked and used if the previous ones are not finally used. The order they will be added will be the one used in the {@link CB_Configuration.CrossBase.CB_Canvas_PREFERRED_EMULATION_METHODS} constant.
113 * @param {boolean} [allowFlashCanvasLocally={@link CB_Configuration.CrossBase.FLASHCANVAS_ALLOW_RUN_LOCALLY_DEFAULT}] - If set to true, it will allow to use [Adobe Flash (formerly Macromedia Flash)]{@link https://en.wikipedia.org/wiki/Adobe_Flash_Player} emulation (if needed) even when it is running locally. Uses the {@link CB_Client.isRunningLocally} function internally.
114 * @returns {CB_Canvas} Returns a new {@link CB_Canvas} object.
115 */
116var CB_Canvas = function(canvasId, contextType, canvasWidth, canvasHeight, onLoad, onError, canvasParent, alternativeCanvasEmulationPreferredOrder, forceFirstEmulationMethod, addOtherMethods, allowFlashCanvasLocally)
117{
118 //Creates an instance of this object and returns it in the case that it is being called from an unexpected context:
119 if (this === window || !(this instanceof CB_Canvas)) { return new CB_Canvas(canvasId, contextType, canvasWidth, canvasHeight, canvasParent, alternativeCanvasEmulationPreferredOrder, forceFirstEmulationMethod, addOtherMethods, allowFlashCanvasLocally); }
120
121 //Properties:
122 this._parent = undefined; //The parents of the canvas.
123 this._id = undefined; //The ID of the canvas element.
124 this.canvas = undefined; //Canvas element itself.
125 this.context = undefined; //Context of the canvas element.
126 this._contextType = undefined; //Type of the context of the canvas element.
127 this._supported = false; //Defines whether Canvas works.
128 this._width = undefined; //Canvas width.
129 this._height = undefined; //Canvas height.
130 this._mode = "NONE"; //Stores the mode used for the canvas ('NONE', 'NORMAL', 'FLASH', 'SILVERLIGHT', 'VML' or 'DHTML').
131 this._ready = false; //Stores whether the canvas is ready to be used or not (useful for SLCanvas).
132 this._loading = true; //Stores whether the canvas is loading or not (useful for SLCanvas).
133
134
135 //Calls the constructor of the object when creates an instance:
136 return this._init(canvasId, contextType, canvasWidth, canvasHeight, onLoad, onError, canvasParent, alternativeCanvasEmulationPreferredOrder, forceFirstEmulationMethod, addOtherMethods, allowFlashCanvasLocally);
137}
138
139
140/*
141//Static properties and functions:
142CB_Canvas._MODES = { "NONE" : 0, "VML" : 1, "FLASH" : 2, "SILVERLIGHT" : 3, "DHTML" : 4 }; //Defines rendering mode.
143CB_Canvas._MODES_STRING = [ "NONE", "VML", "FLASH", "SILVERLIGHT", "DHTML" ];
144CB_Canvas.getModeString =
145 function(mode)
146 {
147 if (typeof(CB_Canvas._MODES_STRING[mode]) !== "undefined") { return CB_Canvas._MODES_STRING[mode]; }
148 else { return "UNKNOWN"; }
149 };
150*/
151
152
153//Constants:
154/**
155 * Default canvas width in pixels.
156 * @constant
157 * @type {integer}
158 * @default
159 */
160CB_Canvas.WIDTH_DEFAULT = 320; //Default canvas width.
161/**
162 * Default canvas height in pixels.
163 * @constant
164 * @type {integer}
165 * @default
166 */
167CB_Canvas.HEIGHT_DEFAULT = 240; //Default canvas height.
168
169CB_Canvas.prototype._allowedContextTypes = ["2d", "webgl", "experimental-webgl", "webgl2", "experimental-webgl2", "bitmaprenderer"]; //Allowed context types.
170
171
172//Constructor:
173CB_Canvas.prototype._init = function(canvasId, contextType, canvasWidth, canvasHeight, onLoad, onError, canvasParent, alternativeCanvasEmulationPreferredOrder, forceFirstEmulationMethod, addOtherMethods, allowFlashCanvasLocally)
174{
175 //If they have not been sent, uses default parameters:
176 if (typeof(canvasParent) === "undefined" || canvasParent === null) { canvasParent = document.body; }
177
178 //Gets the best emulation method:
179 alternativeCanvasEmulation = CB_Canvas.bestEmulation(alternativeCanvasEmulationPreferredOrder, forceFirstEmulationMethod, addOtherMethods, allowFlashCanvasLocally);
180
181 //Defines the parent given:
182 this._parent = canvasParent;
183
184 //Defines the canvas element by using the ID given:
185 this.setId(canvasId);
186 this.set(this.getId(), canvasWidth, canvasHeight, onLoad, onError, alternativeCanvasEmulation, forceFirstEmulationMethod);
187
188 //Detects whether Canvas works:
189 if (this.isSupported())
190 {
191 //Defines the canvas context:
192 this.setContextType(contextType);
193 this.getContext(this.getContextType());
194 }
195 else
196 {
197 //There is no mode unless we are using Silverlight (since SLCanvas needs time to load):
198 if (this._mode !== "SILVERLIGHT" &amp;&amp; !this._loading)
199 {
200 this._mode = "NONE"; //This will be changed when SLCanvas loads (if it does).
201 }
202 }
203
204 return this;
205}
206
207
208/**
209 * Tells whether the current client needs canvas emulation or not. Uses {@link CB_Client.supportsCanvas} internally.
210 * @function
211 * @returns {boolean} Returns whether the current client needs canvas emulation or not.
212 */
213CB_Canvas.needsEmulation = function()
214{
215 return !CB_Client.supportsCanvas();
216}
217
218
219/**
220 * Calculates and returns the best alternative canvas emulation.
221 * @function
222 * @param {array|string} [preferredOrder={@link CB_Configuration.CrossBase.CB_Canvas_PREFERRED_EMULATION_METHODS}] - Numeric array listing the desired alternative emulation methods for rendering the canvas, in order of preference. Possible emulation methods: "FLASH", "VML", "DHTML" and "SILVERLIGHT". It can also be a string with the unique desired canvas emulation method or with "NO" or "NONE" value (meaning no emulation method is desired and then the returning value will always be "NONE").
223 * @param {boolean} [forceFirstEmulationMethod=false] - If set to true, it will force to return the first alternative emulation method desired which is detected as supported without being too strict (even when this alternative emulation method could be not really supported and even when native [canvas]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas} support could be supported).
224 * @param {boolean} [addOtherMethods=true] - If set to true, it will add other alternative methods (if any is missing) at the end of the desired alternative emulation methods so they will also be checked and used if the previous ones are not finally used. The order they will be added will be the one used in the {@link CB_Configuration.CrossBase.CB_Canvas_PREFERRED_EMULATION_METHODS} constant.
225 * @param {boolean} [allowFlashCanvasLocally={@link CB_Configuration.CrossBase.FLASHCANVAS_ALLOW_RUN_LOCALLY_DEFAULT}] - If set to true, it will allow to use [Adobe Flash (formerly Macromedia Flash)]{@link https://en.wikipedia.org/wiki/Adobe_Flash_Player} emulation (if needed) even when it is running locally. Uses the {@link CB_Client.isRunningLocally} function internally.
226 * @returns {'NONE'|'FLASH'|'SILVERLIGHT'|'VML'|'DHTML'} Returns "NONE" if no canvas emulation is needed/supported (and no emulation method is forced). Otherwise, it returns the best emulation method calculated ("FLASH", "SILVERLIGHT", "VML" or "DHTML").
227 */
228CB_Canvas.bestEmulation = function(preferredOrder, forceFirstEmulationMethod, addOtherMethods, allowFlashCanvasLocally)
229{
230 //If not given, sets the default parameters:
231 if (typeof(addOtherMethods) === "undefined" || addOtherMethods === null) { addOtherMethods = true; }
232 if (typeof(allowFlashCanvasLocally) === "undefined" || allowFlashCanvasLocally === null) { allowFlashCanvasLocally = CB_Configuration[CB_BASE_NAME].FLASHCANVAS_ALLOW_RUN_LOCALLY_DEFAULT; }
233
234 //If we don't want to force emulation and we don't need any emulation, exits:
235 if (!forceFirstEmulationMethod &amp;&amp; !CB_Canvas.needsEmulation())
236 {
237 return "NONE";
238 }
239
240 //Defines all allowed canvas emulation methods and the default order or preference (to use in case it was not provided):
241 var allEmulationMethods = CB_Configuration[CB_BASE_NAME].CB_Canvas_PREFERRED_EMULATION_METHODS;
242
243 //If not given, uses the default order of preference:
244 if (typeof(preferredOrder) === "undefined" || preferredOrder === null)
245 {
246 //If we want to force the first emulation method, we exit returning the first one:
247 //if (forceFirstEmulationMethod) { return allEmulationMethods[0]; } //We can be sure it is a valid one.
248 preferredOrder = allEmulationMethods; //Uses the default order with all methods.
249 addOtherMethods = false; //There is no need to add other methods since it contains all.
250 }
251 //...if the preferred order is not an array, we force it to be one:
252 else if (!CB_isArray(preferredOrder)) { preferredOrder = [(preferredOrder+"").toUpperCase()]; } //Parses it as a string and to upper case.
253
254 //If the user doesn't want any emulation method, we exit:
255 if (preferredOrder[0] === "NO" || preferredOrder[0] === "NONE") { return "NONE"; }
256
257 //If not all emulation methods has been given in the preferred order, adds them (at the end) if we wanted:
258 if (addOtherMethods &amp;&amp; preferredOrder !== allEmulationMethods || preferredOrder[0] === "AUTO") //We don't need to add them if already has all methods.
259 {
260 var allEmulationMethodsLength = allEmulationMethods.length;
261 for (var x = 0; x &lt; allEmulationMethodsLength; x++)
262 {
263 //If the current emulation method of this loop is not in the given preferred order, we add it at the end of the array:
264 if (CB_indexOf(preferredOrder, allEmulationMethods[x]) === -1) { preferredOrder[preferredOrder.length] = allEmulationMethods[x]; }
265 }
266 }
267
268 //Check the emulation methods availability according to the preferred order given:
269 var preferredOrderLength = preferredOrder.length;
270 var chosenEmulationMethod = "NONE";
271 var currentEmulationMethod;
272 for (x = 0; x &lt; preferredOrderLength; x++)
273 {
274 currentEmulationMethod = CB_trim(preferredOrder[x]).toUpperCase();
275
276 //If we want to force the first emulation method and it is available (not being strict):
277 if (forceFirstEmulationMethod &amp;&amp; CB_Canvas.supportsEmulationMethod(currentEmulationMethod, false))
278 {
279 chosenEmulationMethod = currentEmulationMethod;
280 break;
281 }
282 //...otherwise, if the method is available (being strict):
283 else if (CB_Canvas.supportsEmulationMethod(currentEmulationMethod, true))
284 {
285 chosenEmulationMethod = currentEmulationMethod;
286 break;
287 }
288 }
289
290 //Returns the chosen emulation method (if any):
291 return chosenEmulationMethod;
292}
293
294
295/**
296 * Tells whether the current client is compatible with a given canvas emulation method or not.
297 * @function
298 * @param {string} emulationMethod - Emulation method we want to check. Possible emulation methods: "FLASH", "VML", "DHTML" and "SILVERLIGHT".
299 * @param {boolean} [strictMode=true] - If set to true, the compatibility will be checked more carefully. If set to false (not recommended), the method could return true even when sometimes the canvas emulation method is not totally supported by the current client.
300 * @returns {boolean} Returns whether the current client is compatible with the given canvas emulation method or not.
301 */
302CB_Canvas.supportsEmulationMethod = function(emulationMethod, strictMode)
303{
304 //If not given, uses the default parameters:
305 if (typeof(strictMode) === "undefined" || strictMode === null) { strictMode = true; }
306
307 emulationMethod = CB_trim(emulationMethod).toUpperCase();
308
309 var isAvailable = false;
310
311 //If we want to try Flash (FlashCanvas):
312 if (emulationMethod === "FLASH")
313 {
314 //If FlashCanvas is present:
315 var FlashCanvas = window.FlashCanvas || undefined;
316 if (typeof(FlashCanvas) !== "undefined")
317 {
318 //If we don't want to be strict, the method is supported:
319 if (!strictMode) { isAvailable = true; }
320 //...otherwise, if Flash is installed and version is 9 or newer:
321 else if (CB_Client.supportsFlash() &amp;&amp; CB_Client.getFlashVersion()[0] >= 9)
322 {
323 //If the script is not running locally or it is running but we allow running FlashCanvas anyway:
324 if (!CB_Client.isRunningLocally() || CB_Client.isRunningLocally() &amp;&amp; allowFlashCanvasLocally)
325 {
326 isAvailable = true;
327 }
328 }
329
330 }
331 }
332 //...otherwise, if we want to try SILVERLIGHT (SLCanvas):
333 else if (emulationMethod === "SILVERLIGHT")
334 {
335 //If SLCanvas is present:
336 var slcanvas = window.slcanvas || undefined;
337 if (typeof(slcanvas) !== "undefined")
338 {
339 //If we don't want to be strict, the method is supported:
340 if (!strictMode) { isAvailable = true; }
341 //...otherwise, if Silverlight is installed:
342 if (CB_Client.supportsSilverlight())
343 {
344 isAvailable = true;
345 }
346 }
347 }
348 //...otherwise, if we want to try VML (ExplorerCanvas):
349 else if (emulationMethod === "VML")
350 {
351 //If ExplorerCanvas is present:
352 var G_vmlCanvasManager = window.G_vmlCanvasManager || undefined;
353 if (typeof(G_vmlCanvasManager) !== "undefined" &amp;&amp; G_vmlCanvasManager.initElement.toString().indexOf("macromedia") === -1) //We make sure that the object has not been created by FlashCanvas.
354 {
355 //If we don't want to be strict, the method is supported:
356 if (!strictMode) { isAvailable = true; }
357 //...otherwise, if we are not using Internet Explorer 5 (ExplorerCanvas doesn't work with IE5/IE5.5):
358 if (navigator.appVersion.indexOf("MSIE 5") === -1)
359 {
360 isAvailable = true;
361 }
362 }
363 }
364 //...otherwise, if we want to try DHTML (Canbox):
365 else if (emulationMethod === "DHTML")
366 {
367 //If Canbox is present:
368 var _CanboxManager = window._CanboxManager || undefined;
369 if (typeof(_CanboxManager) !== "undefined")
370 {
371 //If we don't want to be strict, the method is supported:
372 if (!strictMode) { isAvailable = true; }
373 //...otherwise, if we are not using Internet Explorer 5 (Canbox doesn't work with IE5/IE5.5):
374 else if (navigator.appVersion.indexOf("MSIE 5") === -1)
375 {
376 isAvailable = true;
377 }
378 }
379 }
380
381 return isAvailable;
382}
383
384
385/**
386 * Sets the desired identifier (ID) of the canvas element. Since this method is called by the constructor already, it is not needed to be called unless the canvas element wants to be defined again through the {@link CB_Canvas#set} method. Note that changing the ID after the canvas has been set could lead to some problems when using certain emulation methods so it is not recommended.
387 * @function
388 * @param {string} canvasId - Identifier (ID) for the canvas element.
389 */
390CB_Canvas.prototype.setId = function(canvasId)
391{
392 this._id = CB_trim(canvasId);
393 if (typeof(this.canvas) !== "undefined" &amp;&amp; this.canvas !== null &amp;&amp; typeof(this.canvas.setAttribute) === "function")
394 {
395 this.canvas.setAttribute("id", canvasId);
396 }
397}
398
399
400/**
401 * Returns the identifier (ID) of the canvas element.
402 * @function
403 * @returns {string} Returns the identifier (ID) of the canvas element.
404 */
405CB_Canvas.prototype.getId = function()
406{
407 return this._id;
408}
409
410
411/**
412 * Defines the canvas element. Since this method is called by the constructor already, it is not needed to be called unless the canvas element wants to be defined again.
413 * @function
414 * @param {string} canvasId - The desired ID for the canvas.
415 * @param {integer} [canvasWidth={@link CB_Canvas.WIDTH_DEFAULT}] - The desired width (horizontal size) in pixels for the canvas.
416 * @param {integer} [canvasHeight={@link CB_Canvas.HEIGHT_DEFAULT}] - The desired height (vertical size) in pixels for the canvas.
417 * @param {function} [onLoad] - Callback function that will be called when the canvas is finally loaded. It will not receive parameters, being "this" the {@link CB_Canvas} object itself.
418 * @param {function} [onError] - Callback function that will be called when there is an error creating or loading the canvas. Being "this" the {@link CB_Canvas} object itself, the unique parameter received will be a string describing the error (if it could be determined).
419 * @param {string} [alternativeCanvasEmulation={@link CB_Canvas.bestEmulation}()] - Emulation method we want to use in the case that the native [canvas]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas} is not supported or if the "forceEmulation" parameter is set to true. Possible emulation methods: "FLASH", "VML", "DHTML" and "SILVERLIGHT".
420 * @param {boolean} [forceEmulation=false] - If set to true, it will force to use the emulation method defined in the "alternativeCanvasEmulation" parameter (even when this alternative emulation method could be not supported and even when native [canvas]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas} support could be supported).
421 */
422CB_Canvas.prototype.set = function(canvasId, canvasWidth, canvasHeight, onLoad, onError, alternativeCanvasEmulation, forceEmulation)
423{
424 //If not given, sets the default parameters:
425 if (typeof(canvasWidth) === "undefined" || canvasWidth === null || isNaN(canvasWidth)) { canvasWidth = CB_Canvas.WIDTH_DEFAULT; }
426 if (typeof(canvasHeight) === "undefined" || canvasHeight === null || isNaN(canvasHeight)) { canvasHeight = CB_Canvas.HEIGHT_DEFAULT; }
427 if (typeof(alternativeCanvasEmulation) === "undefined" || alternativeCanvasEmulation === null || CB_trim(alternativeCanvasEmulation).toUpperCase() === "AUTO") { alternativeCanvasEmulation = CB_Canvas.bestEmulation(); }
428 alternativeCanvasEmulation = CB_trim(alternativeCanvasEmulation).toUpperCase();
429
430 //Just in case there was a previous onload (action) listener before (used in SLCanvas), we kill it:
431 if (typeof(this.canvas) !== "undefined" &amp;&amp; typeof(this.canvas.action) === "function")
432 {
433 this.canvas.action = function() {};
434 }
435
436 //The canvas is still not ready and it is loading:
437 this._ready = false;
438 this._loading = true;
439
440 //If the element with the ID given exists, just takes it:
441 this.canvas = CB_Elements.id(canvasId);
442
443 //this._mode = "unknown"; //Mode is still unknown (unless we create the element later).
444 this._mode = "NORMAL";
445
446 var needsEmulation = CB_Canvas.needsEmulation();
447
448 //If we are going to use DHTML emulation (forced or needed):
449 if ((needsEmulation || forceEmulation) &amp;&amp; alternativeCanvasEmulation === "DHTML")
450 {
451 //Canbox doesn't work with an existing "canvas" TAG, so we have to destroy it and create a DIV with that id:
452 //CB_Elements.idRemove(canvasId); //Destroys the existing element.
453 if (this.canvas !== null)
454 {
455 //this.canvas.outerHTML = this.canvas.outerHTML.replace(/canvas/g, "div");
456 CB_Elements.idRemove(canvasId);
457 this.canvas = null;
458 }
459
460 //this.canvas = null; //We force to create a new element.
461 }
462
463 //If the element already exists, in determines the emulation mode (if any):
464 if (typeof(this.canvas) !== "undefined" &amp;&amp; this.canvas !== null)
465 {
466 //this._mode = "NORMAL";
467 //If the element is using FlashCanvas (Flash) emulation:
468 //var G_vmlCanvasManager = window.G_vmlCanvasManager || undefined;
469 //if (this.canvas.innerHTML.indexOf("flashcanvas") !== -1) { this._mode = "FLASH"; }
470 //...otherwise, if ExplorerCanvas (VML) is available, the element must be using it:
471 //else if (typeof(G_vmlCanvasManager) !== "undefined") { this._mode = "VML"; }
472 }
473 //...otherwise, it will try to create the element with the ID given:
474 else
475 {
476 //Creates the canvas:
477 var tagName = "canvas"; //By default, the tag name is "canvas".
478 if ((needsEmulation || forceEmulation) &amp;&amp; alternativeCanvasEmulation === "DHTML") { tagName = "div"; } //If we are using DHTML emulation, it is better if the tag name is "div" (to make it work in web clients with canvas support).
479 this.canvas = document.createElement(tagName);
480
481 this.canvas.setAttribute("id", canvasId);
482 this.canvas.innerHTML = "CrossBrowdy canvas not supported! (no emulation)";
483
484 this._parent.appendChild(this.canvas);
485 this.canvas = CB_Elements.id(canvasId);
486 }
487
488 //If we need emulation:
489 if (needsEmulation || forceEmulation)
490 {
491 //If the emulation method is available (it will be only if we need it), we apply it:
492 if (CB_Canvas.supportsEmulationMethod(alternativeCanvasEmulation, false)) //Not being strict.
493 {
494 this._mode = alternativeCanvasEmulation;
495 try { this.canvas.innerHTML = ""; } catch(E) {}
496
497 //If we want to use Flash (FlashCanvas), inits the canvas properly:
498 if (alternativeCanvasEmulation === "FLASH")
499 {
500 this.canvas = FlashCanvas.initElement(this.get());
501 //Provides the canvas context with some methods (in case it needs it):
502 this.prepareContext();
503 }
504 //...otherwise, if we want to use Silverlight (SLCanvas), inits the canvas properly:
505 else if (alternativeCanvasEmulation === "SILVERLIGHT")
506 {
507 var that = this;
508 var functionOnLoad =
509 function(sender)
510 {
511 if (that.isSupported())
512 {
513 that._mode = "SILVERLIGHT";
514 //Provides the canvas context with some methods (in case it needs it):
515 that.prepareContext();
516 //The canvas is ready for use:
517 that._ready = true;
518 that._loading = false;
519 //Calls the onLoad function (if any):
520 if (typeof(onLoad) === "function") { onLoad.call(that); }
521 }
522 else
523 {
524 //Calls the onError function (if any):
525 //if (typeof(onError) === "function") { onLoad.call(this); }
526 if (typeof(onError) === "function") { onError.call(that, "'" + alternativeCanvasEmulation + "' canvas emulation failed."); }
527 }
528 };
529 var SLCanvasDiv = slcanvas.createCanvasDiv(canvasWidth, canvasHeight, functionOnLoad);
530 CB_Elements.idRemove(canvasId);
531 SLCanvasDiv.setAttribute("id", canvasId);
532
533 //IE5/5+, IE6, IE7 and IE8 (I still have to check other newer IE versions) doesn't send keyboard events to the web client when a Silverlight object is clicked. So we have to put a transparent div over it that prevents to click it in order to not focus the Silverlight object:
534 if (CB_Client.supportsSilverlight() &amp;&amp; navigator.userAgent.indexOf('MSIE') !== -1 &amp;&amp; (navigator.appVersion.indexOf("MSIE 5") !== -1 || navigator.appVersion.indexOf("MSIE 6") !== -1 || navigator.appVersion.indexOf("MSIE 7") !== -1 || navigator.appVersion.indexOf("MSIE 8") !== -1))
535 {
536 var SLCanvasDivForeground = document.createElement("div");
537 SLCanvasDivForeground.style.position = "absolute";
538 SLCanvasDivForeground.style.padding = "0px";
539 SLCanvasDivForeground.style.filter = 'alpha(opacity=0)';
540 SLCanvasDivForeground.style.backgroundColor = "#ffffff";
541 SLCanvasDivForeground.style.border = "0px";
542 SLCanvasDivForeground.innerHTML = "";
543
544 //It will always check if the canvas is moved, in order to be always placed above it:
545 setInterval(
546 function()
547 {
548 if (SLCanvasDivForeground !== null &amp;&amp; SLCanvasDiv !== null)
549 {
550 SLCanvasDivForeground.style.top = CB_Elements.getTop(SLCanvasDiv) + "px";
551 SLCanvasDivForeground.style.left = CB_Elements.getLeft(SLCanvasDiv) + "px";
552 SLCanvasDivForeground.style.width = CB_Elements.getWidth(SLCanvasDiv) + "px";
553 SLCanvasDivForeground.style.height = CB_Elements.getHeight(SLCanvasDiv) + "px";
554 var zIndex = SLCanvasDiv.currentStyle.zIndex;
555 if (typeof(zIndex) !== "undefined" &amp;&amp; zIndex !== null &amp;&amp; !isNaN(zIndex)) { zIndex++; }
556 SLCanvasDivForeground.style.zIndex = zIndex;
557 }
558 }, 100);
559
560 document.body.appendChild(SLCanvasDivForeground);
561 }
562
563 //Sets the new canvas:
564 this.canvas = SLCanvasDiv;
565 this._parent.appendChild(this.canvas);
566 }
567 //...otherwise, if we want to use VML (ExplorerCanvas), inits the canvas properly:
568 else if (alternativeCanvasEmulation === "VML")
569 {
570 this.canvas = G_vmlCanvasManager.initElement(this.get());
571
572 //Provides the canvas context with some methods (in case it needs it):
573 this.prepareContext();
574 }
575 //...otherwise, if we want to use DHTML (Canbox), inits the canvas properly:
576 else if (alternativeCanvasEmulation === "DHTML")
577 {
578 //try
579 //{
580 this.canvas = _CanboxManager.initElement(this.get());
581 //} catch(E) {}
582 //Provides the canvas context with some methods (in case it needs it):
583 this.prepareContext();
584 }
585 else
586 {
587 this.canvas.innerHTML = "CrossBrowdy canvas not supported! (with " + alternativeCanvasEmulation + " emulation)";
588 }
589 }
590 else
591 {
592 try { this.canvas.innerHTML = "CrossBrowdy canvas not supported! (without emulation)"; } catch(E) {}
593 if (alternativeCanvasEmulation !== "NONE") { this.canvas.innerHTML += " - tried " + alternativeCanvasEmulation + " but failed"; }
594 }
595 }
596
597 //Defines canvas width and height:
598 this.setWidth(canvasWidth);
599 this.setHeight(canvasHeight);
600
601 //If the canvas is supported (it worked) and we are not using SLCanvas (because it needs time to be ready):
602 if (this.isSupported())
603 {
604 //The canvas is ready and not loading anymore:
605 this._ready = true;
606 this._loading = false;
607 //Calls the onLoad function (if any):
608 if (typeof(onLoad) === "function") { onLoad.call(this); }
609 }
610 //...otherwise, if we didn't used the Silverlight emulation method (SLCanvas):
611 else if (alternativeCanvasEmulation !== "SILVERLIGHT")
612 {
613 //If we are here it means that canvas is not supported and it is not loading anymore:
614 this._loading = false;
615 //Calls the onError function (if any):
616 //if (typeof(onError) === "function") { onLoad.call(this); }
617 if (typeof(onError) === "function") { onError.call(this, "'" + alternativeCanvasEmulation + "' canvas emulation failed!"); }
618 }
619}
620
621
622
623/**
624 * Alias for {@link CB_Canvas#prepareContext}.
625 * @function CB_Canvas.prototype.normalizeContext
626 * @see {@link CB_Canvas#prepareContext}
627 */
628/**
629 * Provides the canvas [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} with some methods and properties, in case it needs it (as some canvas emulation methods lack of some methods and properties). Since this method is called by the {@link CB_Canvas#set} method already (and this one is called by the constructor automatically), it is not needed to be called again normally.
630 * @function
631 * @param {RenderingContext|Object} [context={@link CB_Canvas#getContext}()] - The [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} object that we want to prepare (different type if a canvas emulation method is being used). If not defined, calls the {@link CB_Canvas#getContext} method internally.
632 * @returns {RenderingContext|Object} Returns the canvas [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} (different type if a canvas emulation method is being used).
633 * @todo Add more methods and properties needed by some emulation methods.
634 */
635CB_Canvas.prototype.prepareContext = CB_Canvas.prototype.normalizeContext = function(context)
636{
637 //Gets the context:
638 if (typeof(context) === "undefined" || context === null) { context = this.getContext(); }
639
640 //If the context is not defined or null, exits the function:
641 if (typeof(context) === "undefined" || context === null) { return; }
642
643 //Canbox doesn't support setTransform, so we create a fake function in order not to crash:
644 try
645 {
646 if (typeof(context.setTransform) === "undefined")
647 {
648 context.setTransform = function() {}
649 }
650 } catch(E) { CB_console("The 'setTransform' method could not be added to the given canvas context."); }
651
652 try
653 {
654 //SLCanvas doesn't support font, so we create a fake function in order not to crash:
655 if (typeof(context.font) === "undefined")
656 {
657 context.font = "10px sans-serif";
658 }
659 } catch(E) { CB_console("The 'font' property could not be added to the given canvas context."); }
660
661 try
662 {
663 //SLCanvas doesn't support fillText, so we create a fake function in order not to crash:
664 if (typeof(context.fillText) === "undefined")
665 {
666 context.fillText = function() {}
667 }
668 } catch(E) { CB_console("The 'fillText' method could not be added to the given canvas context."); }
669
670 try
671 {
672 //Internet Explorer 11 (and lower) does not support "ellipse" method, so we try to simulate it:
673 if (typeof(context.drawEllipse) === "undefined")
674 {
675 context.drawEllipse = this._context_drawEllipse;
676 }
677 } catch(E) { CB_console("The 'ellipse' method could not be added to the given canvas context."); }
678
679 return context;
680}
681
682
683/**
684 * Returns the canvas element (if any).
685 * @function
686 * @returns {Element|null} Returns the canvas element (if any). If not found, null will be returned.
687 */
688CB_Canvas.prototype.get = function()
689{
690 return this.canvas || null;
691}
692
693
694 /**
695 * Defines and returns the canvas [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext}. It could call the {@link CB_Canvas#prepareContext} method internally.
696 * @function
697 * @param {('2d'|'webgl'|'experimental-webgl'|'webgl2'|'experimental-webgl2'|'bitmaprenderer')} [contextType=CB_Canvas#._contextType|'2d'] - The [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} type desired. More information: [HTMLCanvasElement.getContext]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext}. Note that most emulation methods will only support "2d".
698 * @returns {RenderingContext|Object} Returns the canvas [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} (different type if a canvas emulation method is being used).
699 */
700CB_Canvas.prototype.getContext = function(contextType)
701{
702 //Defines 2D if any other context type has defined:
703 if (typeof(contextType) === "undefined" || contextType === null)
704 {
705 contextType = this._contextType;
706 if (typeof(contextType) === "undefined" || contextType === null)
707 {
708 contextType = "2d";
709 }
710 }
711
712 contextType = CB_trim(contextType).toLowerCase();
713
714 //If the context type inserted is not allowed, uses the "2d" type by default:
715 //if (contextType === "" || contextType !== "webgl" &amp;&amp; contextType !== "2d")
716 if (CB_indexOf(CB_Canvas.prototype._allowedContextTypes, contextType) === -1) { contextType = "2d"; }
717
718 if (typeof(this.get().getContext) === "function")
719 {
720 try //Uses try-catch to avoid some problems with some web clients (as BeZilla / Bon Echo 2.0.0.22Pre on Haiku OS):
721 {
722 return this.context = this.prepareContext(this.get().getContext(contextType));
723 //////////////return this.context = this.get().getContext(contextType);
724 } catch(E) { return this.context = null; }
725 }
726 else { return this.context = null; }
727}
728
729
730/**
731 * Defines the desired canvas [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} type. Internally, it only defines the {@link CB_Canvas#._contextType} property.
732 * @function
733 * @param {('2d'|'webgl'|'experimental-webgl'|'webgl2'|'experimental-webgl2'|'bitmaprenderer')} [contextType='2d'] - The [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} type desired. More information: [HTMLCanvasElement.getContext]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext}. Note that most emulation methods will only support "2d".
734 * @returns {string} Returns the context type just applied.
735 */
736CB_Canvas.prototype.setContextType = function(contextType)
737{
738 contextType = CB_trim(contextType).toLowerCase();
739
740 //If the context type inserted is not allowed, uses the "2d" type by default:
741 if (CB_indexOf(CB_Canvas.prototype._allowedContextTypes, contextType) === -1) { contextType = "2d"; }
742
743 this._contextType = contextType;
744
745 return this._contextType;
746}
747
748
749 /**
750 * Tells the current canvas [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} type used. Internally, it returns the value of the {@link CB_Canvas#._contextType} property.
751 * @function
752 * @returns {string} Tells the current canvas [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} type used. More information: [HTMLCanvasElement.getContext]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext}.
753 */
754CB_Canvas.prototype.getContextType = function()
755{
756 return this._contextType;
757}
758
759
760/**
761 * Tells whether the canvas works or not. The internal test used could be not totally reliable.
762 * @function
763 * @returns {boolean} Returns whether the canvas works or not. The internal test used could be not totally reliable.
764 */
765CB_Canvas.prototype.isSupported = function()
766{
767 //this._supported = (this.canvas &amp;&amp; this.canvas.getContext) ? true : false;
768 //return this._supported;
769
770 if (this.canvas &amp;&amp; this.canvas.getContext)
771 {
772 try //Uses try-catch to avoid some problems with some web clients (as BeZilla / Bon Echo 2.0.0.22Pre on Haiku OS):
773 {
774 this._supported = (typeof(this.canvas.getContext("2d")) !== "undefined" &amp;&amp; this.canvas.getContext("2d") !== null);
775 } catch(E) { this._supported = false; }
776 }
777 return this._supported || false;
778}
779
780
781/**
782 * Defines the desired canvas width.
783 * @function
784 * @param {integer} [canvasWidth={@link CB_Canvas.WIDTH_DEFAULT}] - The desired width (horizontal size) in pixels for the canvas.
785 * @returns {number} Returns the canvas width (horizontal size) being used in pixels. It could return zero (0) if cannot be calculated.
786 */
787CB_Canvas.prototype.setWidth = function(canvasWidth)
788{
789 //Is not defined or it is wrong, uses default size:
790 if (typeof(canvasWidth) === "undefined" || canvasWidth === null || isNaN(canvasWidth))
791 {
792 canvasWidth = CB_Canvas.WIDTH_DEFAULT;
793 }
794
795 //Detects if a percentage has been received:
796 /*
797 canvasWidth = canvasWidth.toString();
798 var isPercentage = false;
799 if (canvasWidth.indexOf("%") !== -1) { isPercentage = true; }
800 canvasWidth = canvasWidth.replace("%", "");
801 canvasWidth = canvasWidth.replace("px", "");
802 */
803
804 //Applies changes to the canvas:
805 var canvas = this.get();
806 if (typeof(canvas) !== "undefined" &amp;&amp; canvas !== null)
807 {
808 //this._width = canvasWidth + (isPercentage ? "%" : "");
809 this._width = canvasWidth;
810 //this.get().style.width = this._width + (isPercentage ? "%" : "px");
811 canvas.style.width = canvasWidth + "px";
812 canvas.setAttribute('width', canvasWidth);
813 //this.get().setAttribute('width', canvasWidth);
814 }
815
816 return this.getWidth();
817}
818
819
820/**
821 * Tells the canvas width (horizontal size) being used in pixels.
822 * @function
823 * @returns {number} Returns the canvas width (horizontal size) being used in pixels. It could return zero (0) if cannot be calculated.
824 */
825CB_Canvas.prototype.getWidth = function()
826{
827 return this._width || 0;
828}
829
830
831/**
832 * Defines the desired canvas height.
833 * @function
834 * @param {integer} [canvasHeight={@link CB_Canvas.HEIGHT_DEFAULT}] - The desired height (vertical size) in pixels for the canvas.
835 * @returns {number} Returns the canvas height (vertical size) being used in pixels. It could return zero (0) if cannot be calculated.
836 */
837CB_Canvas.prototype.setHeight = function(canvasHeight)
838{
839 //Is not defined or it is wrong, uses default size:
840 if (typeof(canvasHeight) === "undefined" || canvasHeight === null || isNaN(canvasHeight))
841 {
842 canvasHeight = CB_Canvas.HEIGHT_DEFAULT;
843 }
844
845 //Detects if a percentage has been received:
846 /*
847 canvasHeight = canvasHeight.toString();
848 var isPercentage = false;
849 if (canvasHeight.indexOf("%") !== -1) { isPercentage = true; }
850 canvasHeight = canvasHeight.replace("%", "");
851 canvasHeight = canvasHeight.replace("px", "");
852 */
853
854 //Applies changes to the canvas:
855 var canvas = this.get();
856 if (typeof(canvas) !== "undefined" &amp;&amp; canvas !== null)
857 {
858 //this._height = canvasHeight.toString() + (isPercentage ? "%" : "");
859 this._height = canvasHeight;
860 //this.get().style.height = this._height + (isPercentage ? "%" : "px");
861 canvas.style.height = canvasHeight + "px";
862 canvas.setAttribute('height', canvasHeight);
863 //this.get().setAttribute('height', this._height);
864 }
865
866 return this.getHeight();
867}
868
869
870/**
871 * Tells the canvas height (vertical size) being used in pixels.
872 * @function
873 * @returns {number} Returns the canvas height (vertical size) being used in pixels. It could return zero (0) if cannot be calculated.
874 */
875CB_Canvas.prototype.getHeight = function()
876{
877 return this._height || 0;
878}
879
880
881/**
882 * Tells the mode used to create the canvas.
883 * @function
884 * @returns {'NONE'|'NORMAL'|'FLASH'|'SILVERLIGHT'|'VML'|'DHTML'} Returns the mode used to create the canvas. Returns "NONE" if no method is used yet (possible when no method is supported at all or when it is still loading). Returns "NORMAL" if native [canvas]{@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas} is used (no canvas emulation method).
885 */
886CB_Canvas.prototype.getMode = function()
887{
888 return this._mode || "NONE";
889}
890
891
892/**
893 * Tells whether the canvas is ready to be used or not. Some canvas emulation methods can take some time until they are ready to be used.
894 * @function
895 * @returns {boolean} Returns whether the canvas is ready to be used or not.
896 */
897CB_Canvas.prototype.isReady = function()
898{
899 return this._ready;
900}
901
902
903/**
904 * Tells whether the canvas is loading or not. Some canvas emulation methods can take some time until they finish loading.
905 * @function
906 * @returns {boolean} Returns whether the canvas is loading or not.
907 */
908CB_Canvas.prototype.isLoading = function()
909{
910 return this._loading;
911}
912
913
914/**
915 * Alias for {@link CB_Canvas#clear}.
916 * @function CB_Canvas.prototype.clearCanvas
917 * @see {@link CB_Canvas#clear}
918 */
919/**
920 * Clear the canvas entirely.
921 * @function
922 * @param {boolean} [keepTransform=false] - If set to true, it will [save]{@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save} and [restore]{@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore} the current transformation.
923 * @param {string} [backgroundFillStyle] - The style used (color, gradient, pattern...) to fill the canvas background. If defined, it will be used as the value for the [fillStyle]{@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle} property of the [context]{@link https://developer.mozilla.org/en-US/docs/Web/API/RenderingContext} object, internally.
924 * @returns {boolean} Returns true if the action could be performed or false otherwise.
925 */
926CB_Canvas.prototype.clear = CB_Canvas.prototype.clearCanvas = function(keepTransform, backgroundFillStyle)
927{
928 //Gets the context:
929 var context = this.getContext();
930
931 //If the context is not defined or null, exits the function:
932 if (typeof(context) === "undefined" || context === null) { return false; }
933
934 //If defined, saves the current transform:
935 if (keepTransform)
936 {
937 context.save();
938 context.setTransform(1, 0, 0, 1, 0, 0);
939 }
940
941 //this.get().width = this.get().width + 1; //+1 for WebKit compatibility.
942 //this.get().width = this.get().width;
943
944 context.clearRect(0, 0, this.getWidth(), this.getHeight());
945
946 if (typeof(backgroundFillStyle) !== "undefined" &amp;&amp; backgroundFillStyle !== null)
947 {
948 context.globalAlpha = 1;
949 context.fillStyle = backgroundFillStyle;
950 context.fillRect(0, 0, this.getWidth(), this.getHeight());
951 }
952 /*
953 else
954 {
955 context.clearRect(0, 0, this.getWidth(), this.getHeight());
956 }
957 */
958
959 //If defined, restores the transform:
960 if (keepTransform)
961 {
962 context.restore();
963 }
964
965 return true;
966}
967
968
969/**
970 * Disables anti-aliasing. Useful to work with image sprites (to avoid problems showing adjacent ones), for example.
971 * @function
972 * @param {boolean} [performTranslate=false] - If set to true, it will also call the [transform]{@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/transform} method.
973 * @returns {boolean} Returns true if the action could be performed or false otherwise.
974 */
975CB_Canvas.prototype.disableAntiAliasing = function(performTranslate)
976{
977 //Gets the context:
978 var context = this.getContext();
979
980 //If the context is not defined or null, exits the function:
981 if (typeof(context) === "undefined" || context === null) { return false; }
982
983 if (performTranslate) { context.translate(0.5, 0.5); /*context.lineWidth = 0.5;*/ }
984 context.khtmlImageSmoothingEnabled = false;
985 context.oImageSmoothingEnabled = false;
986 context.msImageSmoothingEnabled = false;
987 context.webkitImageSmoothingEnabled = false;
988 context.mozImageSmoothingEnabled = false;
989 context.imageSmoothingEnabled = false;
990
991 return true;
992}
993
994
995//Internet Explorer 11 (and lower) does not support "ellipse" method, so we try to simulate it:
996//* Solution by Steve Tranby. Source: https://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas/2173084#2173084
997//TODO: Add parameters and modify their order to mimic (polyfill) the native ellipse function (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/ellipse).
998CB_Canvas.prototype._context_drawEllipse = function drawEllipse(x, y, w, h) //NOTE: must be called being "this" the canvas context desired.
999{
1000 var kappa = .5522848;
1001 var ox = (w / 2) * kappa; //Control point offset horizontal.
1002 var oy = (h / 2) * kappa; //Control point offset vertical.
1003 var xe = x + w; //x-end.
1004 var ye = y + h; //y-end.
1005 var xm = x + w / 2; //x-middle.
1006 var ym = y + h / 2; //y-middle.
1007
1008 this.beginPath();
1009 this.moveTo(x, ym);
1010 this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
1011 this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
1012 this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
1013 this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
1014 //this.closePath(); // not used correctly, see comments (use to close off open path)
1015 //this.stroke();
1016};
1017
1018//CB_CanvasFileLoaded = true; //This file has been loaded.
1019//CB_filesNeeded["screen/canvas/CB_Canvas.js"] = true; //This file has been loaded.</pre>
1020 </article>
1021</section>
1022
1023
1024
1025
1026
1027 </div>
1028 </div>
1029
1030 <div class="clearfix"></div>
1031
1032
1033
1034</div>
1035</div>
1036
1037
1038 <div class="modal fade" id="searchResults">
1039 <div class="modal-dialog">
1040 <div class="modal-content">
1041 <div class="modal-header">
1042 <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1043 <h4 class="modal-title">Search results</h4>
1044 </div>
1045 <div class="modal-body"></div>
1046 <div class="modal-footer">
1047 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1048 </div>
1049 </div><!-- /.modal-content -->
1050 </div><!-- /.modal-dialog -->
1051 </div>
1052
1053
1054<footer>
1055
1056
1057 <span class="copyright">
1058 <a href="printable/" target="_blank">See a more printer-friendly version</a><hr /><span style="color:#000000">© <address style="display:inline; font-style:normal;"><a href="https://crossbrowdy.com/" target="_blank">CrossBrowdy</a> API documentation</address> by <a href="https://joanalbamaldonado.com/" target="_blank">Joan Alba Maldonado</a> - <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">Creative Commons Attribution 4.0 International</a><br />DocStrap Copyright © 2012-2015 The contributors to the JSDoc3 and DocStrap projects.</span>
1059 </span>
1060
1061<span class="jsdoc-message">
1062 Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a>
1063
1064 on Mon Feb 3rd 2020
1065
1066 using the <a href="https://github.com/docstrap/docstrap">DocStrap template</a>.
1067</span>
1068</footer>
1069
1070<script src="scripts/docstrap.lib.js"></script>
1071<script src="scripts/toc.js"></script>
1072
1073 <script type="text/javascript" src="scripts/fulltext-search-ui.js"></script>
1074
1075
1076<script>
1077$( function () {
1078 $( "[id*='$']" ).each( function () {
1079 var $this = $( this );
1080
1081 $this.attr( "id", $this.attr( "id" ).replace( "$", "__" ) );
1082 } );
1083
1084 $( ".tutorial-section pre, .readme-section pre, pre.prettyprint.source" ).each( function () {
1085 var $this = $( this );
1086
1087 var example = $this.find( "code" );
1088 exampleText = example.html();
1089 var lang = /{@lang (.*?)}/.exec( exampleText );
1090 if ( lang && lang[1] ) {
1091 exampleText = exampleText.replace( lang[0], "" );
1092 example.html( exampleText );
1093 lang = lang[1];
1094 } else {
1095 var langClassMatch = example.parent()[0].className.match(/lang\-(\S+)/);
1096 lang = langClassMatch ? langClassMatch[1] : "javascript";
1097 }
1098
1099 if ( lang ) {
1100
1101 $this
1102 .addClass( "sunlight-highlight-" + lang )
1103 .addClass( "linenums" )
1104 .html( example.html() );
1105
1106 }
1107 } );
1108
1109 Sunlight.highlightAll( {
1110 lineNumbers : true,
1111 showMenu : true,
1112 enableDoclinks : true
1113 } );
1114
1115 $.catchAnchorLinks( {
1116 navbarOffset: 10
1117 } );
1118 $( "#toc" ).toc( {
1119 anchorName : function ( i, heading, prefix ) {
1120 return $( heading ).attr( "id" ) || ( prefix + i );
1121 },
1122 selectors : "#toc-content h1,#toc-content h2,#toc-content h3,#toc-content h4",
1123 showAndHide : false,
1124 smoothScrolling: true
1125 } );
1126
1127 $( "#main span[id^='toc']" ).addClass( "toc-shim" );
1128 $( '.dropdown-toggle' ).dropdown();
1129
1130 $( "table" ).each( function () {
1131 var $this = $( this );
1132 $this.addClass('table');
1133 } );
1134
1135} );
1136</script>
1137
1138
1139
1140<!--Navigation and Symbol Display-->
1141
1142<script>
1143 $( function () {
1144 $( '#main' ).localScroll( {
1145 offset : { top : 60 } //offset by the height of your header (give or take a few px, see what works for you)
1146 } );
1147 $( "dt.name" ).each( function () {
1148 var $this = $( this ).find("h4");
1149 var icon = $( "<i/>" ).addClass( "icon-plus-sign" ).addClass( "pull-right" ).addClass( "icon-white" );
1150 var dt = $(this);
1151 var children = dt.next( "dd" );
1152
1153 dt.prepend( icon ).css( {cursor : "pointer"} );
1154 dt.addClass( "member-collapsed" ).addClass( "member" );
1155
1156
1157 children.hide();
1158
1159 dt.children().on( "click", function () {
1160 children = dt.next( "dd" );
1161 children.slideToggle( "fast", function () {
1162
1163 if ( children.is( ":visible" ) ) {
1164 icon.addClass( "icon-minus-sign" ).removeClass( "icon-plus-sign" ).removeClass( "icon-white" );
1165 dt.addClass( "member-open" ).animate( "member-collapsed" );
1166 } else {
1167 icon.addClass( "icon-plus-sign" ).removeClass( "icon-minus-sign" ).addClass( "icon-white" );
1168 dt.addClass( "member-collapsed" ).removeClass( "member-open" );
1169 }
1170 } );
1171 } );
1172
1173 } );
1174 } );
1175</script>
1176
1177
1178<!--Google Analytics-->
1179
1180
1181
1182 <script type="text/javascript">
1183 $(document).ready(function() {
1184 SearcherDisplay.init();
1185 });
1186 </script>
1187
1188
1189</body>
1190</html>