jquery.flot.composeImages.Test.js 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. /* eslint-disable */
  2. /* global $, describe, it, xit, xdescribe, after, afterEach, expect*/
  3. describe("composeImages", function() {
  4. var placeholder, plot;
  5. var composeImages = $.plot.composeImages,
  6. canvasData = window.colors.canvasData;
  7. beforeEach(function() {
  8. placeholder = setFixtures('<div id="test-container" style="width: 600px;height: 400px; padding: 0px margin: 0px; border: 0px; font-size:0pt; font-family:sans-serif; line-height:0px;">')
  9. .find('#test-container');
  10. jasmine.addMatchers(window.colors.jasmineMatchers);
  11. });
  12. it('should call composeImages on an empty array of sources, so the destination canvas should stay unmodified', function (done) {
  13. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  14. '</div>' +
  15. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  16. ).find('svg').toArray();
  17. var destinationCanvas = document.getElementById("myCanvas");
  18. function drawCircleOnToCanvas(canvas) {
  19. var ctx = canvas.getContext('2d');
  20. ctx.arc(80, 10, 5, 0, 2 * Math.PI);
  21. ctx.fill();
  22. }
  23. drawCircleOnToCanvas(destinationCanvas); //make sure composeImages won't modify this content
  24. composeImages(sources, destinationCanvas).then(function() {
  25. expect(canvasData(destinationCanvas, 80, 10, 1, 1)).toMatchPixelColor([0, 0, 0, 255]);
  26. expect(destinationCanvas.width).toBe(300);
  27. expect(destinationCanvas.height).toBe(150);
  28. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([0, 0, 0, 0]);
  29. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 0, 0, 0]);
  30. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 0, 0]);
  31. expect(canvasData(destinationCanvas, 10, 110, 1, 1)).toMatchPixelColor([0, 0, 0, 0]);
  32. expect(canvasData(destinationCanvas, 30, 140, 1, 1)).toMatchPixelColor([0, 0, 0, 0]);
  33. expect(canvasData(destinationCanvas, 50, 170, 1, 1)).toMatchPixelColor([0, 0, 0, 0]);
  34. done();
  35. }, null);
  36. });
  37. it('should call composeImages on one SVG as a source', function (done) {
  38. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  39. '<svg id="svgSource" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg">' +
  40. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  41. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  42. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  43. '</svg>' +
  44. '</div>' +
  45. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  46. ).find('svg').toArray();
  47. var destinationCanvas = document.getElementById("myCanvas");
  48. composeImages(sources, destinationCanvas).then(function() {
  49. expect(destinationCanvas.width).toBe(100);
  50. expect(destinationCanvas.height).toBe(100);
  51. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  52. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  53. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  54. done();
  55. }, null);
  56. });
  57. it('should call composeImages on two identical SVGs, one near the other', function (done) {
  58. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  59. '<svg id="svgSource" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg">' +
  60. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  61. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  62. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  63. '</svg>' +
  64. '<svg id="svgSource2" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg2">' +
  65. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  66. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  67. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  68. '</svg>' +
  69. '</div>' +
  70. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  71. ).find('svg').toArray();
  72. var destinationCanvas = document.getElementById("myCanvas");
  73. composeImages(sources, destinationCanvas).then(function() {
  74. expect(destinationCanvas.width).toBe(200); //204 - //200 + 2 * 2px_spacing
  75. expect(destinationCanvas.height).toBe(100);
  76. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  77. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  78. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  79. expect(canvasData(destinationCanvas, 110, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]); //110 + 4
  80. expect(canvasData(destinationCanvas, 130, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]); //130 + 4
  81. expect(canvasData(destinationCanvas, 150, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]); //150 + 4
  82. done();
  83. }, null);
  84. });
  85. it('should call composeImages on two identical SVGs, one after the other', function (done) {
  86. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  87. '<svg id="svgSource" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg">' +
  88. '<circle id="c1" cx="10" cy="10" r="5" style="fill:#FF0000"/>' +
  89. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  90. '<circle id="c3" cx="50" cy="70" r="9" style="fill:#0000FF"/>' +
  91. '</svg>' +
  92. '<br>' +
  93. '<svg id="svgSource2" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg2">' +
  94. '<circle id="c1" cx="10" cy="10" r="5" style="fill:#FF0000"/>' +
  95. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  96. '<circle id="c3" cx="50" cy="70" r="9" style="fill:#0000FF"/>' +
  97. '</svg>' +
  98. '</div>' +
  99. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  100. ).find('svg').toArray();
  101. var destinationCanvas = document.getElementById("myCanvas");
  102. composeImages(sources, destinationCanvas).then(function() {
  103. expect(destinationCanvas.width).toBe(100);
  104. expect(destinationCanvas.height).toBe(200); //204 - //200 + 2 * 2px_spacing
  105. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  106. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  107. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  108. expect(canvasData(destinationCanvas, 10, 110, 1, 1)).toMatchPixelColor([255, 0, 0, 255]); //110 + 4
  109. expect(canvasData(destinationCanvas, 30, 140, 1, 1)).toMatchPixelColor([0, 255, 0, 255]); //140 + 4
  110. expect(canvasData(destinationCanvas, 50, 170, 1, 1)).toMatchPixelColor([0, 0, 255, 255]); //170 + 4
  111. done();
  112. }, null);
  113. });
  114. it('should call composeImages on three identical SVGs, placed in an L-shape', function (done) {
  115. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  116. '<svg id="svgSource1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg1">' +
  117. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  118. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  119. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  120. '</svg>' +
  121. '<svg id="svgSource2" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg2">' +
  122. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  123. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  124. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  125. '</svg>' +
  126. '<br>' +
  127. '<svg id="svgSource3" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg3">' +
  128. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  129. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  130. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  131. '</svg>' +
  132. '</div>' +
  133. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  134. ).find('svg').toArray();
  135. var destinationCanvas = document.getElementById("myCanvas");
  136. composeImages(sources, destinationCanvas).then(function() {
  137. expect(destinationCanvas.width).toBe(200); //204 - //200 + 2 * 2px_spacing
  138. expect(destinationCanvas.height).toBe(200); //204 - //200 + 2 * 2px_spacing
  139. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  140. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  141. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  142. expect(canvasData(destinationCanvas, 110, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]); //110 + 4
  143. expect(canvasData(destinationCanvas, 130, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]); //130 + 4
  144. expect(canvasData(destinationCanvas, 150, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]); //150 + 4
  145. expect(canvasData(destinationCanvas, 10, 110, 1, 1)).toMatchPixelColor([255, 0, 0, 255]); //110 + 4
  146. expect(canvasData(destinationCanvas, 30, 140, 1, 1)).toMatchPixelColor([0, 255, 0, 255]); //140 + 4
  147. expect(canvasData(destinationCanvas, 50, 170, 1, 1)).toMatchPixelColor([0, 0, 255, 255]); //170 + 4
  148. done();
  149. }, null);
  150. });
  151. it('should call composeImages on one canvas as a source', function (done) {
  152. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  153. '<canvas id="canvasSource" width="20" height="20" title="canvasSource"></canvas>' +
  154. '</div>' +
  155. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  156. ).find('#canvasSource').toArray();
  157. var originalCanvas = document.getElementById("canvasSource");
  158. var destinationCanvas = document.getElementById("myCanvas");
  159. drawSomeLinesOnCanvas(originalCanvas);
  160. composeImages(sources, destinationCanvas).then(function() {
  161. expect(destinationCanvas.width).toBe(20);
  162. expect(destinationCanvas.height).toBe(20);
  163. expect(canvasData(originalCanvas, 0, 0, 20, 20))
  164. .toMatchCanvasArea(canvasData(destinationCanvas, 0, 0, 20, 20));
  165. done();
  166. }, null);
  167. });
  168. it('should call composeImages on one canvas and one SVG', function (done) {
  169. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  170. '<canvas class="imgsrc" id="canvasSource" width="20" height="20" title="canvasSource"></canvas>' +
  171. '<svg class="imgsrc" id="svgSource1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg1">' +
  172. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  173. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  174. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  175. '</svg>' +
  176. '</div>' +
  177. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  178. ).find('.imgsrc').toArray();
  179. var originalCanvas = document.getElementById("canvasSource");
  180. var destinationCanvas = document.getElementById("myCanvas");
  181. drawSomeLinesOnCanvas(originalCanvas);
  182. composeImages(sources, destinationCanvas).then(function() {
  183. expect(destinationCanvas.width).toBe(120); //124 - //120 + 2 * 2px_spacing
  184. expect(destinationCanvas.height).toBe(100);
  185. expect(canvasData(originalCanvas, 0, 0, 20, 20))
  186. .toMatchCanvasArea(canvasData(destinationCanvas, 0, 80, 20, 20));
  187. expect(canvasData(destinationCanvas, 20 + 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]); //24 + 10
  188. expect(canvasData(destinationCanvas, 20 + 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]); //24 + 30
  189. expect(canvasData(destinationCanvas, 20 + 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]); //24 + 50
  190. done();
  191. }, null);
  192. });
  193. it('should call composeImages on two canvases', function (done) {
  194. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  195. '<canvas class="imgsrc" id="canvasSource1" width="20" height="20" title="canvasSource1"></canvas>' +
  196. '<canvas class="imgsrc" id="canvasSource2" width="20" height="20" title="canvasSource2"></canvas>' +
  197. '</div>' +
  198. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  199. ).find('.imgsrc').toArray();
  200. var originalCanvas1 = document.getElementById("canvasSource1");
  201. var originalCanvas2 = document.getElementById("canvasSource2");
  202. var destinationCanvas = document.getElementById("myCanvas");
  203. drawARectangleOnCanvas(originalCanvas1, "#FF0000");
  204. drawARectangleOnCanvas(originalCanvas2, "#00FF00");
  205. composeImages(sources, destinationCanvas).then(function() {
  206. expect(destinationCanvas.width).toBe(40); //44 - //2 * 20 + 2 * spacing
  207. expect(destinationCanvas.height).toBe(20);
  208. expect(canvasData(originalCanvas1, 0, 0, 20, 20))
  209. .toMatchCanvasArea(canvasData(destinationCanvas, 0, 0, 20, 20));
  210. expect(canvasData(originalCanvas2, 0, 0, 20, 20))
  211. .toMatchCanvasArea(canvasData(destinationCanvas, 20 + 0, 0, 20, 20)); //20 + 4
  212. done();
  213. }, null);
  214. });
  215. it('should call composeImages on two partially overlapped canvases', function (done) {
  216. var sources = placeholder.html('<style type="text/css">' +
  217. '#canvasSource2 {position:relative; left:-10px;}' +
  218. '</style>' +
  219. '<div id="test-container" style="width: 600px;height: 400px">' +
  220. '<canvas class="imgsrc" id="canvasSource1" width="20" height="20" title="canvasSource1"></canvas>' +
  221. '<canvas class="imgsrc" id="canvasSource2" width="20" height="20" title="canvasSource2"></canvas>' +
  222. '</div>' +
  223. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  224. ).find('.imgsrc').toArray();
  225. var originalCanvas1 = document.getElementById("canvasSource1");
  226. var originalCanvas2 = document.getElementById("canvasSource2");
  227. var destinationCanvas = document.getElementById("myCanvas");
  228. drawARectangleOnCanvas(originalCanvas1, "#FF0000");
  229. drawARectangleOnCanvas(originalCanvas2, "#00FF00");
  230. composeImages(sources, destinationCanvas).then(function() {
  231. expect(destinationCanvas.width).toBe(30); //34 - //2 * 20 + 2 * spacing - 10 //10px is the offset of the second canvas, defined in style
  232. expect(destinationCanvas.height).toBe(20);
  233. expect(canvasData(originalCanvas1, 0, 0, 10, 20)) //14
  234. .toMatchCanvasArea(canvasData(destinationCanvas, 0, 0, 10, 20)); //14
  235. expect(canvasData(originalCanvas2, 0, 0, 20, 20))
  236. .toMatchCanvasArea(canvasData(destinationCanvas, 20 + 0 - 10, 0, 20, 20)); //20 + 10 - 4
  237. done();
  238. }, null);
  239. });
  240. it('should call composeImages on two partially overlapped canvases. Same as above test, but the two canvases have the opposite Z order.', function (done) {
  241. var sources = placeholder.html('<style type="text/css">' +
  242. '#canvasSource2 {position:relative; left:-10px;}' +
  243. '</style>' +
  244. '<div id="test-container" style="width: 600px;height: 400px">' +
  245. '<canvas class="imgsrc" id="canvasSource1" width="20" height="20" title="canvasSource1"></canvas>' +
  246. '<canvas class="imgsrc" id="canvasSource2" width="20" height="20" title="canvasSource2"></canvas>' +
  247. '</div>' +
  248. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  249. ).find('.imgsrc').toArray();
  250. var originalCanvas1 = document.getElementById("canvasSource1");
  251. var originalCanvas2 = document.getElementById("canvasSource2");
  252. var destinationCanvas = document.getElementById("myCanvas");
  253. drawARectangleOnCanvas(originalCanvas1, "#FF0000");
  254. drawARectangleOnCanvas(originalCanvas2, "#00FF00");
  255. sources.reverse(); //make sure the images are composed in the inverse order
  256. composeImages(sources, destinationCanvas).then(function() {
  257. expect(destinationCanvas.width).toBe(30); //34 - //2 * 20 + 2 * spacing - 10 //10px is the offset of the second canvas, defined in style
  258. expect(destinationCanvas.height).toBe(20);
  259. expect(canvasData(originalCanvas1, 0, 0, 20, 20))
  260. .toMatchCanvasArea(canvasData(destinationCanvas, 0, 0, 20, 20));
  261. expect(canvasData(originalCanvas2, 0, 0, 20 - 10 + 0, 20)) //20 - 10 + 4
  262. .toMatchCanvasArea(canvasData(destinationCanvas, 20, 0, 20 - 10 + 0, 20)); //20 - 10 + 4
  263. done();
  264. }, null);
  265. });
  266. it('should call composeImages on two separate canvases, where one canvas is outside of view area', function (done) {
  267. var sources = placeholder.html('<style type="text/css">' +
  268. '#canvasSource2 {position:relative; left:-100px;}' +
  269. '</style>' +
  270. '<div id="test-container" style="width: 600px;height: 400px">' +
  271. '<canvas class="imgsrc" id="canvasSource1" width="20" height="20" title="canvasSource1"></canvas>' +
  272. '<canvas class="imgsrc" id="canvasSource2" width="20" height="20" title="canvasSource2"></canvas>' +
  273. '</div>' +
  274. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  275. ).find('.imgsrc').toArray();
  276. var originalCanvas1 = document.getElementById("canvasSource1");
  277. var originalCanvas2 = document.getElementById("canvasSource2");
  278. var destinationCanvas = document.getElementById("myCanvas");
  279. drawARectangleOnCanvas(originalCanvas1, "#FF0000");
  280. drawARectangleOnCanvas(originalCanvas2, "#00FF00");
  281. composeImages(sources, destinationCanvas).then(function() {
  282. expect(destinationCanvas.width).toBe(100 - 0); //100 - 4
  283. expect(destinationCanvas.height).toBe(20);
  284. expect(canvasData(originalCanvas1, 0, 0, 20, 20))
  285. .toMatchCanvasArea(canvasData(destinationCanvas, 100 - 20 - 0, 0, 20, 20)); //100 - 20 - 10 + 6
  286. expect(canvasData(originalCanvas2, 0, 0, 20, 20))
  287. .toMatchCanvasArea(canvasData(destinationCanvas, 0, 0, 20, 20));
  288. done();
  289. }, null);
  290. });
  291. it('should call composeImages on one canvas and an SVG, which are totally overlapped with transparency', function (done) {
  292. var sources = placeholder.html('<style type="text/css">' +
  293. '#canvasSource1 {position:relative; left:-40px; top:-80px;}' +
  294. 'circle { stroke: black; stroke-width: 2px;}' +
  295. '</style>' +
  296. '<div id="test-container" style="width: 600px;height: 400px">' +
  297. '<svg class="imgsrc" id="svgSource1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg1">' +
  298. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  299. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  300. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  301. '</svg>' +
  302. '<canvas class="imgsrc" id="canvasSource1" width="20" height="20" title="canvasSource1"></canvas>' +
  303. '</div>' +
  304. '<canvas id="myCanvas" width="150" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  305. ).find('.imgsrc').toArray();
  306. var originalCanvas1 = document.getElementById("canvasSource1");
  307. var destinationCanvas = document.getElementById("myCanvas");
  308. drawARectangleOnCanvas(originalCanvas1, "#FF0000");
  309. composeImages(sources, destinationCanvas).then(function() {
  310. expect(destinationCanvas.width).toBe(100);
  311. expect(destinationCanvas.height).toBe(100);
  312. expect(canvasData(originalCanvas1, 0, 0, 20, 20))
  313. .toMatchCanvasArea(canvasData(destinationCanvas, 100 - 40 + 0, 0, 20, 20)); //100 - 40 + 4
  314. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  315. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  316. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  317. done();
  318. }, null);
  319. });
  320. it('should call composeImages on one canvas and an SVG, which are totally overlapped with transparency. The SVG has a different size than the ones from other tests. One component of the SVG is partially outside of the view area.', function (done) {
  321. var sources = placeholder.html('<style type="text/css">' +
  322. '#canvasSource1 {position:relative; left:-180px; top:-10px;}' +
  323. 'circle { stroke: black; stroke-width: 4px;}' +
  324. '</style>' +
  325. '<div id="test-container" style="width: 600px;height: 400px">' +
  326. '<svg class="imgsrc" id="svgSource1" viewBox="0 0 250 150" xmlns="http://www.w3.org/2000/svg" width="250" height="150" title="svg1">' +
  327. '<circle id="c1" cx="230" cy="20" r="15" style="fill:red"/>' +
  328. '<circle id="c2" cx="175" cy="100" r="25" style="fill:#00FF00"/>' +
  329. '<circle id="c3" cx="50" cy="130" r="40" style="fill:blue"/>' +
  330. '</svg>' +
  331. '<canvas class="imgsrc" id="canvasSource1" width="20" height="20" title="canvasSource1"></canvas>' +
  332. '</div>' +
  333. '<canvas id="myCanvas" width="150" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  334. ).find('.imgsrc').toArray();
  335. var originalCanvas1 = document.getElementById("canvasSource1");
  336. var destinationCanvas = document.getElementById("myCanvas");
  337. drawARectangleOnCanvas(originalCanvas1, "#FF0000");
  338. composeImages(sources, destinationCanvas).then(function() {
  339. expect(destinationCanvas.width).toBe(250);
  340. expect(destinationCanvas.height).toBe(150);
  341. expect(canvasData(originalCanvas1, 0, 0, 20, 20))
  342. .toMatchCanvasArea(canvasData(destinationCanvas, 250 - 180 + 0, 150 - 10 - 20, 20, 20)); //250 - 180 + 4
  343. //circle centers
  344. expect(canvasData(destinationCanvas, 230, 20, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  345. expect(canvasData(destinationCanvas, 175, 100, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  346. expect(canvasData(destinationCanvas, 50, 130, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  347. //other points on circles should match the required colors, because of configured diameters
  348. expect(canvasData(destinationCanvas, 220, 17, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  349. expect(canvasData(destinationCanvas, 190, 114, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  350. expect(canvasData(destinationCanvas, 80, 149, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  351. //verify a pixel from the circle border, if it comes from a black line (almost black, because of antialiasing), as described in svg style
  352. expect(canvasData(destinationCanvas, 79, 102, 1, 1)).toMatchPixelColorWithError([0, 0, 0, 255, 15]);
  353. done();
  354. }, null);
  355. });
  356. it('should call composeImages on one canvas and an SVG, which are totally overlapped with transparency, using external CSS. The SVG has a different size than the ones from other tests. One component of the SVG is partially outside of the view area.', function (done) {
  357. var sources = placeholder.html('<style type="text/css">' +
  358. '#canvasSource1 {position:relative; left:-180px; top:-10px;}' +
  359. '</style>' +
  360. '<div id="test-container" style="width: 600px;height: 400px">' +
  361. '<svg class="imgsrc" id="svgSource1" viewBox="0 0 250 150" xmlns="http://www.w3.org/2000/svg" width="250" height="150" title="svg1">' +
  362. '<circle class="externalCSS" id="c1" cx="230" cy="20" r="15" style="fill:red"/>' +
  363. '<circle class="externalCSS" id="c2" cx="175" cy="100" r="25" style="fill:#00FF00"/>' +
  364. '<circle class="externalCSS" id="c3" cx="50" cy="130" r="40" style="fill:blue"/>' +
  365. '</svg>' +
  366. '<canvas class="imgsrc" id="canvasSource1" width="20" height="20" title="canvasSource1"></canvas>' +
  367. '</div>' +
  368. '<canvas id="myCanvas" width="150" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  369. ).find('.imgsrc').toArray();
  370. var originalCanvas1 = document.getElementById("canvasSource1");
  371. var destinationCanvas = document.getElementById("myCanvas");
  372. drawARectangleOnCanvas(originalCanvas1, "#FF0000");
  373. composeImages(sources, destinationCanvas).then(function() {
  374. expect(destinationCanvas.width).toBe(250);
  375. expect(destinationCanvas.height).toBe(150);
  376. expect(canvasData(originalCanvas1, 0, 0, 20, 20))
  377. .toMatchCanvasArea(canvasData(destinationCanvas, 250 - 180 + 0, 150 - 10 - 20, 20, 20)); //250 - 180 + 4
  378. //circle centers
  379. expect(canvasData(destinationCanvas, 230, 20, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  380. expect(canvasData(destinationCanvas, 175, 100, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  381. expect(canvasData(destinationCanvas, 50, 130, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  382. //other points on circles should match the required colors, because of configured diameters
  383. expect(canvasData(destinationCanvas, 220, 17, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  384. expect(canvasData(destinationCanvas, 190, 114, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  385. expect(canvasData(destinationCanvas, 80, 149, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  386. //verify a pixel from the circle border, if it comes from a black line (almost black, because of antialiasing), as described in svg style
  387. expect(canvasData(destinationCanvas, 79, 102, 1, 1)).toMatchPixelColorWithError([0, 0, 0, 255, 15]);
  388. done();
  389. }, null);
  390. });
  391. it('should call composeImages on one dynamically created canvas as a source, without being able to compose', function (done) {
  392. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  393. '</div>' +
  394. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  395. ).find('#canvasSource').toArray();
  396. var originalCanvas = document.createElement('canvas');
  397. originalCanvas.width = 20;
  398. originalCanvas.height = 20;
  399. drawSomeLinesOnCanvas(originalCanvas);
  400. sources.push(originalCanvas);
  401. var destinationCanvas = document.getElementById("myCanvas");
  402. composeImages(sources, destinationCanvas).then(function() {
  403. expect(destinationCanvas.width).toBe(30);
  404. expect(destinationCanvas.height).toBe(15);
  405. done();
  406. }, null);
  407. });
  408. it('should call composeImages on two dynamically created canvas as sources, without being able to compose', function (done) {
  409. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  410. '</div>' +
  411. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  412. ).find('#canvasSource').toArray();
  413. var originalCanvas = document.createElement('canvas');
  414. originalCanvas.width = 20;
  415. originalCanvas.height = 20;
  416. drawSomeLinesOnCanvas(originalCanvas);
  417. sources.push(originalCanvas);
  418. originalCanvas = document.createElement('canvas');
  419. originalCanvas.width = 20;
  420. originalCanvas.height = 20;
  421. drawSomeLinesOnCanvas(originalCanvas);
  422. sources.push(originalCanvas);
  423. var destinationCanvas = document.getElementById("myCanvas");
  424. composeImages(sources, destinationCanvas).then(function() {
  425. expect(destinationCanvas.width).toBe(30);
  426. expect(destinationCanvas.height).toBe(15);
  427. done();
  428. }, null);
  429. });
  430. it('should call composeImages on two dynamically created canvas as sources (with left/top properties set), without being able to compose', function (done) {
  431. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  432. '</div>' +
  433. '<canvas id="myCanvas" width="30" height="15" style="border:1px solid #d3d3d3;"></canvas>'
  434. ).find('#canvasSource').toArray();
  435. var originalCanvas = document.createElement('canvas');
  436. originalCanvas.width = 20;
  437. originalCanvas.height = 20;
  438. originalCanvas.left = 0;
  439. originalCanvas.top = 0;
  440. drawSomeLinesOnCanvas(originalCanvas);
  441. sources.push(originalCanvas);
  442. originalCanvas = document.createElement('canvas');
  443. originalCanvas.width = 20;
  444. originalCanvas.height = 20;
  445. originalCanvas.left = 0;
  446. originalCanvas.top = 0;
  447. drawSomeLinesOnCanvas(originalCanvas);
  448. sources.push(originalCanvas);
  449. var destinationCanvas = document.getElementById("myCanvas");
  450. composeImages(sources, destinationCanvas).then(function() {
  451. expect(destinationCanvas.width).toBe(30);
  452. expect(destinationCanvas.height).toBe(15);
  453. done();
  454. }, null);
  455. });
  456. it('should call composeImages on one canvas as a source and a dynamically generated destination Canvas', function (done) {
  457. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  458. '<canvas id="canvasSource" width="20" height="20" title="canvasSource"></canvas>' +
  459. '</div>'
  460. ).find('#canvasSource').toArray();
  461. var originalCanvas = document.getElementById("canvasSource");
  462. var destinationCanvas = document.createElement("canvas");
  463. destinationCanvas.width = 30;
  464. destinationCanvas.height = 15;
  465. drawSomeLinesOnCanvas(originalCanvas);
  466. composeImages(sources, destinationCanvas).then(function() {
  467. expect(destinationCanvas.width).toBe(20);
  468. expect(destinationCanvas.height).toBe(20);
  469. expect(canvasData(originalCanvas, 0, 0, 20, 20))
  470. .toMatchCanvasArea(canvasData(destinationCanvas, 0, 0, 20, 20));
  471. done();
  472. }, null);
  473. });
  474. xit('should call composeImages on one SVG as a source, which defines only its viewbox, without width and height', function (done) {
  475. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  476. '<svg id="svgSource" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" title="svg">' +
  477. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  478. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  479. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  480. '</svg>' +
  481. '</div>' +
  482. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  483. ).find('svg').toArray();
  484. var destinationCanvas = document.getElementById("myCanvas");
  485. composeImages(sources, destinationCanvas).then(function() {
  486. expect(destinationCanvas.width).toBe(600);
  487. expect(destinationCanvas.height).toBe(600);
  488. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  489. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  490. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  491. done();
  492. }, null);
  493. });
  494. xit('should call composeImages on one SVG as a source, which defines only its width and height, without its viewbox', function (done) {
  495. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  496. '<svg id="svgSource" xmlns="http://www.w3.org/2000/svg" width="100" height="100" title="svg">' +
  497. '<circle id="c1" cx="10" cy="10" r="5" style="fill:red"/>' +
  498. '<circle id="c2" cx="30" cy="40" r="7" style="fill:#00FF00"/>' +
  499. '<circle id="c3" cx="50" cy="70" r="9" style="fill:blue"/>' +
  500. '</svg>' +
  501. '</div>' +
  502. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  503. ).find('svg').toArray();
  504. var destinationCanvas = document.getElementById("myCanvas");
  505. composeImages(sources, destinationCanvas).then(function() {
  506. expect(destinationCanvas.width).toBe(100);
  507. expect(destinationCanvas.height).toBe(100);
  508. expect(canvasData(destinationCanvas, 10, 10, 1, 1)).toMatchPixelColor([255, 0, 0, 255]);
  509. expect(canvasData(destinationCanvas, 30, 40, 1, 1)).toMatchPixelColor([0, 255, 0, 255]);
  510. expect(canvasData(destinationCanvas, 50, 70, 1, 1)).toMatchPixelColor([0, 0, 255, 255]);
  511. done();
  512. }, null);
  513. });
  514. xit('should call composeImages on one potentially unsupported SVG as a source, because it contains "uses". Only its viewBox is defined.', function (done) {
  515. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  516. '<svg class="legendLayer" style="width:inherit;height:inherit;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">' +
  517. '<defs>' +
  518. '<symbol id="line" fill="none" viewBox="-5 -5 25 25">' +
  519. '<polyline points="0,15 5,5 10,10 15,0"></polyline>' +
  520. '</symbol>' +
  521. '</defs>' +
  522. '<g>' +
  523. '<use xlink:href="#line" class="legendIcon" x="0em" y="0em" stroke="#82A3D1" stroke-width="2" width="1.5em" height="1.5em"></use>' +
  524. '<text x="0em" y="0em" text-anchor="start"><tspan dx="2em" dy="1.2em">Plot 1</tspan></text>' +
  525. '</g>' +
  526. '<g>' +
  527. '<use xlink:href="#line" class="legendIcon" x="0em" y="1.5em" stroke="#862323" stroke-width="1" width="1.5em" height="1.5em"></use>' +
  528. '<text x="0em" y="1.5em" text-anchor="start"><tspan dx="2em" dy="1.2em">Plot 2</tspan></text>' +
  529. '</g>' +
  530. '</svg>' +
  531. '</div>' +
  532. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  533. ).find('svg').toArray();
  534. var destinationCanvas = document.getElementById("myCanvas");
  535. composeImages(sources, destinationCanvas).then(function() {
  536. expect(destinationCanvas.width).toBe(600);
  537. expect(destinationCanvas.height).toBe(400);
  538. done();
  539. }, null);
  540. });
  541. xit('should call composeImages on one potentially unsupported SVG as a source, because it contains "uses". Only the width and height properties are defined.', function (done) {
  542. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  543. '<svg class="legendLayer" style="width:inherit;height:inherit;" xmlns="http://www.w3.org/2000/svg" width="20" height="20">' +
  544. '<defs>' +
  545. '<symbol id="line" fill="none" viewBox="-5 -5 25 25">' +
  546. '<polyline points="0,15 5,5 10,10 15,0"></polyline>' +
  547. '</symbol>' +
  548. '</defs>' +
  549. '<g>' +
  550. '<use xlink:href="#line" class="legendIcon" x="0em" y="0em" stroke="#82A3D1" stroke-width="2" width="1.5em" height="1.5em"></use>' +
  551. '<text x="0em" y="0em" text-anchor="start"><tspan dx="2em" dy="1.2em">Plot 1</tspan></text>' +
  552. '</g>' +
  553. '<g>' +
  554. '<use xlink:href="#line" class="legendIcon" x="0em" y="1.5em" stroke="#862323" stroke-width="1" width="1.5em" height="1.5em"></use>' +
  555. '<text x="0em" y="1.5em" text-anchor="start"><tspan dx="2em" dy="1.2em">Plot 2</tspan></text>' +
  556. '</g>' +
  557. '</svg>' +
  558. '</div>' +
  559. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  560. ).find('svg').toArray();
  561. var destinationCanvas = document.getElementById("myCanvas");
  562. composeImages(sources, destinationCanvas).then(function() {
  563. expect(destinationCanvas.width).toBe(600);
  564. expect(destinationCanvas.height).toBe(400);
  565. done();
  566. }, null);
  567. });
  568. it('should call composeImages on one potentially unsupported SVG as a source, because it contains "uses". ViewBox, width and height properties are defined.', function (done) {
  569. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  570. '<svg class="legendLayer" style="width:inherit;height:inherit;" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 100 100">' +
  571. '<defs>' +
  572. '<symbol id="line" fill="none" viewBox="-5 -5 25 25">' +
  573. '<polyline points="0,15 5,5 10,10 15,0"></polyline>' +
  574. '</symbol>' +
  575. '</defs>' +
  576. '<g>' +
  577. '<use xlink:href="#line" class="legendIcon" x="0em" y="0em" stroke="#82A3D1" stroke-width="2" width="1.5em" height="1.5em"></use>' +
  578. '<text x="0em" y="0em" text-anchor="start"><tspan dx="2em" dy="1.2em">Plot 1</tspan></text>' +
  579. '</g>' +
  580. '<g>' +
  581. '<use xlink:href="#line" class="legendIcon" x="0em" y="1.5em" stroke="#862323" stroke-width="1" width="1.5em" height="1.5em"></use>' +
  582. '<text x="0em" y="1.5em" text-anchor="start"><tspan dx="2em" dy="1.2em">Plot 2</tspan></text>' +
  583. '</g>' +
  584. '</svg>' +
  585. '</div>' +
  586. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  587. ).find('svg').toArray();
  588. var destinationCanvas = document.getElementById("myCanvas");
  589. composeImages(sources, destinationCanvas).then(function() {
  590. expect(destinationCanvas.width).toBe(600);
  591. expect(destinationCanvas.height).toBe(400);
  592. done();
  593. }, null);
  594. });
  595. xit('should call composeImages on one empty SVG as a source. This may block composeImages.', function (done) {
  596. var sources = placeholder.html('<div id="test-container" style="width: 600px;height: 400px">' +
  597. '<svg class="legendLayer" style="width:inherit;height:inherit;" xmlns="http://www.w3.org/2000/svg" id="blockingTest">' +
  598. '</svg>' +
  599. '</div>' +
  600. '<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;"></canvas>'
  601. ).find('svg').toArray();
  602. var destinationCanvas = document.getElementById("myCanvas");
  603. composeImages(sources, destinationCanvas).then(function() {
  604. expect(destinationCanvas.width).toBe(600);
  605. expect(destinationCanvas.height).toBe(400);
  606. done();
  607. }, null);
  608. });
  609. function drawSomeLinesOnCanvas(canvas) {
  610. var ctx = canvas.getContext('2d');
  611. ctx.beginPath();
  612. ctx.moveTo(0, 0);
  613. ctx.lineTo(19, 19);
  614. ctx.moveTo(3, 18);
  615. ctx.lineTo(17, 5);
  616. ctx.stroke();
  617. }
  618. function drawARectangleOnCanvas(canvas, color) {
  619. var ctx = canvas.getContext('2d');
  620. ctx.rect(0, 0, 20, 20);
  621. ctx.fillStyle = color;
  622. ctx.fill();
  623. }
  624. });