1 /* 2 * Copyright 2010 Scriptoid s.r.l 3 */ 4 5 /** 6 * A simple way of setting the style for a context 7 * 8 * @this {Style} 9 * @constructor 10 * @author Zack Newsham <zack_newsham@yahoo.co.uk> 11 * @author Alex Gheorghiu <alex@scriptoid.com> 12 */ 13 function Style(){ 14 /**Font used*/ 15 this.font = null; 16 17 /**Stroke/pen style*/ 18 this.strokeStyle = null; 19 20 /**Fill style*/ 21 this.fillStyle = null 22 23 /**Alpha/transparency value*/ 24 this.globalAlpha = null; 25 26 /**Composite value*/ 27 this.globalCompositeOperation = null; 28 29 /**Line width*/ 30 this.lineWidth = null; 31 32 /** 33 *Line cap style 34 * 35 *HTML5 Canvas: 36 *The (Canvas's) lineCap property determines how the end points of every line are drawn. 37 *There are three possible values for this property and those are: butt, round and square. 38 *By default this property is set to butt. 39 *@see https://developer.mozilla.org/en/Canvas_tutorial/Applying_styles_and_colors#A_lineCap_example 40 **/ 41 this.lineCap = this.STYLE_LINE_CAP_BUTT; 42 43 /** 44 *Line join style 45 * 46 *HTML5 Canvas: 47 *The (Canvas's) lineJoin property determines how two connecting lines in a shape are joined together. 48 *There are three possible values for this property: round, bevel and miter. 49 *By default this property is set to miter. 50 *@see https://developer.mozilla.org/en/Canvas_tutorial/Applying_styles_and_colors#A_lineJoin_example 51 **/ 52 this.lineJoin = this.STYLE_LINE_JOIN_MITER; 53 54 /**Shadow offset x. Not used yet*/ 55 this.shadowOffsetX = null; 56 57 /**Shadow offset y. Not used yet*/ 58 this.shadowOffsetY = null; 59 60 /**Shadow blur. Not used yet*/ 61 this.shadowBlur = null; 62 63 /**Shadow color. Not used yet*/ 64 this.shadowColor = null; 65 66 /**An {Array} of colors used in gradients*/ 67 this.addColorStop = []; 68 69 /**An {Array} used in gradients*/ 70 this.linearGradient = []; 71 72 /**Dash length used for dashed styles*/ 73 this.dashLength = 0; 74 75 /**Image used*/ 76 this.image = null; 77 78 /**Serialization type*/ 79 this.oType = "Style"; 80 } 81 82 /**Loads a style from a JSONObject 83 **/ 84 Style.load = function(o){ 85 var newStyle = new Style(); 86 87 newStyle.strokeStyle = o.strokeStyle; 88 newStyle.fillStyle = o.fillStyle 89 newStyle.globalAlpha = o.globalAlpha; 90 newStyle.globalCompositeOperation = o.globalCompositeOperation; 91 newStyle.lineWidth = o.lineWidth; 92 newStyle.lineCap = o.lineCap; 93 newStyle.lineJoin = o.lineJoin; 94 newStyle.shadowOffsetX = o.shadowOffsetX; 95 newStyle.shadowOffsetY = o.shadowOffsetY; 96 newStyle.shadowBlur = o.shadowBlur; 97 newStyle.shadowColor = o.shadowColor; 98 newStyle.addColorStop = o.addColorStop; 99 newStyle.linearGradient = o.linearGradient; 100 newStyle.dashLength = o.dashLength; 101 newStyle.image = o.image; 102 103 return newStyle; 104 } 105 106 Style.prototype={ 107 /**Round join*/ 108 STYLE_LINE_JOIN_ROUND: 'round', 109 110 /**Bevel join*/ 111 STYLE_LINE_JOIN_BEVEL: 'bevel', 112 113 /**Mitter join*/ 114 STYLE_LINE_JOIN_MITER: 'miter', 115 116 /**Butt cap*/ 117 STYLE_LINE_CAP_BUTT: 'butt', 118 119 /**Round cap*/ 120 STYLE_LINE_CAP_ROUND: 'round', 121 122 /**Square cap*/ 123 STYLE_LINE_CAP_SQUARE: 'square', 124 125 /**Setup the style of a context 126 *@param {Context} context - the canvas context 127 **/ 128 setupContext:function(context){ 129 for(var propertyName in this){ 130 if(propertyName != "linearGradient" && propertyName != "addColorStop" && propertyName != "image"){ 131 if(this[propertyName] != null && propertyName != undefined){ 132 context[propertyName] = this[propertyName]; 133 } 134 } 135 } 136 137 if(this.linearGradient.length !=0 && image == null){ 138 var lin = context.createLinearGradient(this.linearGradient[0], this.linearGradient[1], this.linearGradient[2], this.linearGradient[3]); 139 140 for(var i=0; i<this.addColorStop.length; i++){ 141 lin.addColorStop(i, this.addColorStop[i]); 142 } 143 144 context.fillStyle = lin; 145 this.fillStyle = lin; 146 } 147 148 if(this.image != null && IE){ 149 var ptrn = context.createPattern(this.image,'no-repeat'); 150 //context.fillStyle=ptrn; 151 //this.fillStyle=ptrn; 152 } 153 }, 154 155 156 clone: function(){ 157 var anotherStyle = new Style; 158 for(var propertyName in anotherStyle){ 159 if(propertyName!="addColorStop" && propertyName!="linearGradient"){ 160 anotherStyle[propertyName]=this[propertyName]; 161 } 162 else{ 163 for(var i=0; i< this[propertyName].length; i++){ 164 anotherStyle[propertyName].push(this[propertyName][i]); 165 } 166 } 167 } 168 return anotherStyle; 169 }, 170 171 172 /**Try not to save the properties that are null 173 *The deleted property will be recreated and set to null while .load() method anyway 174 *@author Alex 175 **/ 176 toJSON : function(){ 177 var aClone = this.clone(); 178 for(var propertyName in aClone){ 179 if(aClone[propertyName] == null){ 180 delete aClone[propertyName]; 181 } 182 } 183 184 return aClone; 185 }, 186 187 188 getGradient:function(){ 189 return this.addColorStop[0]+"/"+this.addColorStop[1]; 190 }, 191 192 193 setGradient:function(figure, value){ 194 this.addColorStop[0] = value.split("/")[0]; 195 this.addColorStop[1] = value.split("/")[1]; 196 }, 197 198 /**Merge current style with another style. 199 *If current style is missing some of other's feature it will be "enhanced" with them 200 *@param {Style} anotherStyle - the other style 201 *@author Zack Newsham <zack_newsham@yahoo.co.uk> 202 *@author Alex <alex@scriptoid.com> 203 **/ 204 merge:function(anotherStyle){ 205 for(var propertyName in anotherStyle){ 206 if( (this[propertyName] == null || this[propertyName] == undefined) && propertyName != "image"){ 207 this[propertyName] = anotherStyle[propertyName]; 208 } 209 } 210 }, 211 212 213 transform:function(matrix){ 214 if(this.linearGradient.length!=0){ 215 var p1=new Point(this.linearGradient[0],this.linearGradient[1]); 216 var p2=new Point(this.linearGradient[2],this.linearGradient[3]); 217 p1.transform(matrix); 218 p2.transform(matrix); 219 this.linearGradient[0]=p1.x; 220 this.linearGradient[1]=p1.y; 221 this.linearGradient[2]=p2.x; 222 this.linearGradient[3]=p2.y; 223 } 224 if(this.image){ 225 var p1 = new Point(0,0); 226 var p2 = new Point(this.image.width, this.image.height); 227 p1.transform(matrix); 228 p2.transform(matrix); 229 this.image.width = p2.x-p1.x; 230 this.image.height = p2.y-p1.y; 231 } 232 }, 233 234 235 /**TODO: implement it*/ 236 equals:function(anotherStyle){ 237 if(!anotherStyle instanceof Style){ 238 return false; 239 } 240 241 //TODO: test members 242 243 return true; 244 }, 245 246 247 /**Transform all the style into a SVG style 248 *@author Alex Gheorghiu <alex@scriptoid.com> 249 **/ 250 toSVG : function(){ 251 var style = ' style="'; 252 253 style += 'stroke:' + ( (this.strokeStyle == null || this.strokeStyle == '') ? 'none' : this.strokeStyle) + ';'; 254 style += 'fill:' + ( (this.fillStyle == null || this.fillStyle == '') ? 'none' : this.fillStyle) + ';'; 255 style += 'stroke-width:' + ( (this.lineWidth == null || this.lineWidth == '') ? 'none' : this.lineWidth) + ';'; 256 style += 'stroke-linecap:' + ( (this.lineCap == null || this.lineCap == '') ? 'inherit' : this.lineCap) + ';'; 257 style += 'stroke-linejoin:' + ( (this.lineJoin == null || this.lineJoin == '') ? 'inherit' : this.lineJoin) + ';'; 258 style += '" '; 259 260 return style; 261 } 262 263 } 264 265