Add possibility to use upper layers as masks for lower ones
This commit is contained in:
parent
7bf1686a34
commit
a4236752ab
@ -13,14 +13,42 @@ function Manager (client) {
|
||||
this.el.setAttribute('version', '1.1')
|
||||
this.el.style.fill = 'none'
|
||||
|
||||
this.masks = []
|
||||
this.layers = []
|
||||
|
||||
this.install = function () {
|
||||
this.masks[0] = [this.maskBg()]
|
||||
this.masks[1] = [this.maskBg(), document.createElementNS('http://www.w3.org/2000/svg', 'path')]
|
||||
this.masks[2] = [
|
||||
this.maskBg(),
|
||||
document.createElementNS('http://www.w3.org/2000/svg', 'path'),
|
||||
document.createElementNS('http://www.w3.org/2000/svg', 'path')
|
||||
]
|
||||
|
||||
const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs')
|
||||
this.el.appendChild(defs)
|
||||
for (const id of [2, 1, 0]) {
|
||||
const maskPath = document.createElementNS('http://www.w3.org/2000/svg', 'mask')
|
||||
maskPath.setAttribute('id', 'mask' + id)
|
||||
for (const mask of this.masks[id]) {
|
||||
maskPath.appendChild(mask)
|
||||
}
|
||||
defs.appendChild(maskPath)
|
||||
}
|
||||
|
||||
this.el.appendChild(this.layers[2] = document.createElementNS('http://www.w3.org/2000/svg', 'path'))
|
||||
this.el.appendChild(this.layers[1] = document.createElementNS('http://www.w3.org/2000/svg', 'path'))
|
||||
this.el.appendChild(this.layers[0] = document.createElementNS('http://www.w3.org/2000/svg', 'path'))
|
||||
}
|
||||
|
||||
this.maskBg = function () {
|
||||
const bg = document.createElementNS('http://www.w3.org/2000/svg', 'rect')
|
||||
bg.setAttribute('fill', 'white')
|
||||
bg.setAttribute('width', '100%')
|
||||
bg.setAttribute('height', '100%')
|
||||
return bg
|
||||
}
|
||||
|
||||
this.update = function () {
|
||||
this.el.setAttribute('width', (client.tool.settings.size.width) + 'px')
|
||||
this.el.setAttribute('height', (client.tool.settings.size.height) + 'px')
|
||||
@ -29,19 +57,53 @@ function Manager (client) {
|
||||
|
||||
const styles = client.tool.styles
|
||||
const paths = client.tool.paths()
|
||||
const masked = styles.map((style) => style.mask)
|
||||
|
||||
const viewBox = this.minimalViewBox();
|
||||
if (viewBox !== null) {
|
||||
for (const id in this.masks) {
|
||||
const [x, y, width, height] = viewBox
|
||||
this.masks[id][0].setAttribute('x', x)
|
||||
this.masks[id][0].setAttribute('y', y)
|
||||
this.masks[id][0].setAttribute('width', width)
|
||||
this.masks[id][0].setAttribute('height', height)
|
||||
}
|
||||
}
|
||||
|
||||
for (const id in this.layers) {
|
||||
const style = styles[id]
|
||||
const path = paths[id]
|
||||
const layer = this.layers[id]
|
||||
|
||||
const nextLayer = parseInt(id) + 1
|
||||
for (var i = nextLayer; i < 3; i++) {
|
||||
const mask = this.masks[i][nextLayer]
|
||||
if (style.mask) {
|
||||
mask.setAttribute('d', path)
|
||||
mask.style.strokeWidth = style.thickness
|
||||
mask.style.strokeLinecap = style.strokeLinecap
|
||||
mask.style.strokeLinejoin = style.strokeLinejoin
|
||||
mask.style.stroke = style.color
|
||||
mask.style.fill = style.fill
|
||||
} else {
|
||||
mask.setAttribute('d', '')
|
||||
}
|
||||
}
|
||||
layer.style.strokeWidth = style.thickness
|
||||
layer.style.strokeLinecap = style.strokeLinecap
|
||||
layer.style.strokeLinejoin = style.strokeLinejoin
|
||||
layer.style.stroke = style.color
|
||||
layer.style.fill = style.fill
|
||||
|
||||
layer.setAttribute('d', path)
|
||||
layer.setAttribute('d', style.mask ? '' : path)
|
||||
|
||||
const maskedAbove = masked.slice(0, id).some((mask) => mask === true)
|
||||
const maskPath = !(style.mask) && maskedAbove ? 'url(#mask' + id + ')' : null
|
||||
if (maskPath !== null) {
|
||||
layer.setAttribute('mask', maskPath)
|
||||
} else if (layer.hasAttribute('mask')) {
|
||||
layer.removeAttribute('mask')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,9 +137,9 @@ function Manager (client) {
|
||||
if (xMax === null || xMaxOfLayer > xMax) { xMax = xMaxOfLayer }
|
||||
if (yMax === null || yMaxOfLayer > yMax) { yMax = yMaxOfLayer }
|
||||
}
|
||||
if (xMin === null || yMin === null || xMax === null || yMax === null) { return '' }
|
||||
if (xMin === null || yMin === null || xMax === null || yMax === null) { return null }
|
||||
|
||||
return xMin + ' ' + yMin + ' ' + (xMax - xMin) + ' ' + (yMax - yMin)
|
||||
return [xMin, yMin, xMax - xMin, yMax - yMin]
|
||||
}
|
||||
|
||||
this.svg64 = function () {
|
||||
@ -106,15 +168,15 @@ function Manager (client) {
|
||||
|
||||
this.toString = () => {
|
||||
const viewBox = this.minimalViewBox();
|
||||
if (viewBox !== '') {
|
||||
this.el.setAttribute('width', viewBox.split(/ /)[2] + 'px')
|
||||
if (viewBox !== null) {
|
||||
this.el.setAttribute('width', viewBox[2] + 'px')
|
||||
this.el.removeAttribute('height')
|
||||
this.el.style.width = null
|
||||
this.el.style.height = null
|
||||
this.el.setAttribute('viewBox', this.minimalViewBox())
|
||||
this.el.setAttribute('viewBox', viewBox.join(' '))
|
||||
}
|
||||
const serialized = new XMLSerializer().serializeToString(this.el)
|
||||
if (viewBox !== '') {
|
||||
if (viewBox !== null) {
|
||||
this.el.setAttribute('width', (client.tool.settings.size.width) + 'px')
|
||||
this.el.setAttribute('height', (client.tool.settings.size.height) + 'px')
|
||||
this.el.style.width = client.tool.settings.size.width
|
||||
|
@ -7,9 +7,9 @@ function Tool (client) {
|
||||
this.settings = { size: { width: 600, height: 300 } }
|
||||
this.layers = [[], [], []]
|
||||
this.styles = [
|
||||
{ thickness: 15, strokeLinecap: 'round', strokeLinejoin: 'round', color: '#f00', fill: 'none', mirror_style: 0, transform: 'rotate(45)' },
|
||||
{ thickness: 15, strokeLinecap: 'round', strokeLinejoin: 'round', color: '#0f0', fill: 'none', mirror_style: 0, transform: 'rotate(45)' },
|
||||
{ thickness: 15, strokeLinecap: 'round', strokeLinejoin: 'round', color: '#00f', fill: 'none', mirror_style: 0, transform: 'rotate(45)' }
|
||||
{ thickness: 15, strokeLinecap: 'round', strokeLinejoin: 'round', color: '#f00', fill: 'none', mask: false, mirror_style: 0, transform: 'rotate(45)' },
|
||||
{ thickness: 15, strokeLinecap: 'round', strokeLinejoin: 'round', color: '#0f0', fill: 'none', mask: false, mirror_style: 0, transform: 'rotate(45)' },
|
||||
{ thickness: 15, strokeLinecap: 'round', strokeLinejoin: 'round', color: '#00f', fill: 'none', mask: false, mirror_style: 0, transform: 'rotate(45)' }
|
||||
]
|
||||
this.vertices = []
|
||||
this.reqs = { line: 2, arc_c: 2, arc_r: 2, arc_c_full: 2, arc_r_full: 2, bezier: 3, close: 0 }
|
||||
|
Loading…
Reference in New Issue
Block a user