-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
PaintBox.js
148 lines (133 loc) · 4.14 KB
/
PaintBox.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import { jGraduate } from './jgraduate/jQuery.jGraduate.js'
/**
*
*/
class PaintBox {
/**
* @param {string|Element|external:jQuery} container
* @param {"fill"} type
*/
constructor (container, type) {
// set up gradients to be used for the buttons
const svgdocbox = new DOMParser().parseFromString(
`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14">
<rect
fill="#000000" opacity="1" width="14" height="14"/>
<defs><linearGradient id="gradbox_${PaintBox.ctr++}"/></defs>
</svg>`,
'text/xml'
)
let docElem = svgdocbox.documentElement
docElem = document.importNode(docElem, true)
container.appendChild(docElem)
this.rect = docElem.firstElementChild
this.defs = docElem.getElementsByTagName('defs')[0]
this.grad = this.defs.firstElementChild
// this.paint = new $.jGraduate.Paint({solidColor: color});
this.type = type
}
/**
* @param {module:jGraduate~Paint} paint
* @returns {void}
*/
setPaint (paint) {
this.paint = paint
const ptype = paint.type
const opac = paint.alpha / 100
let fillAttr = 'none'
switch (ptype) {
case 'solidColor':
fillAttr = (paint[ptype] !== 'none') ? '#' + paint[ptype] : paint[ptype]
break
case 'linearGradient':
case 'radialGradient': {
this.grad.remove()
this.grad = paint[ptype]
this.defs.appendChild(this.grad)
const id = this.grad.id = 'gradbox_' + this.type
fillAttr = 'url(#' + id + ')'
break
}
}
this.rect.setAttribute('fill', fillAttr)
this.rect.setAttribute('opacity', opac)
}
/**
* @param {PlainObject} svgCanvas
* @param {string} color
* @param {Float} opac
* @param {string} type
* @returns {module:jGraduate~Paint}
*/
static getPaint (svgCanvas, color, opac, type) {
// update the editor's fill paint
const opts = { alpha: opac }
if (color.startsWith('url(#')) {
let refElem = svgCanvas.getRefElem(color)
refElem = (refElem) ? refElem.cloneNode(true) : document.querySelectorAll('#' + type + '_color defs *')[0]
if (!refElem) {
console.error(`the color ${color} is referenced by an url that can't be identified - using 'none'`)
opts.solidColor = 'none'
} else {
opts[refElem.tagName] = refElem
}
} else if (color.startsWith('#')) {
opts.solidColor = color.substr(1)
}
return new jGraduate.Paint(opts)
}
/**
* @param {PlainObject} svgcanvas
* @param {PlainObject} selectedElement
* @returns {any}
*/
update (svgcanvas, selectedElement) {
if (!selectedElement) { return null }
const { type } = this
switch (selectedElement.tagName) {
case 'use':
case 'image':
case 'foreignObject':
// These elements don't have fill or stroke, so don't change
// the current value
return null
case 'g':
case 'a': {
const childs = selectedElement.getElementsByTagName('*')
let gPaint = null
for (let i = 0, len = childs.length; i < len; i++) {
const elem = childs[i]
const p = elem.getAttribute(type)
if (i === 0) {
gPaint = p
} else if (gPaint !== p) {
gPaint = null
break
}
}
if (gPaint === null) {
// No common color, don't update anything
this._paintColor = null
return null
}
this._paintColor = gPaint
this._paintOpacity = 1
break
} default: {
this._paintOpacity = Number.parseFloat(selectedElement.getAttribute(type + '-opacity'))
if (Number.isNaN(this._paintOpacity)) {
this._paintOpacity = 1.0
}
const defColor = type === 'fill' ? 'black' : 'none'
this._paintColor = selectedElement.getAttribute(type) || defColor
}
}
this._paintOpacity *= 100
const paint = PaintBox.getPaint(svgcanvas, this._paintColor, this._paintOpacity, type)
// update the rect inside #fill_color/#stroke_color
this.setPaint(paint)
return (paint)
}
}
PaintBox.ctr = 0
export default PaintBox