holder_rails 2.8.0 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -6
- data/lib/holder_rails/helpers.rb +7 -3
- data/lib/holder_rails/version.rb +1 -1
- data/test/holder_rails_test.rb +12 -7
- data/vendor/assets/javascripts/holder.js +940 -510
- data/vendor/assets/javascripts/holder.min.js +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39c5281d7180281efb41a1edf27f298bf8241a6e
|
4
|
+
data.tar.gz: 2dfc66e687c8ba89a0fa565c1fa1b88953c8fb58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53a98257465f143b91d996abf4c6fd7bc44e459ddfb6f8aad46a77e57cc925f7cdedb18c3a165425504a5d042762586db5f643faeadb8f515f78ce1dbcd96898
|
7
|
+
data.tar.gz: 229d18c489cfd94a03ef253efa7d16045272d890a6f0853dcfb7c7239461367bc01480796a478d5cd6b7a55f82b502b1d36d609d5a68e1322c7154a6ec8b37ca
|
data/README.md
CHANGED
@@ -39,19 +39,22 @@ You can use `holder_tag` helper in your views:
|
|
39
39
|
|
40
40
|
```ruby
|
41
41
|
holder_tag 100
|
42
|
-
# => <img data-src="holder.js/100x100
|
42
|
+
# => <img data-src="holder.js/100x100?" src="" />
|
43
43
|
|
44
44
|
holder_tag '200x300'
|
45
|
-
# => <img data-src="holder.js/200x300
|
45
|
+
# => <img data-src="holder.js/200x300?" src="" />
|
46
46
|
|
47
47
|
holder_tag '200x300', 'Lorem ipsum'
|
48
|
-
# => <img data-src="holder.js/200x300
|
48
|
+
# => <img data-src="holder.js/200x300?text=Lorem ipsum" src="" />
|
49
49
|
|
50
50
|
holder_tag '200x300', 'Lorem ipsum', 'social'
|
51
|
-
# => <img data-src="holder.js/200x300
|
51
|
+
# => <img data-src="holder.js/200x300?text=Lorem ipsum&theme=social" src="" />
|
52
52
|
|
53
|
-
holder_tag '500x800', 'Example text', 'gray', :
|
54
|
-
# => <img class="special" data-src="holder.js/500x800
|
53
|
+
holder_tag '500x800', 'Example text', 'gray', id: 'new', class: 'special'
|
54
|
+
# => <img class="special" data-src="holder.js/500x800?text=Example text&theme=gray" id="new" src="" />
|
55
|
+
|
56
|
+
holder_tag '500x800', 'Example text', 'gray', { id: 'new', class: 'special' }, { font: 'Helvetica' }
|
57
|
+
# => <img class="special" data-src="holder.js/500x800?font=Helvetica&text=Example text&theme=gray" id="new" src="" />
|
55
58
|
```
|
56
59
|
|
57
60
|
For more information, check out [holder readme](https://github.com/imsky/holder#readme).
|
data/lib/holder_rails/helpers.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
module HolderRails
|
2
2
|
module Helpers
|
3
|
-
def holder_tag(size, text='', theme=nil, html_options={})
|
3
|
+
def holder_tag(size, text='', theme=nil, html_options={}, holder_options={})
|
4
4
|
size = "#{size}x#{size}" unless size =~ /\A\d+%?x\d+\z/
|
5
|
-
|
6
|
-
|
5
|
+
|
6
|
+
holder_options[:text] = text unless text.to_s.empty?
|
7
|
+
holder_options[:theme] = theme unless theme.nil?
|
8
|
+
holder_options = holder_options.map {|e| e.join('=') }.join('&')
|
9
|
+
|
10
|
+
options = { src: '', data: { src: "holder.js/#{size}?#{holder_options}" }}
|
7
11
|
options = options.merge(html_options)
|
8
12
|
|
9
13
|
tag :img, options
|
data/lib/holder_rails/version.rb
CHANGED
data/test/holder_rails_test.rb
CHANGED
@@ -5,21 +5,26 @@ class HolderRailsTest < ActionView::TestCase
|
|
5
5
|
include HolderRails::Helpers
|
6
6
|
|
7
7
|
test "size" do
|
8
|
-
assert_dom_equal '<img data-src="holder.js/100x100
|
9
|
-
assert_dom_equal '<img data-src="holder.js/200x300
|
10
|
-
assert_dom_equal '<img data-src="holder.js/100%x75
|
8
|
+
assert_dom_equal '<img data-src="holder.js/100x100?" src="" />', holder_tag(100)
|
9
|
+
assert_dom_equal '<img data-src="holder.js/200x300?" src="" />', holder_tag('200x300')
|
10
|
+
assert_dom_equal '<img data-src="holder.js/100%x75?" src="" />', holder_tag('100%x75')
|
11
11
|
end
|
12
12
|
|
13
13
|
test "text" do
|
14
|
-
assert_dom_equal '<img data-src="holder.js/200x300
|
14
|
+
assert_dom_equal '<img data-src="holder.js/200x300?text=Lorem ipsum" src="" />', holder_tag('200x300', 'Lorem ipsum')
|
15
15
|
end
|
16
16
|
|
17
17
|
test "theme" do
|
18
|
-
assert_dom_equal '<img data-src="holder.js/200x300
|
18
|
+
assert_dom_equal '<img data-src="holder.js/200x300?text=Lorem ipsum&theme=social" src="" />', holder_tag('200x300', 'Lorem ipsum', 'social')
|
19
19
|
end
|
20
20
|
|
21
21
|
test "html_options" do
|
22
|
-
assert_dom_equal '<img class="special" data-src="holder.js/500x800
|
23
|
-
holder_tag('500x800', 'Example text', 'gray', :
|
22
|
+
assert_dom_equal '<img class="special" data-src="holder.js/500x800?text=Example text&theme=gray" id="new" src="" />',
|
23
|
+
holder_tag('500x800', 'Example text', 'gray', id: 'new', class: 'special')
|
24
|
+
end
|
25
|
+
|
26
|
+
test "holder_options" do
|
27
|
+
assert_dom_equal '<img class="special" data-src="holder.js/500x800?font=Helvetica&text=Example text&theme=gray" id="new" src="" />',
|
28
|
+
holder_tag('500x800', 'Example text', 'gray', { id: 'new', class: 'special' }, { font: 'Helvetica' })
|
24
29
|
end
|
25
30
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/*!
|
2
2
|
|
3
3
|
Holder - client side image placeholders
|
4
|
-
Version 2.
|
4
|
+
Version 2.9.0+f2dkw
|
5
5
|
© 2015 Ivan Malopinsky - http://imsky.co
|
6
6
|
|
7
7
|
Site: http://holderjs.com
|
@@ -64,6 +64,25 @@ License: MIT
|
|
64
64
|
};
|
65
65
|
}
|
66
66
|
|
67
|
+
// ES5 15.4.4.18 Array.prototype.forEach ( callbackfn [ , thisArg ] )
|
68
|
+
// From https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/forEach
|
69
|
+
if (!Array.prototype.forEach) {
|
70
|
+
Array.prototype.forEach = function (fun /*, thisp */) {
|
71
|
+
if (this === void 0 || this === null) { throw TypeError(); }
|
72
|
+
|
73
|
+
var t = Object(this);
|
74
|
+
var len = t.length >>> 0;
|
75
|
+
if (typeof fun !== "function") { throw TypeError(); }
|
76
|
+
|
77
|
+
var thisp = arguments[1], i;
|
78
|
+
for (i = 0; i < len; i++) {
|
79
|
+
if (i in t) {
|
80
|
+
fun.call(thisp, t[i], i, t);
|
81
|
+
}
|
82
|
+
}
|
83
|
+
};
|
84
|
+
}
|
85
|
+
|
67
86
|
//https://github.com/inexorabletash/polyfill/blob/master/web.js
|
68
87
|
(function (global) {
|
69
88
|
var B64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
@@ -233,7 +252,7 @@ License: MIT
|
|
233
252
|
if(typeof exports === 'object' && typeof module === 'object')
|
234
253
|
module.exports = factory();
|
235
254
|
else if(typeof define === 'function' && define.amd)
|
236
|
-
define(factory);
|
255
|
+
define([], factory);
|
237
256
|
else if(typeof exports === 'object')
|
238
257
|
exports["Holder"] = factory();
|
239
258
|
else
|
@@ -303,29 +322,27 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
303
322
|
*/
|
304
323
|
|
305
324
|
//Libraries and functions
|
306
|
-
var onDomReady = __webpack_require__(
|
307
|
-
var querystring = __webpack_require__(
|
325
|
+
var onDomReady = __webpack_require__(2);
|
326
|
+
var querystring = __webpack_require__(3);
|
327
|
+
|
328
|
+
var SceneGraph = __webpack_require__(6);
|
329
|
+
var utils = __webpack_require__(7);
|
330
|
+
var SVG = __webpack_require__(8);
|
331
|
+
var DOM = __webpack_require__(9);
|
332
|
+
var Color = __webpack_require__(10);
|
333
|
+
var constants = __webpack_require__(11);
|
308
334
|
|
309
|
-
var
|
310
|
-
var
|
311
|
-
var SVG = __webpack_require__(6);
|
312
|
-
var DOM = __webpack_require__(7);
|
313
|
-
var Color = __webpack_require__(8);
|
335
|
+
var svgRenderer = __webpack_require__(12);
|
336
|
+
var sgCanvasRenderer = __webpack_require__(15);
|
314
337
|
|
315
338
|
var extend = utils.extend;
|
316
339
|
var dimensionCheck = utils.dimensionCheck;
|
317
340
|
|
318
341
|
//Constants and definitions
|
319
|
-
var SVG_NS =
|
320
|
-
var NODE_TYPE_COMMENT = 8;
|
321
|
-
var version = '2.8.0';
|
322
|
-
var generatorComment = '\n' +
|
323
|
-
'Created with Holder.js ' + version + '.\n' +
|
324
|
-
'Learn more at http://holderjs.com\n' +
|
325
|
-
'(c) 2012-2015 Ivan Malopinsky - http://imsky.co\n';
|
342
|
+
var SVG_NS = constants.svg_ns;
|
326
343
|
|
327
344
|
var Holder = {
|
328
|
-
version: version,
|
345
|
+
version: constants.version,
|
329
346
|
|
330
347
|
/**
|
331
348
|
* Adds a theme to default settings
|
@@ -347,16 +364,14 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
347
364
|
*/
|
348
365
|
addImage: function(src, el) {
|
349
366
|
//todo: use jquery fallback if available for all QSA references
|
350
|
-
var
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
}
|
359
|
-
}
|
367
|
+
var nodes = DOM.getNodeArray(el);
|
368
|
+
nodes.forEach(function (node) {
|
369
|
+
var img = DOM.newEl('img');
|
370
|
+
var domProps = {};
|
371
|
+
domProps[App.setup.dataAttr] = src;
|
372
|
+
DOM.setAttr(img, domProps);
|
373
|
+
node.appendChild(img);
|
374
|
+
});
|
360
375
|
return this;
|
361
376
|
},
|
362
377
|
|
@@ -389,7 +404,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
389
404
|
|
390
405
|
App.vars.preempted = true;
|
391
406
|
App.vars.dataAttr = options.dataAttr || App.setup.dataAttr;
|
392
|
-
App.vars.lineWrapRatio = options.lineWrapRatio || App.setup.lineWrapRatio;
|
393
407
|
|
394
408
|
engineSettings.renderer = options.renderer ? options.renderer : App.setup.renderer;
|
395
409
|
if (App.setup.renderers.join(',').indexOf(engineSettings.renderer) === -1) {
|
@@ -405,8 +419,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
405
419
|
engineSettings.svgXMLStylesheet = true;
|
406
420
|
engineSettings.noFontFallback = options.noFontFallback ? options.noFontFallback : false;
|
407
421
|
|
408
|
-
|
409
|
-
var styleNode = stylenodes[i];
|
422
|
+
stylenodes.forEach(function (styleNode) {
|
410
423
|
if (styleNode.attributes.rel && styleNode.attributes.href && styleNode.attributes.rel.value == 'stylesheet') {
|
411
424
|
var href = styleNode.attributes.href.value;
|
412
425
|
//todo: write isomorphic relative-to-absolute URL function
|
@@ -415,26 +428,29 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
415
428
|
var stylesheetURL = proxyLink.protocol + '//' + proxyLink.host + proxyLink.pathname + proxyLink.search;
|
416
429
|
engineSettings.stylesheets.push(stylesheetURL);
|
417
430
|
}
|
418
|
-
}
|
431
|
+
});
|
419
432
|
|
420
|
-
|
433
|
+
bgnodes.forEach(function (bgNode) {
|
421
434
|
//Skip processing background nodes if getComputedStyle is unavailable, since only modern browsers would be able to use canvas or SVG to render to background
|
422
|
-
if (!global.getComputedStyle)
|
423
|
-
var backgroundImage = global.getComputedStyle(
|
424
|
-
var dataBackgroundImage =
|
435
|
+
if (!global.getComputedStyle) return;
|
436
|
+
var backgroundImage = global.getComputedStyle(bgNode, null).getPropertyValue('background-image');
|
437
|
+
var dataBackgroundImage = bgNode.getAttribute('data-background-src');
|
425
438
|
var rawURL = dataBackgroundImage || backgroundImage;
|
426
439
|
|
427
440
|
var holderURL = null;
|
428
|
-
var holderString =
|
441
|
+
var holderString = options.domain + '/';
|
442
|
+
var holderStringIndex = rawURL.indexOf(holderString);
|
429
443
|
|
430
|
-
if (
|
444
|
+
if (holderStringIndex === 0) {
|
445
|
+
holderURL = rawURL;
|
446
|
+
} else if (holderStringIndex === 1 && rawURL[0] === '?') {
|
431
447
|
holderURL = rawURL.slice(1);
|
432
|
-
} else
|
433
|
-
var fragment = rawURL.substr(
|
434
|
-
|
435
|
-
|
436
|
-
if (
|
437
|
-
|
448
|
+
} else {
|
449
|
+
var fragment = rawURL.substr(holderStringIndex).match(/([^\"]*)"?\)/);
|
450
|
+
if (fragment !== null) {
|
451
|
+
holderURL = fragment[1];
|
452
|
+
} else if (rawURL.indexOf('url(') === 0) {
|
453
|
+
throw 'Holder: unable to parse background URL: ' + rawURL;
|
438
454
|
}
|
439
455
|
}
|
440
456
|
|
@@ -443,16 +459,15 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
443
459
|
if (holderFlags) {
|
444
460
|
prepareDOMElement({
|
445
461
|
mode: 'background',
|
446
|
-
el:
|
462
|
+
el: bgNode,
|
447
463
|
flags: holderFlags,
|
448
464
|
engineSettings: engineSettings
|
449
465
|
});
|
450
466
|
}
|
451
467
|
}
|
452
|
-
}
|
468
|
+
});
|
453
469
|
|
454
|
-
|
455
|
-
var object = objects[i];
|
470
|
+
objects.forEach(function (object) {
|
456
471
|
var objectAttr = {};
|
457
472
|
|
458
473
|
try {
|
@@ -468,10 +483,9 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
468
483
|
} else if (objectHasDataSrcURL) {
|
469
484
|
prepareImageElement(options, engineSettings, objectAttr.dataSrc, object);
|
470
485
|
}
|
471
|
-
}
|
486
|
+
});
|
472
487
|
|
473
|
-
|
474
|
-
var image = images[i];
|
488
|
+
images.forEach(function (image) {
|
475
489
|
var imageAttr = {};
|
476
490
|
|
477
491
|
try {
|
@@ -506,7 +520,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
506
520
|
} else if (imageHasDataSrcURL) {
|
507
521
|
prepareImageElement(options, engineSettings, imageAttr.dataSrc, image);
|
508
522
|
}
|
509
|
-
}
|
523
|
+
});
|
510
524
|
|
511
525
|
return this;
|
512
526
|
}
|
@@ -521,28 +535,28 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
521
535
|
stylenodes: 'head link.holderjs',
|
522
536
|
themes: {
|
523
537
|
'gray': {
|
524
|
-
|
525
|
-
|
538
|
+
bg: '#EEEEEE',
|
539
|
+
fg: '#AAAAAA'
|
526
540
|
},
|
527
541
|
'social': {
|
528
|
-
|
529
|
-
|
542
|
+
bg: '#3a5a97',
|
543
|
+
fg: '#FFFFFF'
|
530
544
|
},
|
531
545
|
'industrial': {
|
532
|
-
|
533
|
-
|
546
|
+
bg: '#434A52',
|
547
|
+
fg: '#C2F200'
|
534
548
|
},
|
535
549
|
'sky': {
|
536
|
-
|
537
|
-
|
550
|
+
bg: '#0D8FDB',
|
551
|
+
fg: '#FFFFFF'
|
538
552
|
},
|
539
553
|
'vine': {
|
540
|
-
|
541
|
-
|
554
|
+
bg: '#39DBAC',
|
555
|
+
fg: '#1E292C'
|
542
556
|
},
|
543
557
|
'lava': {
|
544
|
-
|
545
|
-
|
558
|
+
bg: '#F8591A',
|
559
|
+
fg: '#1C2846'
|
546
560
|
}
|
547
561
|
}
|
548
562
|
},
|
@@ -575,30 +589,19 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
575
589
|
}
|
576
590
|
|
577
591
|
/**
|
578
|
-
* Processes a Holder URL
|
592
|
+
* Processes a Holder URL and extracts configuration from query string
|
579
593
|
*
|
580
594
|
* @private
|
581
595
|
* @param url URL
|
582
|
-
* @param
|
596
|
+
* @param instanceOptions Instance options from Holder.run
|
583
597
|
*/
|
584
|
-
function parseURL(url,
|
598
|
+
function parseURL(url, instanceOptions) {
|
585
599
|
var holder = {
|
586
600
|
theme: extend(App.settings.themes.gray, null),
|
587
|
-
stylesheets:
|
588
|
-
instanceOptions:
|
601
|
+
stylesheets: instanceOptions.stylesheets,
|
602
|
+
instanceOptions: instanceOptions
|
589
603
|
};
|
590
604
|
|
591
|
-
return parseQueryString(url, holder);
|
592
|
-
}
|
593
|
-
|
594
|
-
/**
|
595
|
-
* Processes a Holder URL and extracts configuration from query string
|
596
|
-
*
|
597
|
-
* @private
|
598
|
-
* @param url URL
|
599
|
-
* @param holder Staging Holder object
|
600
|
-
*/
|
601
|
-
function parseQueryString(url, holder) {
|
602
605
|
var parts = url.split('?');
|
603
606
|
var basics = parts[0].split('/');
|
604
607
|
|
@@ -622,11 +625,11 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
622
625
|
// Colors
|
623
626
|
|
624
627
|
if (options.bg) {
|
625
|
-
holder.theme.
|
628
|
+
holder.theme.bg = utils.parseColor(options.bg);
|
626
629
|
}
|
627
630
|
|
628
631
|
if (options.fg) {
|
629
|
-
holder.theme.
|
632
|
+
holder.theme.fg = utils.parseColor(options.fg);
|
630
633
|
}
|
631
634
|
|
632
635
|
//todo: add automatic foreground to themes without foreground
|
@@ -660,6 +663,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
660
663
|
holder.align = options.align;
|
661
664
|
}
|
662
665
|
|
666
|
+
if (options.lineWrap) {
|
667
|
+
holder.lineWrap = options.lineWrap;
|
668
|
+
}
|
669
|
+
|
663
670
|
holder.nowrap = utils.truthy(options.nowrap);
|
664
671
|
|
665
672
|
// Miscellaneous
|
@@ -693,6 +700,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
693
700
|
theme = flags.theme;
|
694
701
|
var dimensionsCaption = dimensions.width + 'x' + dimensions.height;
|
695
702
|
mode = mode == null ? (flags.fluid ? 'fluid' : 'image') : mode;
|
703
|
+
var holderTemplateRe = /holder_([a-z]+)/g;
|
704
|
+
var dimensionsInText = false;
|
696
705
|
|
697
706
|
if (flags.text != null) {
|
698
707
|
theme.text = flags.text;
|
@@ -707,12 +716,30 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
707
716
|
}
|
708
717
|
}
|
709
718
|
|
719
|
+
if (theme.text) {
|
720
|
+
var holderTemplateMatches = theme.text.match(holderTemplateRe);
|
721
|
+
|
722
|
+
if (holderTemplateMatches !== null) {
|
723
|
+
//todo: optimize template replacement
|
724
|
+
holderTemplateMatches.forEach(function (match) {
|
725
|
+
if (match === 'holder_dimensions') {
|
726
|
+
theme.text = theme.text.replace(match, dimensionsCaption);
|
727
|
+
}
|
728
|
+
});
|
729
|
+
}
|
730
|
+
}
|
731
|
+
|
710
732
|
var holderURL = flags.holderURL;
|
711
733
|
var engineSettings = extend(_engineSettings, null);
|
712
734
|
|
713
735
|
if (flags.font) {
|
736
|
+
/*
|
737
|
+
If external fonts are used in a <img> placeholder rendered with SVG, Holder falls back to canvas.
|
738
|
+
|
739
|
+
This is done because Firefox and Chrome disallow embedded SVGs from referencing external assets.
|
740
|
+
The workaround is either to change the placeholder tag from <img> to <object> or to use the canvas renderer.
|
741
|
+
*/
|
714
742
|
theme.font = flags.font;
|
715
|
-
//Only run the <canvas> webfont fallback if noFontFallback is false, if the node is not an image, and if canvas is supported
|
716
743
|
if (!engineSettings.noFontFallback && el.nodeName.toLowerCase() === 'img' && App.setup.supportsCanvas && engineSettings.renderer === 'svg') {
|
717
744
|
engineSettings = extend(engineSettings, {
|
718
745
|
renderer: 'canvas'
|
@@ -747,7 +774,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
747
774
|
|
748
775
|
if (mode == 'image' || mode == 'fluid') {
|
749
776
|
DOM.setAttr(el, {
|
750
|
-
'alt':
|
777
|
+
'alt': theme.text ? (dimensionsInText ? theme.text : theme.text + ' [' + dimensionsCaption + ']') : dimensionsCaption
|
751
778
|
});
|
752
779
|
}
|
753
780
|
|
@@ -763,10 +790,11 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
763
790
|
};
|
764
791
|
|
765
792
|
if (mode == 'image') {
|
766
|
-
if (
|
793
|
+
if (!flags.auto) {
|
767
794
|
el.style.width = dimensions.width + 'px';
|
768
795
|
el.style.height = dimensions.height + 'px';
|
769
796
|
}
|
797
|
+
|
770
798
|
if (engineSettings.renderer == 'html') {
|
771
799
|
el.style.backgroundColor = theme.background;
|
772
800
|
} else {
|
@@ -849,7 +877,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
849
877
|
image = sgCanvasRenderer(sceneGraph, renderSettings);
|
850
878
|
break;
|
851
879
|
case 'svg':
|
852
|
-
image =
|
880
|
+
image = svgRenderer(sceneGraph, renderSettings);
|
853
881
|
break;
|
854
882
|
default:
|
855
883
|
throw 'Holder: invalid renderer: ' + engineSettings.renderer;
|
@@ -875,14 +903,12 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
875
903
|
});
|
876
904
|
} else if (el.nodeName.toLowerCase() === 'object') {
|
877
905
|
DOM.setAttr(el, {
|
878
|
-
'data': image
|
879
|
-
});
|
880
|
-
DOM.setAttr(el, {
|
906
|
+
'data': image,
|
881
907
|
'type': 'image/svg+xml'
|
882
908
|
});
|
883
909
|
}
|
884
910
|
if (engineSettings.reRender) {
|
885
|
-
global.setTimeout(function() {
|
911
|
+
global.setTimeout(function () {
|
886
912
|
var image = getRenderedImage();
|
887
913
|
if (image == null) {
|
888
914
|
throw 'Holder: couldn\'t render placeholder';
|
@@ -894,9 +920,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
894
920
|
});
|
895
921
|
} else if (el.nodeName.toLowerCase() === 'object') {
|
896
922
|
DOM.setAttr(el, {
|
897
|
-
'data': image
|
898
|
-
});
|
899
|
-
DOM.setAttr(el, {
|
923
|
+
'data': image,
|
900
924
|
'type': 'image/svg+xml'
|
901
925
|
});
|
902
926
|
}
|
@@ -927,7 +951,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
927
951
|
|
928
952
|
scene.font = {
|
929
953
|
family: scene.theme.font ? scene.theme.font : 'Arial, Helvetica, Open Sans, sans-serif',
|
930
|
-
size: textSize(scene.width, scene.height, fontSize),
|
954
|
+
size: textSize(scene.width, scene.height, fontSize, App.defaults.scale),
|
931
955
|
units: scene.theme.units ? scene.theme.units : App.defaults.units,
|
932
956
|
weight: scene.theme.fontweight ? scene.theme.fontweight : 'bold'
|
933
957
|
};
|
@@ -948,6 +972,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
948
972
|
break;
|
949
973
|
}
|
950
974
|
|
975
|
+
var lineWrap = scene.flags.lineWrap || App.setup.lineWrapRatio;
|
976
|
+
var sceneMargin = scene.width * lineWrap;
|
977
|
+
var maxLineWidth = sceneMargin;
|
978
|
+
|
951
979
|
var sceneGraph = new SceneGraph({
|
952
980
|
width: scene.width,
|
953
981
|
height: scene.height
|
@@ -956,30 +984,29 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
956
984
|
var Shape = sceneGraph.Shape;
|
957
985
|
|
958
986
|
var holderBg = new Shape.Rect('holderBg', {
|
959
|
-
fill: scene.theme.
|
987
|
+
fill: scene.theme.bg
|
960
988
|
});
|
961
989
|
|
962
990
|
holderBg.resize(scene.width, scene.height);
|
963
991
|
sceneGraph.root.add(holderBg);
|
964
992
|
|
965
993
|
if (scene.flags.outline) {
|
966
|
-
//todo: generalize darken/lighten to more than RRGGBB hex values
|
967
994
|
var outlineColor = new Color(holderBg.properties.fill);
|
968
|
-
|
969
995
|
outlineColor = outlineColor.lighten(outlineColor.lighterThan('7f7f7f') ? -0.1 : 0.1);
|
970
|
-
|
971
996
|
holderBg.properties.outline = {
|
972
997
|
fill: outlineColor.toHex(true),
|
973
998
|
width: 2
|
974
999
|
};
|
975
1000
|
}
|
976
1001
|
|
977
|
-
var holderTextColor = scene.theme.
|
1002
|
+
var holderTextColor = scene.theme.fg;
|
978
1003
|
|
979
1004
|
if (scene.flags.autoFg) {
|
980
1005
|
var holderBgColor = new Color(holderBg.properties.fill);
|
981
1006
|
var lightColor = new Color('fff');
|
982
|
-
var darkColor = new Color('000', {
|
1007
|
+
var darkColor = new Color('000', {
|
1008
|
+
'alpha': 0.285714
|
1009
|
+
});
|
983
1010
|
|
984
1011
|
holderTextColor = holderBgColor.blendAlpha(holderBgColor.lighterThan('7f7f7f') ? darkColor : lightColor).toHex(true);
|
985
1012
|
}
|
@@ -1010,9 +1037,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1010
1037
|
parent.height += line.height;
|
1011
1038
|
}
|
1012
1039
|
|
1013
|
-
var sceneMargin = scene.width * App.vars.lineWrapRatio;
|
1014
|
-
var maxLineWidth = sceneMargin;
|
1015
|
-
|
1016
1040
|
if (tpdata.lineCount > 1) {
|
1017
1041
|
var offsetX = 0;
|
1018
1042
|
var offsetY = 0;
|
@@ -1022,7 +1046,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1022
1046
|
|
1023
1047
|
//Double margin so that left/right-aligned next is not flush with edge of image
|
1024
1048
|
if (scene.align === 'left' || scene.align === 'right') {
|
1025
|
-
maxLineWidth = scene.width * (1 - (1 -
|
1049
|
+
maxLineWidth = scene.width * (1 - (1 - lineWrap) * 2);
|
1026
1050
|
}
|
1027
1051
|
|
1028
1052
|
for (var i = 0; i < tpdata.words.length; i++) {
|
@@ -1101,15 +1125,16 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1101
1125
|
* @param width Parent width
|
1102
1126
|
* @param height Parent height
|
1103
1127
|
* @param fontSize Requested text size
|
1128
|
+
* @param scale Proportional scale of text
|
1104
1129
|
*/
|
1105
|
-
function textSize(width, height, fontSize) {
|
1130
|
+
function textSize(width, height, fontSize, scale) {
|
1106
1131
|
var stageWidth = parseInt(width, 10);
|
1107
1132
|
var stageHeight = parseInt(height, 10);
|
1108
1133
|
|
1109
1134
|
var bigSide = Math.max(stageWidth, stageHeight);
|
1110
1135
|
var smallSide = Math.min(stageWidth, stageHeight);
|
1111
1136
|
|
1112
|
-
var newHeight = 0.8 * Math.min(smallSide, bigSide *
|
1137
|
+
var newHeight = 0.8 * Math.min(smallSide, bigSide * scale);
|
1113
1138
|
return Math.round(Math.max(fontSize, newHeight));
|
1114
1139
|
}
|
1115
1140
|
|
@@ -1215,13 +1240,14 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1215
1240
|
var renderableImages = [];
|
1216
1241
|
var keys = Object.keys(App.vars.invisibleImages);
|
1217
1242
|
var el;
|
1218
|
-
|
1219
|
-
|
1243
|
+
|
1244
|
+
keys.forEach(function (key) {
|
1245
|
+
el = App.vars.invisibleImages[key];
|
1220
1246
|
if (dimensionCheck(el) && el.nodeName.toLowerCase() == 'img') {
|
1221
1247
|
renderableImages.push(el);
|
1222
|
-
delete App.vars.invisibleImages[
|
1248
|
+
delete App.vars.invisibleImages[key];
|
1223
1249
|
}
|
1224
|
-
}
|
1250
|
+
});
|
1225
1251
|
|
1226
1252
|
if (renderableImages.length) {
|
1227
1253
|
Holder.run({
|
@@ -1229,7 +1255,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1229
1255
|
});
|
1230
1256
|
}
|
1231
1257
|
|
1232
|
-
|
1258
|
+
// Done to prevent 100% CPU usage via aggressive calling of requestAnimationFrame
|
1259
|
+
setTimeout(function () {
|
1260
|
+
global.requestAnimationFrame(visibilityCheck);
|
1261
|
+
}, 10);
|
1233
1262
|
}
|
1234
1263
|
|
1235
1264
|
/**
|
@@ -1312,7 +1341,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1312
1341
|
var stagingTextBBox = stagingText.getBBox();
|
1313
1342
|
|
1314
1343
|
//Get line count and split the string into words
|
1315
|
-
var lineCount = Math.ceil(stagingTextBBox.width /
|
1344
|
+
var lineCount = Math.ceil(stagingTextBBox.width / rootNode.properties.width);
|
1316
1345
|
var words = htgProps.text.split(' ');
|
1317
1346
|
var newlines = htgProps.text.match(/\\n/g);
|
1318
1347
|
lineCount += newlines == null ? 0 : newlines.length;
|
@@ -1356,178 +1385,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1356
1385
|
};
|
1357
1386
|
})();
|
1358
1387
|
|
1359
|
-
var sgCanvasRenderer = (function() {
|
1360
|
-
var canvas = DOM.newEl('canvas');
|
1361
|
-
var ctx = null;
|
1362
|
-
|
1363
|
-
return function(sceneGraph) {
|
1364
|
-
if (ctx == null) {
|
1365
|
-
ctx = canvas.getContext('2d');
|
1366
|
-
}
|
1367
|
-
var root = sceneGraph.root;
|
1368
|
-
canvas.width = App.dpr(root.properties.width);
|
1369
|
-
canvas.height = App.dpr(root.properties.height);
|
1370
|
-
ctx.textBaseline = 'middle';
|
1371
|
-
|
1372
|
-
var bg = root.children.holderBg;
|
1373
|
-
var bgWidth = App.dpr(bg.width);
|
1374
|
-
var bgHeight = App.dpr(bg.height);
|
1375
|
-
//todo: parametrize outline width (e.g. in scene object)
|
1376
|
-
var outlineWidth = 2;
|
1377
|
-
var outlineOffsetWidth = outlineWidth / 2;
|
1378
|
-
|
1379
|
-
ctx.fillStyle = bg.properties.fill;
|
1380
|
-
ctx.fillRect(0, 0, bgWidth, bgHeight);
|
1381
|
-
|
1382
|
-
if (bg.properties.outline) {
|
1383
|
-
//todo: abstract this into a method
|
1384
|
-
ctx.strokeStyle = bg.properties.outline.fill;
|
1385
|
-
ctx.lineWidth = bg.properties.outline.width;
|
1386
|
-
ctx.moveTo(outlineOffsetWidth, outlineOffsetWidth);
|
1387
|
-
// TL, TR, BR, BL
|
1388
|
-
ctx.lineTo(bgWidth - outlineOffsetWidth, outlineOffsetWidth);
|
1389
|
-
ctx.lineTo(bgWidth - outlineOffsetWidth, bgHeight - outlineOffsetWidth);
|
1390
|
-
ctx.lineTo(outlineOffsetWidth, bgHeight - outlineOffsetWidth);
|
1391
|
-
ctx.lineTo(outlineOffsetWidth, outlineOffsetWidth);
|
1392
|
-
// Diagonals
|
1393
|
-
ctx.moveTo(0, outlineOffsetWidth);
|
1394
|
-
ctx.lineTo(bgWidth, bgHeight - outlineOffsetWidth);
|
1395
|
-
ctx.moveTo(0, bgHeight - outlineOffsetWidth);
|
1396
|
-
ctx.lineTo(bgWidth, outlineOffsetWidth);
|
1397
|
-
ctx.stroke();
|
1398
|
-
}
|
1399
|
-
|
1400
|
-
var textGroup = root.children.holderTextGroup;
|
1401
|
-
var tgProps = textGroup.properties;
|
1402
|
-
ctx.font = textGroup.properties.font.weight + ' ' + App.dpr(textGroup.properties.font.size) + textGroup.properties.font.units + ' ' + textGroup.properties.font.family + ', monospace';
|
1403
|
-
ctx.fillStyle = textGroup.properties.fill;
|
1404
|
-
|
1405
|
-
for (var lineKey in textGroup.children) {
|
1406
|
-
var line = textGroup.children[lineKey];
|
1407
|
-
for (var wordKey in line.children) {
|
1408
|
-
var word = line.children[wordKey];
|
1409
|
-
var x = App.dpr(textGroup.x + line.x + word.x);
|
1410
|
-
var y = App.dpr(textGroup.y + line.y + word.y + (textGroup.properties.leading / 2));
|
1411
|
-
|
1412
|
-
ctx.fillText(word.properties.text, x, y);
|
1413
|
-
}
|
1414
|
-
}
|
1415
|
-
|
1416
|
-
return canvas.toDataURL('image/png');
|
1417
|
-
};
|
1418
|
-
})();
|
1419
|
-
|
1420
|
-
var sgSVGRenderer = (function() {
|
1421
|
-
//Prevent IE <9 from initializing SVG renderer
|
1422
|
-
if (!global.XMLSerializer) return;
|
1423
|
-
var xml = DOM.createXML();
|
1424
|
-
var svg = SVG.initSVG(null, 0, 0);
|
1425
|
-
var bgEl = DOM.newEl('rect', SVG_NS);
|
1426
|
-
svg.appendChild(bgEl);
|
1427
|
-
|
1428
|
-
//todo: create a reusable pool for textNodes, resize if more words present
|
1429
|
-
|
1430
|
-
return function(sceneGraph, renderSettings) {
|
1431
|
-
var root = sceneGraph.root;
|
1432
|
-
|
1433
|
-
SVG.initSVG(svg, root.properties.width, root.properties.height);
|
1434
|
-
|
1435
|
-
var groups = svg.querySelectorAll('g');
|
1436
|
-
|
1437
|
-
for (var i = 0; i < groups.length; i++) {
|
1438
|
-
groups[i].parentNode.removeChild(groups[i]);
|
1439
|
-
}
|
1440
|
-
|
1441
|
-
var holderURL = renderSettings.holderSettings.flags.holderURL;
|
1442
|
-
var holderId = 'holder_' + (Number(new Date()) + 32768 + (0 | Math.random() * 32768)).toString(16);
|
1443
|
-
var sceneGroupEl = DOM.newEl('g', SVG_NS);
|
1444
|
-
var textGroup = root.children.holderTextGroup;
|
1445
|
-
var tgProps = textGroup.properties;
|
1446
|
-
var textGroupEl = DOM.newEl('g', SVG_NS);
|
1447
|
-
var tpdata = textGroup.textPositionData;
|
1448
|
-
var textCSSRule = '#' + holderId + ' text { ' +
|
1449
|
-
utils.cssProps({
|
1450
|
-
'fill': tgProps.fill,
|
1451
|
-
'font-weight': tgProps.font.weight,
|
1452
|
-
'font-family': tgProps.font.family + ', monospace',
|
1453
|
-
'font-size': tgProps.font.size + tgProps.font.units
|
1454
|
-
}) + ' } ';
|
1455
|
-
var commentNode = xml.createComment('\n' + 'Source URL: ' + holderURL + generatorComment);
|
1456
|
-
var holderCSS = xml.createCDATASection(textCSSRule);
|
1457
|
-
var styleEl = svg.querySelector('style');
|
1458
|
-
var bg = root.children.holderBg;
|
1459
|
-
|
1460
|
-
DOM.setAttr(sceneGroupEl, {
|
1461
|
-
id: holderId
|
1462
|
-
});
|
1463
|
-
|
1464
|
-
svg.insertBefore(commentNode, svg.firstChild);
|
1465
|
-
styleEl.appendChild(holderCSS);
|
1466
|
-
|
1467
|
-
sceneGroupEl.appendChild(bgEl);
|
1468
|
-
|
1469
|
-
//todo: abstract this into a cross-browser SVG outline method
|
1470
|
-
if (bg.properties.outline) {
|
1471
|
-
var outlineEl = DOM.newEl('path', SVG_NS);
|
1472
|
-
var outlineWidth = bg.properties.outline.width;
|
1473
|
-
var outlineOffsetWidth = outlineWidth / 2;
|
1474
|
-
DOM.setAttr(outlineEl, {
|
1475
|
-
'd': [
|
1476
|
-
'M', outlineOffsetWidth, outlineOffsetWidth,
|
1477
|
-
'H', bg.width - outlineOffsetWidth,
|
1478
|
-
'V', bg.height - outlineOffsetWidth,
|
1479
|
-
'H', outlineOffsetWidth,
|
1480
|
-
'V', 0,
|
1481
|
-
'M', 0, outlineOffsetWidth,
|
1482
|
-
'L', bg.width, bg.height - outlineOffsetWidth,
|
1483
|
-
'M', 0, bg.height - outlineOffsetWidth,
|
1484
|
-
'L', bg.width, outlineOffsetWidth
|
1485
|
-
].join(' '),
|
1486
|
-
'stroke-width': bg.properties.outline.width,
|
1487
|
-
'stroke': bg.properties.outline.fill,
|
1488
|
-
'fill': 'none'
|
1489
|
-
});
|
1490
|
-
sceneGroupEl.appendChild(outlineEl);
|
1491
|
-
}
|
1492
|
-
|
1493
|
-
sceneGroupEl.appendChild(textGroupEl);
|
1494
|
-
svg.appendChild(sceneGroupEl);
|
1495
|
-
|
1496
|
-
DOM.setAttr(bgEl, {
|
1497
|
-
'width': bg.width,
|
1498
|
-
'height': bg.height,
|
1499
|
-
'fill': bg.properties.fill
|
1500
|
-
});
|
1501
|
-
|
1502
|
-
textGroup.y += tpdata.boundingBox.height * 0.8;
|
1503
|
-
|
1504
|
-
for (var lineKey in textGroup.children) {
|
1505
|
-
var line = textGroup.children[lineKey];
|
1506
|
-
for (var wordKey in line.children) {
|
1507
|
-
var word = line.children[wordKey];
|
1508
|
-
var x = textGroup.x + line.x + word.x;
|
1509
|
-
var y = textGroup.y + line.y + word.y;
|
1510
|
-
|
1511
|
-
var textEl = DOM.newEl('text', SVG_NS);
|
1512
|
-
var textNode = document.createTextNode(null);
|
1513
|
-
|
1514
|
-
DOM.setAttr(textEl, {
|
1515
|
-
'x': x,
|
1516
|
-
'y': y
|
1517
|
-
});
|
1518
|
-
|
1519
|
-
textNode.nodeValue = word.properties.text;
|
1520
|
-
textEl.appendChild(textNode);
|
1521
|
-
textGroupEl.appendChild(textEl);
|
1522
|
-
}
|
1523
|
-
}
|
1524
|
-
|
1525
|
-
//todo: factor the background check up the chain, perhaps only return reference
|
1526
|
-
var svgString = SVG.svgStringToDataURI(SVG.serializeSVG(svg, renderSettings.engineSettings), renderSettings.mode === 'background');
|
1527
|
-
return svgString;
|
1528
|
-
};
|
1529
|
-
})();
|
1530
|
-
|
1531
1388
|
//Helpers
|
1532
1389
|
|
1533
1390
|
/**
|
@@ -1575,10 +1432,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1575
1432
|
renderers: ['html', 'canvas', 'svg']
|
1576
1433
|
};
|
1577
1434
|
|
1578
|
-
App.dpr = function(val) {
|
1579
|
-
return val * App.setup.ratio;
|
1580
|
-
};
|
1581
|
-
|
1582
1435
|
//Properties modified during runtime
|
1583
1436
|
|
1584
1437
|
App.vars = {
|
@@ -1594,27 +1447,15 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1594
1447
|
//Pre-flight
|
1595
1448
|
|
1596
1449
|
(function() {
|
1597
|
-
var devicePixelRatio = 1,
|
1598
|
-
backingStoreRatio = 1;
|
1599
|
-
|
1600
1450
|
var canvas = DOM.newEl('canvas');
|
1601
|
-
var ctx = null;
|
1602
1451
|
|
1603
1452
|
if (canvas.getContext) {
|
1604
1453
|
if (canvas.toDataURL('image/png').indexOf('data:image/png') != -1) {
|
1605
1454
|
App.setup.renderer = 'canvas';
|
1606
|
-
ctx = canvas.getContext('2d');
|
1607
1455
|
App.setup.supportsCanvas = true;
|
1608
1456
|
}
|
1609
1457
|
}
|
1610
1458
|
|
1611
|
-
if (App.setup.supportsCanvas) {
|
1612
|
-
devicePixelRatio = global.devicePixelRatio || 1;
|
1613
|
-
backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
|
1614
|
-
}
|
1615
|
-
|
1616
|
-
App.setup.ratio = devicePixelRatio / backingStoreRatio;
|
1617
|
-
|
1618
1459
|
if (!!document.createElementNS && !!document.createElementNS(SVG_NS, 'svg').createSVGRect) {
|
1619
1460
|
App.setup.renderer = 'svg';
|
1620
1461
|
App.setup.supportsSVG = true;
|
@@ -1650,131 +1491,23 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1650
1491
|
|
1651
1492
|
/***/ },
|
1652
1493
|
/* 2 */
|
1653
|
-
/***/ function(module, exports
|
1654
|
-
|
1655
|
-
//Modified version of component/querystring
|
1656
|
-
//Changes: updated dependencies, dot notation parsing, JSHint fixes
|
1657
|
-
//Fork at https://github.com/imsky/querystring
|
1658
|
-
|
1659
|
-
/**
|
1660
|
-
* Module dependencies.
|
1661
|
-
*/
|
1662
|
-
|
1663
|
-
var encode = encodeURIComponent;
|
1664
|
-
var decode = decodeURIComponent;
|
1665
|
-
var trim = __webpack_require__(10);
|
1666
|
-
var type = __webpack_require__(9);
|
1494
|
+
/***/ function(module, exports) {
|
1667
1495
|
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
/**
|
1672
|
-
* Parse the given query `str`.
|
1496
|
+
/*!
|
1497
|
+
* onDomReady.js 1.4.0 (c) 2013 Tubal Martin - MIT license
|
1673
1498
|
*
|
1674
|
-
*
|
1675
|
-
* @return {Object}
|
1676
|
-
* @api public
|
1499
|
+
* Specially modified to work with Holder.js
|
1677
1500
|
*/
|
1678
1501
|
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
for (var i = 0; i < pairs.length; i++) {
|
1689
|
-
var parts = pairs[i].split('=');
|
1690
|
-
var key = decode(parts[0]);
|
1691
|
-
var m, ctx, prop;
|
1692
|
-
|
1693
|
-
if (m = arrayRegex.exec(key)) {
|
1694
|
-
obj[m[1]] = obj[m[1]] || [];
|
1695
|
-
obj[m[1]][m[2]] = decode(parts[1]);
|
1696
|
-
continue;
|
1697
|
-
}
|
1698
|
-
|
1699
|
-
if (m = objectRegex.test(key)) {
|
1700
|
-
m = key.split('.');
|
1701
|
-
ctx = obj;
|
1702
|
-
|
1703
|
-
while (m.length) {
|
1704
|
-
prop = m.shift();
|
1705
|
-
|
1706
|
-
if (!prop.length) continue;
|
1707
|
-
|
1708
|
-
if (!ctx[prop]) {
|
1709
|
-
ctx[prop] = {};
|
1710
|
-
} else if (ctx[prop] && typeof ctx[prop] !== 'object') {
|
1711
|
-
break;
|
1712
|
-
}
|
1713
|
-
|
1714
|
-
if (!m.length) {
|
1715
|
-
ctx[prop] = decode(parts[1]);
|
1716
|
-
}
|
1717
|
-
|
1718
|
-
ctx = ctx[prop];
|
1719
|
-
}
|
1720
|
-
|
1721
|
-
continue;
|
1722
|
-
}
|
1723
|
-
|
1724
|
-
obj[parts[0]] = null == parts[1] ? '' : decode(parts[1]);
|
1725
|
-
}
|
1726
|
-
|
1727
|
-
return obj;
|
1728
|
-
};
|
1729
|
-
|
1730
|
-
/**
|
1731
|
-
* Stringify the given `obj`.
|
1732
|
-
*
|
1733
|
-
* @param {Object} obj
|
1734
|
-
* @return {String}
|
1735
|
-
* @api public
|
1736
|
-
*/
|
1737
|
-
|
1738
|
-
exports.stringify = function(obj){
|
1739
|
-
if (!obj) return '';
|
1740
|
-
var pairs = [];
|
1741
|
-
|
1742
|
-
for (var key in obj) {
|
1743
|
-
var value = obj[key];
|
1744
|
-
|
1745
|
-
if ('array' == type(value)) {
|
1746
|
-
for (var i = 0; i < value.length; ++i) {
|
1747
|
-
pairs.push(encode(key + '[' + i + ']') + '=' + encode(value[i]));
|
1748
|
-
}
|
1749
|
-
continue;
|
1750
|
-
}
|
1751
|
-
|
1752
|
-
pairs.push(encode(key) + '=' + encode(obj[key]));
|
1753
|
-
}
|
1754
|
-
|
1755
|
-
return pairs.join('&');
|
1756
|
-
};
|
1757
|
-
|
1758
|
-
|
1759
|
-
/***/ },
|
1760
|
-
/* 3 */
|
1761
|
-
/***/ function(module, exports, __webpack_require__) {
|
1762
|
-
|
1763
|
-
/*!
|
1764
|
-
* onDomReady.js 1.4.0 (c) 2013 Tubal Martin - MIT license
|
1765
|
-
*
|
1766
|
-
* Specially modified to work with Holder.js
|
1767
|
-
*/
|
1768
|
-
|
1769
|
-
function _onDomReady(win) {
|
1770
|
-
//Lazy loading fix for Firefox < 3.6
|
1771
|
-
//http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
|
1772
|
-
if (document.readyState == null && document.addEventListener) {
|
1773
|
-
document.addEventListener("DOMContentLoaded", function DOMContentLoaded() {
|
1774
|
-
document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
|
1775
|
-
document.readyState = "complete";
|
1776
|
-
}, false);
|
1777
|
-
document.readyState = "loading";
|
1502
|
+
function _onDomReady(win) {
|
1503
|
+
//Lazy loading fix for Firefox < 3.6
|
1504
|
+
//http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
|
1505
|
+
if (document.readyState == null && document.addEventListener) {
|
1506
|
+
document.addEventListener("DOMContentLoaded", function DOMContentLoaded() {
|
1507
|
+
document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
|
1508
|
+
document.readyState = "complete";
|
1509
|
+
}, false);
|
1510
|
+
document.readyState = "loading";
|
1778
1511
|
}
|
1779
1512
|
|
1780
1513
|
var doc = win.document,
|
@@ -1917,9 +1650,177 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
1917
1650
|
module.exports = typeof window !== "undefined" && _onDomReady(window);
|
1918
1651
|
|
1919
1652
|
/***/ },
|
1920
|
-
/*
|
1653
|
+
/* 3 */
|
1921
1654
|
/***/ function(module, exports, __webpack_require__) {
|
1922
1655
|
|
1656
|
+
//Modified version of component/querystring
|
1657
|
+
//Changes: updated dependencies, dot notation parsing, JSHint fixes
|
1658
|
+
//Fork at https://github.com/imsky/querystring
|
1659
|
+
|
1660
|
+
/**
|
1661
|
+
* Module dependencies.
|
1662
|
+
*/
|
1663
|
+
|
1664
|
+
var encode = encodeURIComponent;
|
1665
|
+
var decode = decodeURIComponent;
|
1666
|
+
var trim = __webpack_require__(4);
|
1667
|
+
var type = __webpack_require__(5);
|
1668
|
+
|
1669
|
+
var arrayRegex = /(\w+)\[(\d+)\]/;
|
1670
|
+
var objectRegex = /\w+\.\w+/;
|
1671
|
+
|
1672
|
+
/**
|
1673
|
+
* Parse the given query `str`.
|
1674
|
+
*
|
1675
|
+
* @param {String} str
|
1676
|
+
* @return {Object}
|
1677
|
+
* @api public
|
1678
|
+
*/
|
1679
|
+
|
1680
|
+
exports.parse = function(str){
|
1681
|
+
if ('string' !== typeof str) return {};
|
1682
|
+
|
1683
|
+
str = trim(str);
|
1684
|
+
if ('' === str) return {};
|
1685
|
+
if ('?' === str.charAt(0)) str = str.slice(1);
|
1686
|
+
|
1687
|
+
var obj = {};
|
1688
|
+
var pairs = str.split('&');
|
1689
|
+
for (var i = 0; i < pairs.length; i++) {
|
1690
|
+
var parts = pairs[i].split('=');
|
1691
|
+
var key = decode(parts[0]);
|
1692
|
+
var m, ctx, prop;
|
1693
|
+
|
1694
|
+
if (m = arrayRegex.exec(key)) {
|
1695
|
+
obj[m[1]] = obj[m[1]] || [];
|
1696
|
+
obj[m[1]][m[2]] = decode(parts[1]);
|
1697
|
+
continue;
|
1698
|
+
}
|
1699
|
+
|
1700
|
+
if (m = objectRegex.test(key)) {
|
1701
|
+
m = key.split('.');
|
1702
|
+
ctx = obj;
|
1703
|
+
|
1704
|
+
while (m.length) {
|
1705
|
+
prop = m.shift();
|
1706
|
+
|
1707
|
+
if (!prop.length) continue;
|
1708
|
+
|
1709
|
+
if (!ctx[prop]) {
|
1710
|
+
ctx[prop] = {};
|
1711
|
+
} else if (ctx[prop] && typeof ctx[prop] !== 'object') {
|
1712
|
+
break;
|
1713
|
+
}
|
1714
|
+
|
1715
|
+
if (!m.length) {
|
1716
|
+
ctx[prop] = decode(parts[1]);
|
1717
|
+
}
|
1718
|
+
|
1719
|
+
ctx = ctx[prop];
|
1720
|
+
}
|
1721
|
+
|
1722
|
+
continue;
|
1723
|
+
}
|
1724
|
+
|
1725
|
+
obj[parts[0]] = null == parts[1] ? '' : decode(parts[1]);
|
1726
|
+
}
|
1727
|
+
|
1728
|
+
return obj;
|
1729
|
+
};
|
1730
|
+
|
1731
|
+
/**
|
1732
|
+
* Stringify the given `obj`.
|
1733
|
+
*
|
1734
|
+
* @param {Object} obj
|
1735
|
+
* @return {String}
|
1736
|
+
* @api public
|
1737
|
+
*/
|
1738
|
+
|
1739
|
+
exports.stringify = function(obj){
|
1740
|
+
if (!obj) return '';
|
1741
|
+
var pairs = [];
|
1742
|
+
|
1743
|
+
for (var key in obj) {
|
1744
|
+
var value = obj[key];
|
1745
|
+
|
1746
|
+
if ('array' == type(value)) {
|
1747
|
+
for (var i = 0; i < value.length; ++i) {
|
1748
|
+
pairs.push(encode(key + '[' + i + ']') + '=' + encode(value[i]));
|
1749
|
+
}
|
1750
|
+
continue;
|
1751
|
+
}
|
1752
|
+
|
1753
|
+
pairs.push(encode(key) + '=' + encode(obj[key]));
|
1754
|
+
}
|
1755
|
+
|
1756
|
+
return pairs.join('&');
|
1757
|
+
};
|
1758
|
+
|
1759
|
+
|
1760
|
+
/***/ },
|
1761
|
+
/* 4 */
|
1762
|
+
/***/ function(module, exports) {
|
1763
|
+
|
1764
|
+
|
1765
|
+
exports = module.exports = trim;
|
1766
|
+
|
1767
|
+
function trim(str){
|
1768
|
+
return str.replace(/^\s*|\s*$/g, '');
|
1769
|
+
}
|
1770
|
+
|
1771
|
+
exports.left = function(str){
|
1772
|
+
return str.replace(/^\s*/, '');
|
1773
|
+
};
|
1774
|
+
|
1775
|
+
exports.right = function(str){
|
1776
|
+
return str.replace(/\s*$/, '');
|
1777
|
+
};
|
1778
|
+
|
1779
|
+
|
1780
|
+
/***/ },
|
1781
|
+
/* 5 */
|
1782
|
+
/***/ function(module, exports) {
|
1783
|
+
|
1784
|
+
/**
|
1785
|
+
* toString ref.
|
1786
|
+
*/
|
1787
|
+
|
1788
|
+
var toString = Object.prototype.toString;
|
1789
|
+
|
1790
|
+
/**
|
1791
|
+
* Return the type of `val`.
|
1792
|
+
*
|
1793
|
+
* @param {Mixed} val
|
1794
|
+
* @return {String}
|
1795
|
+
* @api public
|
1796
|
+
*/
|
1797
|
+
|
1798
|
+
module.exports = function(val){
|
1799
|
+
switch (toString.call(val)) {
|
1800
|
+
case '[object Date]': return 'date';
|
1801
|
+
case '[object RegExp]': return 'regexp';
|
1802
|
+
case '[object Arguments]': return 'arguments';
|
1803
|
+
case '[object Array]': return 'array';
|
1804
|
+
case '[object Error]': return 'error';
|
1805
|
+
}
|
1806
|
+
|
1807
|
+
if (val === null) return 'null';
|
1808
|
+
if (val === undefined) return 'undefined';
|
1809
|
+
if (val !== val) return 'nan';
|
1810
|
+
if (val && val.nodeType === 1) return 'element';
|
1811
|
+
|
1812
|
+
val = val.valueOf
|
1813
|
+
? val.valueOf()
|
1814
|
+
: Object.prototype.valueOf.apply(val)
|
1815
|
+
|
1816
|
+
return typeof val;
|
1817
|
+
};
|
1818
|
+
|
1819
|
+
|
1820
|
+
/***/ },
|
1821
|
+
/* 6 */
|
1822
|
+
/***/ function(module, exports) {
|
1823
|
+
|
1923
1824
|
var SceneGraph = function(sceneProperties) {
|
1924
1825
|
var nodeCount = 1;
|
1925
1826
|
|
@@ -2028,10 +1929,10 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2028
1929
|
|
2029
1930
|
|
2030
1931
|
/***/ },
|
2031
|
-
/*
|
2032
|
-
/***/ function(module, exports
|
1932
|
+
/* 7 */
|
1933
|
+
/***/ function(module, exports) {
|
2033
1934
|
|
2034
|
-
/**
|
1935
|
+
/* WEBPACK VAR INJECTION */(function(global) {/**
|
2035
1936
|
* Shallow object clone and merge
|
2036
1937
|
*
|
2037
1938
|
* @param a Object A
|
@@ -2148,12 +2049,69 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2148
2049
|
return !!val;
|
2149
2050
|
};
|
2150
2051
|
|
2052
|
+
/**
|
2053
|
+
* Parses input into a well-formed CSS color
|
2054
|
+
* @param val
|
2055
|
+
*/
|
2056
|
+
exports.parseColor = function(val) {
|
2057
|
+
var hexre = /(^(?:#?)[0-9a-f]{6}$)|(^(?:#?)[0-9a-f]{3}$)/i;
|
2058
|
+
var rgbre = /^rgb\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;
|
2059
|
+
var rgbare = /^rgba\((\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(0\.\d{1,}|1)\)$/;
|
2060
|
+
|
2061
|
+
var match = val.match(hexre);
|
2062
|
+
var retval;
|
2063
|
+
|
2064
|
+
if (match !== null) {
|
2065
|
+
retval = match[1] || match[2];
|
2066
|
+
if (retval[0] !== '#') {
|
2067
|
+
return '#' + retval;
|
2068
|
+
} else {
|
2069
|
+
return retval;
|
2070
|
+
}
|
2071
|
+
}
|
2072
|
+
|
2073
|
+
match = val.match(rgbre);
|
2074
|
+
|
2075
|
+
if (match !== null) {
|
2076
|
+
retval = 'rgb(' + match.slice(1).join(',') + ')';
|
2077
|
+
return retval;
|
2078
|
+
}
|
2079
|
+
|
2080
|
+
match = val.match(rgbare);
|
2081
|
+
|
2082
|
+
if (match !== null) {
|
2083
|
+
retval = 'rgba(' + match.slice(1).join(',') + ')';
|
2084
|
+
return retval;
|
2085
|
+
}
|
2086
|
+
|
2087
|
+
return null;
|
2088
|
+
};
|
2089
|
+
|
2090
|
+
/**
|
2091
|
+
* Provides the correct scaling ratio for canvas drawing operations on HiDPI screens (e.g. Retina displays)
|
2092
|
+
*/
|
2093
|
+
exports.canvasRatio = function () {
|
2094
|
+
var devicePixelRatio = 1;
|
2095
|
+
var backingStoreRatio = 1;
|
2096
|
+
|
2097
|
+
if (global.document) {
|
2098
|
+
var canvas = global.document.createElement('canvas');
|
2099
|
+
if (canvas.getContext) {
|
2100
|
+
var ctx = canvas.getContext('2d');
|
2101
|
+
devicePixelRatio = global.devicePixelRatio || 1;
|
2102
|
+
backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
|
2103
|
+
}
|
2104
|
+
}
|
2105
|
+
|
2106
|
+
return devicePixelRatio / backingStoreRatio;
|
2107
|
+
};
|
2108
|
+
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
2151
2109
|
|
2152
2110
|
/***/ },
|
2153
|
-
/*
|
2111
|
+
/* 8 */
|
2154
2112
|
/***/ function(module, exports, __webpack_require__) {
|
2155
2113
|
|
2156
|
-
/* WEBPACK VAR INJECTION */(function(global) {var DOM = __webpack_require__(
|
2114
|
+
/* WEBPACK VAR INJECTION */(function(global) {var DOM = __webpack_require__(9);
|
2157
2115
|
|
2158
2116
|
var SVG_NS = 'http://www.w3.org/2000/svg';
|
2159
2117
|
var NODE_TYPE_COMMENT = 8;
|
@@ -2161,7 +2119,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2161
2119
|
/**
|
2162
2120
|
* Generic SVG element creation function
|
2163
2121
|
*
|
2164
|
-
* @private
|
2165
2122
|
* @param svg SVG context, set to null if new
|
2166
2123
|
* @param width Document width
|
2167
2124
|
* @param height Document height
|
@@ -2227,7 +2184,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2227
2184
|
|
2228
2185
|
return function(svgString, base64) {
|
2229
2186
|
if (base64) {
|
2230
|
-
return base64Prefix + btoa(unescape(encodeURIComponent(svgString)));
|
2187
|
+
return base64Prefix + btoa(global.unescape(encodeURIComponent(svgString)));
|
2231
2188
|
} else {
|
2232
2189
|
return rawPrefix + encodeURIComponent(svgString);
|
2233
2190
|
}
|
@@ -2237,7 +2194,6 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2237
2194
|
/**
|
2238
2195
|
* Returns serialized SVG with XML processing instructions
|
2239
2196
|
*
|
2240
|
-
* @private
|
2241
2197
|
* @param svg SVG context
|
2242
2198
|
* @param stylesheets CSS stylesheets to include
|
2243
2199
|
*/
|
@@ -2268,13 +2224,12 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2268
2224
|
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
2269
2225
|
|
2270
2226
|
/***/ },
|
2271
|
-
/*
|
2272
|
-
/***/ function(module, exports
|
2227
|
+
/* 9 */
|
2228
|
+
/***/ function(module, exports) {
|
2273
2229
|
|
2274
2230
|
/* WEBPACK VAR INJECTION */(function(global) {/**
|
2275
2231
|
* Generic new DOM element function
|
2276
2232
|
*
|
2277
|
-
* @private
|
2278
2233
|
* @param tag Tag to create
|
2279
2234
|
* @param namespace Optional namespace value
|
2280
2235
|
*/
|
@@ -2282,20 +2237,19 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2282
2237
|
if (!global.document) return;
|
2283
2238
|
|
2284
2239
|
if (namespace == null) {
|
2285
|
-
return document.createElement(tag);
|
2240
|
+
return global.document.createElement(tag);
|
2286
2241
|
} else {
|
2287
|
-
return document.createElementNS(namespace, tag);
|
2242
|
+
return global.document.createElementNS(namespace, tag);
|
2288
2243
|
}
|
2289
2244
|
};
|
2290
2245
|
|
2291
2246
|
/**
|
2292
2247
|
* Generic setAttribute function
|
2293
2248
|
*
|
2294
|
-
* @private
|
2295
2249
|
* @param el Reference to DOM element
|
2296
2250
|
* @param attrs Object with attribute keys and values
|
2297
2251
|
*/
|
2298
|
-
exports.setAttr = function(el, attrs) {
|
2252
|
+
exports.setAttr = function (el, attrs) {
|
2299
2253
|
for (var a in attrs) {
|
2300
2254
|
el.setAttribute(a, attrs[a]);
|
2301
2255
|
}
|
@@ -2330,20 +2284,26 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2330
2284
|
} else if (val === null) {
|
2331
2285
|
retval = [];
|
2332
2286
|
}
|
2287
|
+
|
2288
|
+
retval = Array.prototype.slice.call(retval);
|
2289
|
+
|
2333
2290
|
return retval;
|
2334
2291
|
};
|
2335
2292
|
|
2336
2293
|
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }())))
|
2337
2294
|
|
2338
2295
|
/***/ },
|
2339
|
-
/*
|
2340
|
-
/***/ function(module, exports
|
2296
|
+
/* 10 */
|
2297
|
+
/***/ function(module, exports) {
|
2341
2298
|
|
2342
|
-
var Color = function
|
2343
|
-
//todo: support array->color conversion
|
2299
|
+
var Color = function(color, options) {
|
2344
2300
|
//todo: support rgba, hsla, and rrggbbaa notation
|
2301
|
+
//todo: use CIELAB internally
|
2302
|
+
//todo: add clamp function (with sign)
|
2345
2303
|
if (typeof color !== 'string') return;
|
2346
2304
|
|
2305
|
+
this.original = color;
|
2306
|
+
|
2347
2307
|
if (color.charAt(0) === '#') {
|
2348
2308
|
color = color.slice(1);
|
2349
2309
|
}
|
@@ -2358,58 +2318,119 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2358
2318
|
|
2359
2319
|
this.alpha = 1;
|
2360
2320
|
|
2361
|
-
if (options) {
|
2362
|
-
this.alpha = options.alpha
|
2321
|
+
if (options && options.alpha) {
|
2322
|
+
this.alpha = options.alpha;
|
2363
2323
|
}
|
2364
2324
|
|
2365
|
-
|
2325
|
+
this.set(parseInt(color, 16));
|
2366
2326
|
};
|
2367
2327
|
|
2368
|
-
|
2369
|
-
|
2328
|
+
//todo: jsdocs
|
2329
|
+
Color.rgb2hex = function(r, g, b) {
|
2330
|
+
function format (decimal) {
|
2331
|
+
var hex = (decimal | 0).toString(16);
|
2332
|
+
if (decimal < 16) {
|
2333
|
+
hex = '0' + hex;
|
2334
|
+
}
|
2335
|
+
return hex;
|
2336
|
+
}
|
2337
|
+
|
2338
|
+
return [r, g, b].map(format).join('');
|
2339
|
+
};
|
2340
|
+
|
2341
|
+
//todo: jsdocs
|
2342
|
+
Color.hsl2rgb = function (h, s, l) {
|
2343
|
+
var H = h / 60;
|
2344
|
+
var C = (1 - Math.abs(2 * l - 1)) * s;
|
2345
|
+
var X = C * (1 - Math.abs(parseInt(H) % 2 - 1));
|
2346
|
+
var m = l - (C / 2);
|
2347
|
+
|
2348
|
+
var r = 0, g = 0, b = 0;
|
2349
|
+
|
2350
|
+
if (H >= 0 && H < 1) {
|
2351
|
+
r = C;
|
2352
|
+
g = X;
|
2353
|
+
} else if (H >= 1 && H < 2) {
|
2354
|
+
r = X;
|
2355
|
+
g = C;
|
2356
|
+
} else if (H >= 2 && H < 3) {
|
2357
|
+
g = C;
|
2358
|
+
b = X;
|
2359
|
+
} else if (H >= 3 && H < 4) {
|
2360
|
+
g = X;
|
2361
|
+
b = C;
|
2362
|
+
} else if (H >= 4 && H < 5) {
|
2363
|
+
r = X;
|
2364
|
+
b = C;
|
2365
|
+
} else if (H >= 5 && H < 6) {
|
2366
|
+
r = C;
|
2367
|
+
b = X;
|
2368
|
+
}
|
2369
|
+
|
2370
|
+
r += m;
|
2371
|
+
g += m;
|
2372
|
+
b += m;
|
2373
|
+
|
2374
|
+
r = parseInt(r * 255);
|
2375
|
+
g = parseInt(g * 255);
|
2376
|
+
b = parseInt(b * 255);
|
2377
|
+
|
2378
|
+
return [r, g, b];
|
2370
2379
|
};
|
2371
2380
|
|
2372
2381
|
/**
|
2373
2382
|
* Sets the color from a raw RGB888 integer
|
2374
2383
|
* @param raw RGB888 representation of color
|
2375
2384
|
*/
|
2376
|
-
|
2377
|
-
|
2378
|
-
|
2379
|
-
|
2380
|
-
this.raw =
|
2385
|
+
//todo: refactor into a static method
|
2386
|
+
//todo: factor out individual color spaces
|
2387
|
+
//todo: add HSL, CIELAB, and CIELUV
|
2388
|
+
Color.prototype.set = function (val) {
|
2389
|
+
this.raw = val;
|
2381
2390
|
|
2382
|
-
|
2383
|
-
|
2384
|
-
|
2391
|
+
var r = (this.raw & 0xFF0000) >> 16;
|
2392
|
+
var g = (this.raw & 0x00FF00) >> 8;
|
2393
|
+
var b = (this.raw & 0x0000FF);
|
2385
2394
|
|
2386
2395
|
// BT.709
|
2387
|
-
|
2388
|
-
|
2389
|
-
|
2396
|
+
var y = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
2397
|
+
var u = -0.09991 * r - 0.33609 * g + 0.436 * b;
|
2398
|
+
var v = 0.615 * r - 0.55861 * g - 0.05639 * b;
|
2399
|
+
|
2400
|
+
this.rgb = {
|
2401
|
+
r: r,
|
2402
|
+
g: g,
|
2403
|
+
b: b
|
2404
|
+
};
|
2405
|
+
|
2406
|
+
this.yuv = {
|
2407
|
+
y: y,
|
2408
|
+
u: u,
|
2409
|
+
v: v
|
2410
|
+
};
|
2390
2411
|
|
2391
2412
|
return this;
|
2392
|
-
}
|
2413
|
+
};
|
2393
2414
|
|
2394
2415
|
/**
|
2395
2416
|
* Lighten or darken a color
|
2396
2417
|
* @param multiplier Amount to lighten or darken (-1 to 1)
|
2397
2418
|
*/
|
2398
|
-
Color.prototype.lighten = function
|
2399
|
-
var
|
2400
|
-
var
|
2401
|
-
var
|
2402
|
-
|
2403
|
-
var
|
2404
|
-
|
2405
|
-
return new Color(
|
2419
|
+
Color.prototype.lighten = function(multiplier) {
|
2420
|
+
var cm = Math.min(1, Math.max(0, Math.abs(multiplier))) * (multiplier < 0 ? -1 : 1);
|
2421
|
+
var bm = (255 * cm) | 0;
|
2422
|
+
var cr = Math.min(255, Math.max(0, this.rgb.r + bm));
|
2423
|
+
var cg = Math.min(255, Math.max(0, this.rgb.g + bm));
|
2424
|
+
var cb = Math.min(255, Math.max(0, this.rgb.b + bm));
|
2425
|
+
var hex = Color.rgb2hex(cr, cg, cb);
|
2426
|
+
return new Color(hex);
|
2406
2427
|
};
|
2407
2428
|
|
2408
2429
|
/**
|
2409
2430
|
* Output color in hex format
|
2410
2431
|
* @param addHash Add a hash character to the beginning of the output
|
2411
|
-
*/
|
2412
|
-
Color.prototype.toHex = function
|
2432
|
+
*/
|
2433
|
+
Color.prototype.toHex = function(addHash) {
|
2413
2434
|
return (addHash ? '#' : '') + this.raw.toString(16);
|
2414
2435
|
};
|
2415
2436
|
|
@@ -2417,7 +2438,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2417
2438
|
* Returns whether or not current color is lighter than another color
|
2418
2439
|
* @param color Color to compare against
|
2419
2440
|
*/
|
2420
|
-
Color.prototype.lighterThan = function
|
2441
|
+
Color.prototype.lighterThan = function(color) {
|
2421
2442
|
if (!(color instanceof Color)) {
|
2422
2443
|
color = new Color(color);
|
2423
2444
|
}
|
@@ -2430,7 +2451,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2430
2451
|
* @param color Color to mix with
|
2431
2452
|
* @param multiplier How much to mix with the other color
|
2432
2453
|
*/
|
2433
|
-
|
2454
|
+
/*
|
2434
2455
|
Color.prototype.mix = function (color, multiplier) {
|
2435
2456
|
if (!(color instanceof Color)) {
|
2436
2457
|
color = new Color(color);
|
@@ -2459,8 +2480,8 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2459
2480
|
* Returns the result of blending another color on top of current color with alpha
|
2460
2481
|
* @param color Color to blend on top of current color, i.e. "Ca"
|
2461
2482
|
*/
|
2462
|
-
|
2463
|
-
Color.prototype.blendAlpha = function
|
2483
|
+
//todo: see if .blendAlpha can be merged into .mix
|
2484
|
+
Color.prototype.blendAlpha = function(color) {
|
2464
2485
|
if (!(color instanceof Color)) {
|
2465
2486
|
color = new Color(color);
|
2466
2487
|
}
|
@@ -2473,71 +2494,480 @@ return /******/ (function(modules) { // webpackBootstrap
|
|
2473
2494
|
var g = Ca.alpha * Ca.rgb.g + (1 - Ca.alpha) * Cb.rgb.g;
|
2474
2495
|
var b = Ca.alpha * Ca.rgb.b + (1 - Ca.alpha) * Cb.rgb.b;
|
2475
2496
|
|
2476
|
-
return new Color(Color.
|
2497
|
+
return new Color(Color.rgb2hex(r, g, b));
|
2477
2498
|
};
|
2478
2499
|
|
2479
2500
|
module.exports = Color;
|
2480
2501
|
|
2481
2502
|
|
2482
2503
|
/***/ },
|
2483
|
-
/*
|
2504
|
+
/* 11 */
|
2505
|
+
/***/ function(module, exports) {
|
2506
|
+
|
2507
|
+
module.exports = {
|
2508
|
+
'version': '2.9.0',
|
2509
|
+
'svg_ns': 'http://www.w3.org/2000/svg'
|
2510
|
+
};
|
2511
|
+
|
2512
|
+
/***/ },
|
2513
|
+
/* 12 */
|
2514
|
+
/***/ function(module, exports, __webpack_require__) {
|
2515
|
+
|
2516
|
+
var shaven = __webpack_require__(13);
|
2517
|
+
|
2518
|
+
var SVG = __webpack_require__(8);
|
2519
|
+
var constants = __webpack_require__(11);
|
2520
|
+
var utils = __webpack_require__(7);
|
2521
|
+
|
2522
|
+
var SVG_NS = constants.svg_ns;
|
2523
|
+
|
2524
|
+
var templates = {
|
2525
|
+
'element': function (options) {
|
2526
|
+
var tag = options.tag;
|
2527
|
+
var content = options.content || '';
|
2528
|
+
delete options.tag;
|
2529
|
+
delete options.content;
|
2530
|
+
return [tag, content, options];
|
2531
|
+
}
|
2532
|
+
};
|
2533
|
+
|
2534
|
+
//todo: deprecate tag arg, infer tag from shape object
|
2535
|
+
function convertShape (shape, tag) {
|
2536
|
+
return templates.element({
|
2537
|
+
'tag': tag,
|
2538
|
+
'width': shape.width,
|
2539
|
+
'height': shape.height,
|
2540
|
+
'fill': shape.properties.fill
|
2541
|
+
});
|
2542
|
+
}
|
2543
|
+
|
2544
|
+
function textCss (properties) {
|
2545
|
+
return utils.cssProps({
|
2546
|
+
'fill': properties.fill,
|
2547
|
+
'font-weight': properties.font.weight,
|
2548
|
+
'font-family': properties.font.family + ', monospace',
|
2549
|
+
'font-size': properties.font.size + properties.font.units
|
2550
|
+
});
|
2551
|
+
}
|
2552
|
+
|
2553
|
+
function outlinePath (bgWidth, bgHeight, outlineWidth) {
|
2554
|
+
var outlineOffsetWidth = outlineWidth / 2;
|
2555
|
+
|
2556
|
+
return [
|
2557
|
+
'M', outlineOffsetWidth, outlineOffsetWidth,
|
2558
|
+
'H', bgWidth - outlineOffsetWidth,
|
2559
|
+
'V', bgHeight - outlineOffsetWidth,
|
2560
|
+
'H', outlineOffsetWidth,
|
2561
|
+
'V', 0,
|
2562
|
+
'M', 0, outlineOffsetWidth,
|
2563
|
+
'L', bgWidth, bgHeight - outlineOffsetWidth,
|
2564
|
+
'M', 0, bgHeight - outlineOffsetWidth,
|
2565
|
+
'L', bgWidth, outlineOffsetWidth
|
2566
|
+
].join(' ');
|
2567
|
+
}
|
2568
|
+
|
2569
|
+
module.exports = function (sceneGraph, renderSettings) {
|
2570
|
+
var engineSettings = renderSettings.engineSettings;
|
2571
|
+
var stylesheets = engineSettings.stylesheets;
|
2572
|
+
var stylesheetXml = stylesheets.map(function (stylesheet) {
|
2573
|
+
return '<?xml-stylesheet rel="stylesheet" href="' + stylesheet + '"?>';
|
2574
|
+
}).join('\n');
|
2575
|
+
|
2576
|
+
var holderId = 'holder_' + Number(new Date()).toString(16);
|
2577
|
+
|
2578
|
+
var root = sceneGraph.root;
|
2579
|
+
var textGroup = root.children.holderTextGroup;
|
2580
|
+
|
2581
|
+
var css = '#' + holderId + ' text { ' + textCss(textGroup.properties) + ' } ';
|
2582
|
+
|
2583
|
+
// push text down to be equally vertically aligned with canvas renderer
|
2584
|
+
textGroup.y += textGroup.textPositionData.boundingBox.height * 0.8;
|
2585
|
+
|
2586
|
+
var wordTags = [];
|
2587
|
+
|
2588
|
+
Object.keys(textGroup.children).forEach(function (lineKey) {
|
2589
|
+
var line = textGroup.children[lineKey];
|
2590
|
+
|
2591
|
+
Object.keys(line.children).forEach(function (wordKey) {
|
2592
|
+
var word = line.children[wordKey];
|
2593
|
+
var x = textGroup.x + line.x + word.x;
|
2594
|
+
var y = textGroup.y + line.y + word.y;
|
2595
|
+
|
2596
|
+
var wordTag = templates.element({
|
2597
|
+
'tag': 'text',
|
2598
|
+
'content': word.properties.text,
|
2599
|
+
'x': x,
|
2600
|
+
'y': y
|
2601
|
+
});
|
2602
|
+
|
2603
|
+
wordTags.push(wordTag);
|
2604
|
+
});
|
2605
|
+
});
|
2606
|
+
|
2607
|
+
var text = templates.element({
|
2608
|
+
'tag': 'g',
|
2609
|
+
'content': wordTags
|
2610
|
+
});
|
2611
|
+
|
2612
|
+
var outline = null;
|
2613
|
+
|
2614
|
+
if (root.children.holderBg.properties.outline) {
|
2615
|
+
var outlineProperties = root.children.holderBg.properties.outline;
|
2616
|
+
outline = templates.element({
|
2617
|
+
'tag': 'path',
|
2618
|
+
'd': outlinePath(root.children.holderBg.width, root.children.holderBg.height, outlineProperties.width),
|
2619
|
+
'stroke-width': outlineProperties.width,
|
2620
|
+
'stroke': outlineProperties.fill,
|
2621
|
+
'fill': 'none'
|
2622
|
+
});
|
2623
|
+
}
|
2624
|
+
|
2625
|
+
var bg = convertShape(root.children.holderBg, 'rect');
|
2626
|
+
|
2627
|
+
var sceneContent = [];
|
2628
|
+
|
2629
|
+
sceneContent.push(bg);
|
2630
|
+
if (outlineProperties) {
|
2631
|
+
sceneContent.push(outline);
|
2632
|
+
}
|
2633
|
+
sceneContent.push(text);
|
2634
|
+
|
2635
|
+
var scene = templates.element({
|
2636
|
+
'tag': 'g',
|
2637
|
+
'id': holderId,
|
2638
|
+
'content': sceneContent
|
2639
|
+
});
|
2640
|
+
|
2641
|
+
var style = templates.element({
|
2642
|
+
'tag': 'style',
|
2643
|
+
//todo: figure out how to add CDATA directive
|
2644
|
+
'content': css,
|
2645
|
+
'type': 'text/css'
|
2646
|
+
});
|
2647
|
+
|
2648
|
+
var defs = templates.element({
|
2649
|
+
'tag': 'defs',
|
2650
|
+
'content': style
|
2651
|
+
});
|
2652
|
+
|
2653
|
+
var svg = templates.element({
|
2654
|
+
'tag': 'svg',
|
2655
|
+
'content': [defs, scene],
|
2656
|
+
'width': root.properties.width,
|
2657
|
+
'height': root.properties.height,
|
2658
|
+
'xmlns': SVG_NS,
|
2659
|
+
'viewBox': [0, 0, root.properties.width, root.properties.height].join(' '),
|
2660
|
+
'preserveAspectRatio': 'none'
|
2661
|
+
});
|
2662
|
+
|
2663
|
+
var output = shaven(svg);
|
2664
|
+
|
2665
|
+
output = stylesheetXml + output[0];
|
2666
|
+
|
2667
|
+
var svgString = SVG.svgStringToDataURI(output, renderSettings.mode === 'background');
|
2668
|
+
return svgString;
|
2669
|
+
};
|
2670
|
+
|
2671
|
+
/***/ },
|
2672
|
+
/* 13 */
|
2484
2673
|
/***/ function(module, exports, __webpack_require__) {
|
2485
2674
|
|
2675
|
+
var escape = __webpack_require__(14)
|
2676
|
+
|
2677
|
+
// TODO: remove namespace
|
2678
|
+
|
2679
|
+
module.exports = function shaven (array, namespace, returnObject) {
|
2680
|
+
|
2681
|
+
'use strict'
|
2682
|
+
|
2683
|
+
var i = 1,
|
2684
|
+
doesEscape = true,
|
2685
|
+
HTMLString,
|
2686
|
+
attributeKey,
|
2687
|
+
callback,
|
2688
|
+
key
|
2689
|
+
|
2690
|
+
|
2691
|
+
returnObject = returnObject || {}
|
2692
|
+
|
2693
|
+
|
2694
|
+
function createElement (sugarString) {
|
2695
|
+
|
2696
|
+
var tags = sugarString.match(/^\w+/),
|
2697
|
+
element = {
|
2698
|
+
tag: tags ? tags[0] : 'div',
|
2699
|
+
attr: {},
|
2700
|
+
children: []
|
2701
|
+
},
|
2702
|
+
id = sugarString.match(/#([\w-]+)/),
|
2703
|
+
reference = sugarString.match(/\$([\w-]+)/),
|
2704
|
+
classNames = sugarString.match(/\.[\w-]+/g)
|
2705
|
+
|
2706
|
+
|
2707
|
+
// Assign id if is set
|
2708
|
+
if (id) {
|
2709
|
+
element.attr.id = id[1]
|
2710
|
+
|
2711
|
+
// Add element to the return object
|
2712
|
+
returnObject[id[1]] = element
|
2713
|
+
}
|
2714
|
+
|
2715
|
+
if (reference)
|
2716
|
+
returnObject[reference[1]] = element
|
2717
|
+
|
2718
|
+
if (classNames)
|
2719
|
+
element.attr.class = classNames.join(' ').replace(/\./g, '')
|
2720
|
+
|
2721
|
+
if (sugarString.match(/&$/g))
|
2722
|
+
doesEscape = false
|
2723
|
+
|
2724
|
+
return element
|
2725
|
+
}
|
2726
|
+
|
2727
|
+
function replacer (key, value) {
|
2728
|
+
|
2729
|
+
if (value === null || value === false || value === undefined)
|
2730
|
+
return
|
2731
|
+
|
2732
|
+
if (typeof value !== 'string' && typeof value !== 'object')
|
2733
|
+
return String(value)
|
2734
|
+
|
2735
|
+
return value
|
2736
|
+
}
|
2737
|
+
|
2738
|
+
function escapeAttribute (string) {
|
2739
|
+
return String(string)
|
2740
|
+
.replace(/&/g, '&')
|
2741
|
+
.replace(/"/g, '"')
|
2742
|
+
}
|
2743
|
+
|
2744
|
+
function escapeHTML (string) {
|
2745
|
+
return String(string)
|
2746
|
+
.replace(/&/g, '&')
|
2747
|
+
.replace(/"/g, '"')
|
2748
|
+
.replace(/'/g, ''')
|
2749
|
+
.replace(/</g, '<')
|
2750
|
+
.replace(/>/g, '>')
|
2751
|
+
}
|
2752
|
+
|
2753
|
+
|
2754
|
+
if (typeof array[0] === 'string')
|
2755
|
+
array[0] = createElement(array[0])
|
2756
|
+
|
2757
|
+
else if (Array.isArray(array[0]))
|
2758
|
+
i = 0
|
2759
|
+
|
2760
|
+
else
|
2761
|
+
throw new Error(
|
2762
|
+
'First element of array must be a string, ' +
|
2763
|
+
'or an array and not ' + JSON.stringify(array[0])
|
2764
|
+
)
|
2765
|
+
|
2766
|
+
|
2767
|
+
for (; i < array.length; i++) {
|
2768
|
+
|
2769
|
+
// Don't render element if value is false or null
|
2770
|
+
if (array[i] === false || array[i] === null) {
|
2771
|
+
array[0] = false
|
2772
|
+
break
|
2773
|
+
}
|
2774
|
+
|
2775
|
+
// Continue with next array value if current value is undefined or true
|
2776
|
+
else if (array[i] === undefined || array[i] === true) {
|
2777
|
+
continue
|
2778
|
+
}
|
2779
|
+
|
2780
|
+
else if (typeof array[i] === 'string') {
|
2781
|
+
if (doesEscape)
|
2782
|
+
array[i] = escapeHTML(array[i])
|
2783
|
+
|
2784
|
+
array[0].children.push(array[i])
|
2785
|
+
}
|
2786
|
+
|
2787
|
+
else if (typeof array[i] === 'number') {
|
2788
|
+
|
2789
|
+
array[0].children.push(array[i])
|
2790
|
+
}
|
2791
|
+
|
2792
|
+
else if (Array.isArray(array[i])) {
|
2793
|
+
|
2794
|
+
if (Array.isArray(array[i][0])) {
|
2795
|
+
array[i].reverse().forEach(function (subArray) {
|
2796
|
+
array.splice(i + 1, 0, subArray)
|
2797
|
+
})
|
2798
|
+
|
2799
|
+
if (i !== 0)
|
2800
|
+
continue
|
2801
|
+
i++
|
2802
|
+
}
|
2803
|
+
|
2804
|
+
shaven(array[i], namespace, returnObject)
|
2805
|
+
|
2806
|
+
if (array[i][0])
|
2807
|
+
array[0].children.push(array[i][0])
|
2808
|
+
}
|
2809
|
+
|
2810
|
+
else if (typeof array[i] === 'function')
|
2811
|
+
callback = array[i]
|
2812
|
+
|
2813
|
+
|
2814
|
+
else if (typeof array[i] === 'object') {
|
2815
|
+
for (attributeKey in array[i])
|
2816
|
+
if (array[i].hasOwnProperty(attributeKey))
|
2817
|
+
if (array[i][attributeKey] !== null &&
|
2818
|
+
array[i][attributeKey] !== false)
|
2819
|
+
if (attributeKey === 'style' &&
|
2820
|
+
typeof array[i][attributeKey] === 'object')
|
2821
|
+
array[0].attr[attributeKey] = JSON
|
2822
|
+
.stringify(array[i][attributeKey], replacer)
|
2823
|
+
.slice(2, -2)
|
2824
|
+
.replace(/","/g, ';')
|
2825
|
+
.replace(/":"/g, ':')
|
2826
|
+
.replace(/\\"/g, '\'')
|
2827
|
+
|
2828
|
+
else
|
2829
|
+
array[0].attr[attributeKey] = array[i][attributeKey]
|
2830
|
+
}
|
2831
|
+
|
2832
|
+
else
|
2833
|
+
throw new TypeError('"' + array[i] + '" is not allowed as a value.')
|
2834
|
+
}
|
2835
|
+
|
2836
|
+
|
2837
|
+
if (array[0] !== false) {
|
2838
|
+
|
2839
|
+
HTMLString = '<' + array[0].tag
|
2840
|
+
|
2841
|
+
for (key in array[0].attr)
|
2842
|
+
if (array[0].attr.hasOwnProperty(key))
|
2843
|
+
HTMLString += ' ' + key + '="' +
|
2844
|
+
escapeAttribute(array[0].attr[key] || '') + '"'
|
2845
|
+
|
2846
|
+
HTMLString += '>'
|
2847
|
+
|
2848
|
+
array[0].children.forEach(function (child) {
|
2849
|
+
HTMLString += child
|
2850
|
+
})
|
2851
|
+
|
2852
|
+
HTMLString += '</' + array[0].tag + '>'
|
2853
|
+
|
2854
|
+
array[0] = HTMLString
|
2855
|
+
}
|
2856
|
+
|
2857
|
+
// Return root element on index 0
|
2858
|
+
returnObject[0] = array[0]
|
2859
|
+
|
2860
|
+
if (callback)
|
2861
|
+
callback(array[0])
|
2862
|
+
|
2863
|
+
// returns object containing all elements with an id and the root element
|
2864
|
+
return returnObject
|
2865
|
+
}
|
2866
|
+
|
2867
|
+
|
2868
|
+
/***/ },
|
2869
|
+
/* 14 */
|
2870
|
+
/***/ function(module, exports) {
|
2871
|
+
|
2872
|
+
/*!
|
2873
|
+
* escape-html
|
2874
|
+
* Copyright(c) 2012-2013 TJ Holowaychuk
|
2875
|
+
* MIT Licensed
|
2876
|
+
*/
|
2877
|
+
|
2486
2878
|
/**
|
2487
|
-
*
|
2879
|
+
* Module exports.
|
2880
|
+
* @public
|
2488
2881
|
*/
|
2489
2882
|
|
2490
|
-
|
2883
|
+
module.exports = escapeHtml;
|
2491
2884
|
|
2492
2885
|
/**
|
2493
|
-
*
|
2886
|
+
* Escape special characters in the given string of html.
|
2494
2887
|
*
|
2495
|
-
* @param
|
2496
|
-
* @return {
|
2497
|
-
* @
|
2888
|
+
* @param {string} str The string to escape for inserting into HTML
|
2889
|
+
* @return {string}
|
2890
|
+
* @public
|
2498
2891
|
*/
|
2499
2892
|
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
2504
|
-
|
2505
|
-
|
2506
|
-
|
2507
|
-
|
2893
|
+
function escapeHtml(html) {
|
2894
|
+
return String(html)
|
2895
|
+
.replace(/&/g, '&')
|
2896
|
+
.replace(/"/g, '"')
|
2897
|
+
.replace(/'/g, ''')
|
2898
|
+
.replace(/</g, '<')
|
2899
|
+
.replace(/>/g, '>');
|
2900
|
+
}
|
2508
2901
|
|
2509
|
-
if (val === null) return 'null';
|
2510
|
-
if (val === undefined) return 'undefined';
|
2511
|
-
if (val !== val) return 'nan';
|
2512
|
-
if (val && val.nodeType === 1) return 'element';
|
2513
2902
|
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2903
|
+
/***/ },
|
2904
|
+
/* 15 */
|
2905
|
+
/***/ function(module, exports, __webpack_require__) {
|
2517
2906
|
|
2518
|
-
|
2519
|
-
|
2907
|
+
var DOM = __webpack_require__(9);
|
2908
|
+
var utils = __webpack_require__(7);
|
2520
2909
|
|
2910
|
+
module.exports = (function() {
|
2911
|
+
var canvas = DOM.newEl('canvas');
|
2912
|
+
var ctx = null;
|
2521
2913
|
|
2522
|
-
|
2523
|
-
|
2524
|
-
|
2914
|
+
return function(sceneGraph) {
|
2915
|
+
if (ctx == null) {
|
2916
|
+
ctx = canvas.getContext('2d');
|
2917
|
+
}
|
2525
2918
|
|
2526
|
-
|
2527
|
-
|
2919
|
+
var dpr = utils.canvasRatio();
|
2920
|
+
var root = sceneGraph.root;
|
2921
|
+
canvas.width = dpr * root.properties.width;
|
2922
|
+
canvas.height = dpr * root.properties.height ;
|
2923
|
+
ctx.textBaseline = 'middle';
|
2528
2924
|
|
2529
|
-
|
2530
|
-
|
2531
|
-
|
2925
|
+
var bg = root.children.holderBg;
|
2926
|
+
var bgWidth = dpr * bg.width;
|
2927
|
+
var bgHeight = dpr * bg.height;
|
2928
|
+
//todo: parametrize outline width (e.g. in scene object)
|
2929
|
+
var outlineWidth = 2;
|
2930
|
+
var outlineOffsetWidth = outlineWidth / 2;
|
2532
2931
|
|
2533
|
-
|
2534
|
-
|
2535
|
-
};
|
2932
|
+
ctx.fillStyle = bg.properties.fill;
|
2933
|
+
ctx.fillRect(0, 0, bgWidth, bgHeight);
|
2536
2934
|
|
2537
|
-
|
2538
|
-
|
2539
|
-
|
2935
|
+
if (bg.properties.outline) {
|
2936
|
+
//todo: abstract this into a method
|
2937
|
+
ctx.strokeStyle = bg.properties.outline.fill;
|
2938
|
+
ctx.lineWidth = bg.properties.outline.width;
|
2939
|
+
ctx.moveTo(outlineOffsetWidth, outlineOffsetWidth);
|
2940
|
+
// TL, TR, BR, BL
|
2941
|
+
ctx.lineTo(bgWidth - outlineOffsetWidth, outlineOffsetWidth);
|
2942
|
+
ctx.lineTo(bgWidth - outlineOffsetWidth, bgHeight - outlineOffsetWidth);
|
2943
|
+
ctx.lineTo(outlineOffsetWidth, bgHeight - outlineOffsetWidth);
|
2944
|
+
ctx.lineTo(outlineOffsetWidth, outlineOffsetWidth);
|
2945
|
+
// Diagonals
|
2946
|
+
ctx.moveTo(0, outlineOffsetWidth);
|
2947
|
+
ctx.lineTo(bgWidth, bgHeight - outlineOffsetWidth);
|
2948
|
+
ctx.moveTo(0, bgHeight - outlineOffsetWidth);
|
2949
|
+
ctx.lineTo(bgWidth, outlineOffsetWidth);
|
2950
|
+
ctx.stroke();
|
2951
|
+
}
|
2540
2952
|
|
2953
|
+
var textGroup = root.children.holderTextGroup;
|
2954
|
+
ctx.font = textGroup.properties.font.weight + ' ' + (dpr * textGroup.properties.font.size) + textGroup.properties.font.units + ' ' + textGroup.properties.font.family + ', monospace';
|
2955
|
+
ctx.fillStyle = textGroup.properties.fill;
|
2956
|
+
|
2957
|
+
for (var lineKey in textGroup.children) {
|
2958
|
+
var line = textGroup.children[lineKey];
|
2959
|
+
for (var wordKey in line.children) {
|
2960
|
+
var word = line.children[wordKey];
|
2961
|
+
var x = dpr * (textGroup.x + line.x + word.x);
|
2962
|
+
var y = dpr * (textGroup.y + line.y + word.y + (textGroup.properties.leading / 2));
|
2963
|
+
|
2964
|
+
ctx.fillText(word.properties.text, x, y);
|
2965
|
+
}
|
2966
|
+
}
|
2967
|
+
|
2968
|
+
return canvas.toDataURL('image/png');
|
2969
|
+
};
|
2970
|
+
})();
|
2541
2971
|
|
2542
2972
|
/***/ }
|
2543
2973
|
/******/ ])
|