| 1 |
/* |
| 2 |
canvas.js: Canvas utilities |
| 3 |
|
| 4 |
iSlideMaker |
| 5 |
http://sourceforge.jp/projects/islidemaker/simple/ |
| 6 |
|
| 7 |
Copyright(c) 2010, Isao Hara, isao-hara@users.sourceforge.jp |
| 8 |
|
| 9 |
All rights reserved. This program is made available under the terms of the |
| 10 |
Eclipse Public License v1.0 which accompanies this distribution, and is |
| 11 |
available at http://www.eclipse.org/legal/epl-v10.html |
| 12 |
|
| 13 |
Contributors: Isao Hara. |
| 14 |
|
| 15 |
*/ |
| 16 |
//////// SVG compatible canvas functions |
| 17 |
function drawString(){ |
| 18 |
var x = document.getElementById('toString'); |
| 19 |
var aa = document.getElementById('slide1'); |
| 20 |
if(aa) x.innerHTML = aa.toString(); |
| 21 |
} |
| 22 |
|
| 23 |
function drawCanvas(element){ |
| 24 |
var canvasEle = element.getElementsByTagName("canvas"); |
| 25 |
for (var i = 0; i< canvasEle.length; i++) { |
| 26 |
draw(canvasEle[i]); |
| 27 |
} |
| 28 |
} |
| 29 |
|
| 30 |
function draw(canvas){ |
| 31 |
if(!canvas.hasChildNodes()) return false; |
| 32 |
if(!canvas || !canvas.getContext){ return false; } |
| 33 |
var ctx = canvas.getContext('2d'); |
| 34 |
var ele = canvas.childNodes; |
| 35 |
drawAll(ctx, ele); |
| 36 |
} |
| 37 |
|
| 38 |
function drawAll(ctx, ele){ |
| 39 |
for(var i=0 ; i<ele.length; i++){ |
| 40 |
var tName = ele[i].tagName; |
| 41 |
if(!tName) continue; |
| 42 |
|
| 43 |
var color = ele[i].getAttribute("stroke"); |
| 44 |
var fill = ele[i].getAttribute("fill"); |
| 45 |
var width = ele[i].getAttribute("stroke-width"); |
| 46 |
|
| 47 |
switch(tName){ |
| 48 |
case 'TEXT': |
| 49 |
var x = ele[i].getAttribute("x"); |
| 50 |
var y = ele[i].getAttribute("y"); |
| 51 |
var f_family = ele[i].getAttribute("font-family"); |
| 52 |
var f_size = ele[i].getAttribute("font-size"); |
| 53 |
var f_style = ele[i].getAttribute("font-style"); |
| 54 |
var txt = ele[i].textContent; |
| 55 |
|
| 56 |
ctx.beginPath(); |
| 57 |
if(!f_size) f_size = '12pt'; |
| 58 |
if(!f_family) f_family = 'Helvetica'; |
| 59 |
if(!f_style) f_style = ''; |
| 60 |
|
| 61 |
ctx.fillStyle = color; |
| 62 |
ctx.font = f_style + " " + f_size+"pt" + " '"+f_family + "'"; |
| 63 |
ctx.fillText( txt, x, y); |
| 64 |
ctx.closePath(); |
| 65 |
|
| 66 |
break; |
| 67 |
case 'POLYLINE': |
| 68 |
var points = ele[i].getAttribute("points"); |
| 69 |
polyline(ctx, points, color, fill, width, false); |
| 70 |
break; |
| 71 |
|
| 72 |
case 'POLYGON': |
| 73 |
var points = ele[i].getAttribute("points"); |
| 74 |
polyline(ctx, points, color, fill, width, true); |
| 75 |
break; |
| 76 |
|
| 77 |
case 'LINE': |
| 78 |
var points = ele[i].getAttribute("x1"); |
| 79 |
points += ',' + ele[i].getAttribute("y1"); |
| 80 |
points += ' ' + ele[i].getAttribute("x2"); |
| 81 |
points += ',' + ele[i].getAttribute("y2"); |
| 82 |
polyline(ctx, points, color, 'none', width, false); |
| 83 |
break; |
| 84 |
|
| 85 |
case 'IMG': |
| 86 |
var iname = ele[i].getAttribute("xlink:href"); |
| 87 |
var x = ele[i].getAttribute("x"); |
| 88 |
var y = ele[i].getAttribute("y"); |
| 89 |
var w = ele[i].getAttribute("width"); |
| 90 |
var h = ele[i].getAttribute("height"); |
| 91 |
if(!x) x=0; |
| 92 |
if(!y) y=0; |
| 93 |
if(!w) w=-1; |
| 94 |
if(!h) h=-1; |
| 95 |
svg_image(ctx, iname, x, y, w, h); |
| 96 |
break; |
| 97 |
|
| 98 |
case 'PATH': |
| 99 |
var d = ele[i].getAttribute("d"); |
| 100 |
var path = d.split(' '); |
| 101 |
var cmd = path.shift(); |
| 102 |
var pp; |
| 103 |
var p; |
| 104 |
|
| 105 |
ctx.beginPath(); |
| 106 |
if(color)ctx.strokeStyle = color; |
| 107 |
if(width) ctx.lineWidth = width; |
| 108 |
|
| 109 |
while(path.length > 0){ |
| 110 |
pp = path.shift(); |
| 111 |
p=pp.split(','); |
| 112 |
|
| 113 |
if(p.length == 1){ |
| 114 |
cmd=p[0]; |
| 115 |
if(cmd == "Z" || cmd == "z"){ |
| 116 |
ctx.stroke(); |
| 117 |
} |
| 118 |
continue; |
| 119 |
} |
| 120 |
|
| 121 |
if(cmd == "Z" || cmd == "z"){ |
| 122 |
ctx.stroke(); |
| 123 |
}else if (cmd == "M"){ |
| 124 |
ctx.moveTo(p[0], p[1]); |
| 125 |
}else if (cmd == "m"){ |
| 126 |
}else if (cmd == "L"){ |
| 127 |
ctx.lineTo(p[0], p[1]); |
| 128 |
}else if (cmd == "l"){ |
| 129 |
|
| 130 |
}else if (cmd == "H"){ |
| 131 |
|
| 132 |
}else if (cmd == "h"){ |
| 133 |
|
| 134 |
}else if (cmd == "V"){ |
| 135 |
|
| 136 |
}else if (cmd == "v"){ |
| 137 |
|
| 138 |
}else if (cmd == "C"){ |
| 139 |
var pp2 = path.shift(); |
| 140 |
var p2=pp2.split(','); |
| 141 |
if(p2.length == 1){ |
| 142 |
cmd=p2[0]; |
| 143 |
continue; |
| 144 |
} |
| 145 |
|
| 146 |
var pp3 = path.shift(); |
| 147 |
var p3=pp3.split(','); |
| 148 |
if(p3.length == 1){ |
| 149 |
cmd=p3[0]; |
| 150 |
continue; |
| 151 |
} |
| 152 |
ctx.bezierCurveTo(p[0], p[1], p2[0], p2[1], p3[0], p3[1]); |
| 153 |
|
| 154 |
}else if (cmd == "c"){ |
| 155 |
}else if (cmd == "S"){ |
| 156 |
}else if (cmd == "s"){ |
| 157 |
}else if (cmd == "Q"){ |
| 158 |
var pp2 = path.shift(); |
| 159 |
var p2=pp2.split(','); |
| 160 |
if(p2.length == 1){ |
| 161 |
cmd=p2[0]; |
| 162 |
continue; |
| 163 |
}else{ |
| 164 |
ctx.quadraticCurveTo(p[0], p[1], p2[0], p2[1]); |
| 165 |
} |
| 166 |
}else if (cmd == "q"){ |
| 167 |
}else if (cmd == "T"){ |
| 168 |
}else if (cmd == "t"){ |
| 169 |
}else if (cmd == "A"){ |
| 170 |
}else if (cmd == "a"){ |
| 171 |
}else{ |
| 172 |
} |
| 173 |
} |
| 174 |
|
| 175 |
ctx.stroke(); |
| 176 |
ctx.closePath(); |
| 177 |
break; |
| 178 |
|
| 179 |
case 'RECT': |
| 180 |
var px = ele[i].getAttribute("x"); |
| 181 |
var py = ele[i].getAttribute("y"); |
| 182 |
var w = ele[i].getAttribute("width"); |
| 183 |
var h = ele[i].getAttribute("height"); |
| 184 |
|
| 185 |
ctx.beginPath(); |
| 186 |
ctx.setTransform(1, 0, 0, 1, 0, 0); |
| 187 |
if(color)ctx.strokeStyle = color; |
| 188 |
if(width) ctx.lineWidth = width; |
| 189 |
|
| 190 |
if(!fill || fill == 'none'){ |
| 191 |
ctx.strokeRect(px, py, w, h); |
| 192 |
}else if( fill == 'clear'){ |
| 193 |
ctx.clearRect(px, py, w, h); |
| 194 |
}else{ |
| 195 |
ctx.fillStyle = fill; |
| 196 |
ctx.fillRect(px, py, w, h); |
| 197 |
if(color) ctx.strokeRect(px, py, w, h); |
| 198 |
} |
| 199 |
ctx.closePath(); |
| 200 |
break; |
| 201 |
|
| 202 |
case 'CIRCLE': |
| 203 |
var cx = ele[i].getAttribute("cx"); |
| 204 |
var cy = ele[i].getAttribute("cy"); |
| 205 |
var r = ele[i].getAttribute("r"); |
| 206 |
ctx.beginPath(); |
| 207 |
ctx.setTransform(1, 0, 0, 1, 0, 0); |
| 208 |
circle(ctx, cx, cy, r, color, fill, width); |
| 209 |
ctx.closePath(); |
| 210 |
break; |
| 211 |
|
| 212 |
case 'ELLIPSE': |
| 213 |
var cx = parseInt(ele[i].getAttribute("cx")); |
| 214 |
var cy = parseInt(ele[i].getAttribute("cy")); |
| 215 |
var rx = parseInt(ele[i].getAttribute("rx")); |
| 216 |
var ry = parseInt(ele[i].getAttribute("ry")); |
| 217 |
|
| 218 |
ctx.beginPath(); |
| 219 |
ctx.setTransform(1, 0, 0, 1, 0, 0); |
| 220 |
ellipse(ctx, cx, cy, rx, ry, color, fill, width); |
| 221 |
ctx.closePath(); |
| 222 |
break; |
| 223 |
|
| 224 |
defalut: |
| 225 |
break; |
| 226 |
} |
| 227 |
if(ele[i].hasChildNodes()){ |
| 228 |
drawAll(ctx, ele[i].childNodes); |
| 229 |
} |
| 230 |
} |
| 231 |
|
| 232 |
} |
| 233 |
|
| 234 |
function circle(ctx, cx, cy, r, color, fill, width){ |
| 235 |
if(color)ctx.strokeStyle = color; |
| 236 |
if(width) ctx.lineWidth = width; |
| 237 |
if(!fill || fill == 'none'){ |
| 238 |
ctx.arc(cx, cy, r, 0, Math.PI *2 ,true); |
| 239 |
ctx.stroke() |
| 240 |
}else{ |
| 241 |
ctx.fillStyle = fill; |
| 242 |
ctx.arc(cx, cy, r, 0, Math.PI *2 ,true); |
| 243 |
ctx.fill() |
| 244 |
if(color){ |
| 245 |
ctx.arc(cx, cy, r, 0, Math.PI *2 ,true); |
| 246 |
ctx.stroke() |
| 247 |
} |
| 248 |
} |
| 249 |
} |
| 250 |
|
| 251 |
function ellipse(ctx, cx, cy, rx, ry, color, fill, width) { |
| 252 |
if(color)ctx.strokeStyle = color; |
| 253 |
if(width) ctx.lineWidth = width; |
| 254 |
if(!fill || fill == 'none'){ |
| 255 |
draw_ellipse(ctx, cx, cy, rx, ry, color, fill, width); |
| 256 |
ctx.stroke() |
| 257 |
}else{ |
| 258 |
ctx.fillStyle = fill; |
| 259 |
draw_ellipse(ctx, cx, cy, rx, ry, color, fill, width); |
| 260 |
ctx.fill() |
| 261 |
if(color){ |
| 262 |
draw_ellipse(ctx, cx, cy, rx, ry, color, fill, width); |
| 263 |
ctx.stroke() |
| 264 |
} |
| 265 |
} |
| 266 |
} |
| 267 |
|
| 268 |
function draw_ellipse(ctx, x, y, w, h) { |
| 269 |
var kappa = .5522848; |
| 270 |
ox = w * kappa , // control point offset horizontal |
| 271 |
oy = h * kappa , // control point offset vertical |
| 272 |
xe = x + w*2, // x-end |
| 273 |
ye = y + h*2, // y-end |
| 274 |
xm = x + w , // x-middle |
| 275 |
ym = y + h ; // y-middle |
| 276 |
|
| 277 |
ctx.moveTo(x-w, ym-h); |
| 278 |
ctx.bezierCurveTo(x-w, ym - oy-h, xm - ox-w, y-h, xm-w, y-h); |
| 279 |
ctx.bezierCurveTo(xm + ox-w, y-h, xe-w, ym - oy-h, xe-w, ym-h); |
| 280 |
ctx.bezierCurveTo(xe-w, ym + oy-h, xm + ox-w, ye-h, xm-w, ye-h); |
| 281 |
ctx.bezierCurveTo(xm - ox-w, ye-h, x-w, ym + oy-h, x-w, ym-h); |
| 282 |
} |
| 283 |
|
| 284 |
function polyline(ctx, pts, color, fill, width, isClose){ |
| 285 |
var points = pts.split(' '); |
| 286 |
|
| 287 |
if(points.length < 2) return false; |
| 288 |
|
| 289 |
var tmp = points.shift(); |
| 290 |
|
| 291 |
var p = tmp.split(','); |
| 292 |
|
| 293 |
ctx.beginPath(); |
| 294 |
ctx.setTransform(1, 0, 0, 1, 0, 0); |
| 295 |
ctx.strokeStyle=color; |
| 296 |
ctx.lineWidth=width; |
| 297 |
ctx.moveTo(p[0], p[1]); |
| 298 |
|
| 299 |
for(var i=0; i <points.length; i++){ |
| 300 |
tmp = points[i]; |
| 301 |
p = tmp.split(','); |
| 302 |
ctx.lineTo(p[0], p[1]); |
| 303 |
} |
| 304 |
|
| 305 |
if (isClose) ctx.closePath(); |
| 306 |
|
| 307 |
if (fill && fill != 'none'){ |
| 308 |
ctx.fillStyle=fill; |
| 309 |
ctx.fill(); |
| 310 |
} |
| 311 |
ctx.stroke(); |
| 312 |
} |
| 313 |
|
| 314 |
function svg_image(ctx,iname, x, y, w, h){ |
| 315 |
if (w == 0 || h == 0) return; |
| 316 |
|
| 317 |
var img = new Image(); |
| 318 |
img.src = iname; |
| 319 |
|
| 320 |
img.onload = function (){ |
| 321 |
if (w < 0 || h < 0){ |
| 322 |
ctx.drawImage(img, x, y); |
| 323 |
}else{ |
| 324 |
ctx.drawImage(img, x, y, w, h); |
| 325 |
} |
| 326 |
} |
| 327 |
} |