791 lines
26 KiB
JavaScript
791 lines
26 KiB
JavaScript
import tinycolor from 'tinycolor2'
|
|
import { getSchemeColorFromTheme } from './schemeColor'
|
|
import {
|
|
applyShade,
|
|
applyTint,
|
|
applyLumOff,
|
|
applyLumMod,
|
|
applyHueMod,
|
|
applySatMod,
|
|
hslToRgb,
|
|
getColorName2Hex,
|
|
} from './color'
|
|
|
|
import {
|
|
base64ArrayBuffer,
|
|
getTextByPathList,
|
|
angleToDegrees,
|
|
escapeHtml,
|
|
getMimeType,
|
|
toHex,
|
|
} from './utils'
|
|
|
|
export function getFillType(node) {
|
|
let fillType = ''
|
|
if (node['a:noFill']) fillType = 'NO_FILL'
|
|
if (node['a:solidFill']) fillType = 'SOLID_FILL'
|
|
if (node['a:gradFill']) fillType = 'GRADIENT_FILL'
|
|
if (node['a:pattFill']) fillType = 'PATTERN_FILL'
|
|
if (node['a:blipFill']) fillType = 'PIC_FILL'
|
|
if (node['a:grpFill']) fillType = 'GROUP_FILL'
|
|
|
|
return fillType
|
|
}
|
|
|
|
export async function getPicFill(type, node, warpObj) {
|
|
if (!node) return ''
|
|
|
|
let img
|
|
const rId = getTextByPathList(node, ['a:blip', 'attrs', 'r:embed'])
|
|
let imgPath
|
|
if (type === 'slideBg' || type === 'slide') {
|
|
imgPath = getTextByPathList(warpObj, ['slideResObj', rId, 'target'])
|
|
}
|
|
else if (type === 'slideLayoutBg') {
|
|
imgPath = getTextByPathList(warpObj, ['layoutResObj', rId, 'target'])
|
|
}
|
|
else if (type === 'slideMasterBg') {
|
|
imgPath = getTextByPathList(warpObj, ['masterResObj', rId, 'target'])
|
|
}
|
|
else if (type === 'themeBg') {
|
|
imgPath = getTextByPathList(warpObj, ['themeResObj', rId, 'target'])
|
|
}
|
|
else if (type === 'diagramBg') {
|
|
imgPath = getTextByPathList(warpObj, ['diagramResObj', rId, 'target'])
|
|
}
|
|
if (!imgPath) return imgPath
|
|
|
|
img = getTextByPathList(warpObj, ['loaded-images', imgPath])
|
|
if (!img) {
|
|
imgPath = escapeHtml(imgPath)
|
|
|
|
const imgExt = imgPath.split('.').pop()
|
|
if (imgExt === 'xml') return ''
|
|
|
|
const imgArrayBuffer = await warpObj['zip'].file(imgPath).async('arraybuffer')
|
|
const imgMimeType = getMimeType(imgExt)
|
|
if (warpObj.mediaMode === 'blob' && typeof URL !== 'undefined' && typeof Blob !== 'undefined' && URL.createObjectURL) {
|
|
img = URL.createObjectURL(new Blob([imgArrayBuffer], { type: imgMimeType }))
|
|
} else {
|
|
img = `data:${imgMimeType};base64,${base64ArrayBuffer(imgArrayBuffer)}`
|
|
}
|
|
|
|
const loadedImages = warpObj['loaded-images'] || {}
|
|
loadedImages[imgPath] = img
|
|
warpObj['loaded-images'] = loadedImages
|
|
}
|
|
return img
|
|
}
|
|
|
|
export function getPicFillOpacity(node) {
|
|
const aBlipNode = node['a:blip']
|
|
|
|
const aphaModFixNode = getTextByPathList(aBlipNode, ['a:alphaModFix', 'attrs'])
|
|
let opacity = 1
|
|
if (aphaModFixNode && aphaModFixNode['amt'] && aphaModFixNode['amt'] !== '') {
|
|
opacity = parseInt(aphaModFixNode['amt']) / 100000
|
|
}
|
|
|
|
return opacity
|
|
}
|
|
|
|
export function getPicFilters(node) {
|
|
if (!node) return null
|
|
|
|
const aBlipNode = node['a:blip']
|
|
if (!aBlipNode) return null
|
|
|
|
const filters = {}
|
|
|
|
// 从a:extLst中获取滤镜效果(Microsoft Office 2010+扩展)
|
|
const extLstNode = aBlipNode['a:extLst']
|
|
if (extLstNode && extLstNode['a:ext']) {
|
|
const extNodes = Array.isArray(extLstNode['a:ext']) ? extLstNode['a:ext'] : [extLstNode['a:ext']]
|
|
|
|
for (const extNode of extNodes) {
|
|
if (!extNode['a14:imgProps'] || !extNode['a14:imgProps']['a14:imgLayer']) continue
|
|
|
|
const imgLayerNode = extNode['a14:imgProps']['a14:imgLayer']
|
|
const imgEffects = imgLayerNode['a14:imgEffect']
|
|
|
|
if (!imgEffects) continue
|
|
|
|
const effectArray = Array.isArray(imgEffects) ? imgEffects : [imgEffects]
|
|
|
|
for (const effect of effectArray) {
|
|
// 饱和度
|
|
if (effect['a14:saturation']) {
|
|
const satAttr = getTextByPathList(effect, ['a14:saturation', 'attrs', 'sat'])
|
|
if (satAttr) {
|
|
filters.saturation = parseInt(satAttr) / 100000
|
|
}
|
|
}
|
|
|
|
// 亮度、对比度
|
|
if (effect['a14:brightnessContrast']) {
|
|
const brightAttr = getTextByPathList(effect, ['a14:brightnessContrast', 'attrs', 'bright'])
|
|
const contrastAttr = getTextByPathList(effect, ['a14:brightnessContrast', 'attrs', 'contrast'])
|
|
|
|
if (brightAttr) {
|
|
filters.brightness = parseInt(brightAttr) / 100000
|
|
}
|
|
if (contrastAttr) {
|
|
filters.contrast = parseInt(contrastAttr) / 100000
|
|
}
|
|
}
|
|
|
|
// 锐化/柔化
|
|
if (effect['a14:sharpenSoften']) {
|
|
const amountAttr = getTextByPathList(effect, ['a14:sharpenSoften', 'attrs', 'amount'])
|
|
if (amountAttr) {
|
|
const amount = parseInt(amountAttr) / 100000
|
|
if (amount > 0) {
|
|
filters.sharpen = amount
|
|
}
|
|
else {
|
|
filters.soften = Math.abs(amount)
|
|
}
|
|
}
|
|
}
|
|
|
|
// 色温
|
|
if (effect['a14:colorTemperature']) {
|
|
const tempAttr = getTextByPathList(effect, ['a14:colorTemperature', 'attrs', 'colorTemp'])
|
|
if (tempAttr) {
|
|
filters.colorTemperature = parseInt(tempAttr)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return Object.keys(filters).length > 0 ? filters : null
|
|
}
|
|
|
|
export async function getBgPicFill(bgPr, sorce, warpObj) {
|
|
const picBase64 = await getPicFill(sorce, bgPr['a:blipFill'], warpObj)
|
|
const aBlipNode = bgPr['a:blipFill']['a:blip']
|
|
|
|
const aphaModFixNode = getTextByPathList(aBlipNode, ['a:alphaModFix', 'attrs'])
|
|
let opacity = 1
|
|
if (aphaModFixNode && aphaModFixNode['amt'] && aphaModFixNode['amt'] !== '') {
|
|
opacity = parseInt(aphaModFixNode['amt']) / 100000
|
|
}
|
|
|
|
return {
|
|
picBase64,
|
|
opacity,
|
|
}
|
|
}
|
|
|
|
export function getGradientFill(node, warpObj) {
|
|
const gsLst = node['a:gsLst']['a:gs']
|
|
const colors = []
|
|
for (let i = 0; i < gsLst.length; i++) {
|
|
const lo_color = getSolidFill(gsLst[i], undefined, undefined, warpObj)
|
|
const pos = getTextByPathList(gsLst[i], ['attrs', 'pos'])
|
|
|
|
colors[i] = {
|
|
pos: pos ? (pos / 1000 + '%') : '',
|
|
color: lo_color,
|
|
}
|
|
}
|
|
const lin = node['a:lin']
|
|
let rot = 0
|
|
let pathType = 'line'
|
|
if (lin) rot = angleToDegrees(lin['attrs']['ang'])
|
|
else {
|
|
const path = node['a:path']
|
|
if (path && path['attrs'] && path['attrs']['path']) pathType = path['attrs']['path']
|
|
}
|
|
return {
|
|
rot,
|
|
path: pathType,
|
|
colors: colors.sort((a, b) => parseInt(a.pos) - parseInt(b.pos)),
|
|
}
|
|
}
|
|
|
|
export function getPatternFill(node, warpObj) {
|
|
if (!node) return null
|
|
|
|
const pattFill = node['a:pattFill']
|
|
if (!pattFill) return null
|
|
|
|
const type = getTextByPathList(pattFill, ['attrs', 'prst'])
|
|
|
|
const fgColorNode = pattFill['a:fgClr']
|
|
const bgColorNode = pattFill['a:bgClr']
|
|
|
|
let foregroundColor = '#000000'
|
|
let backgroundColor = '#FFFFFF'
|
|
|
|
if (fgColorNode) {
|
|
foregroundColor = getSolidFill(fgColorNode, undefined, undefined, warpObj)
|
|
}
|
|
|
|
if (bgColorNode) {
|
|
backgroundColor = getSolidFill(bgColorNode, undefined, undefined, warpObj)
|
|
}
|
|
|
|
return {
|
|
type,
|
|
foregroundColor,
|
|
backgroundColor,
|
|
}
|
|
}
|
|
|
|
export function getBgGradientFill(bgPr, phClr, slideMasterContent, warpObj) {
|
|
if (bgPr) {
|
|
const grdFill = bgPr['a:gradFill']
|
|
const gsLst = grdFill['a:gsLst']['a:gs']
|
|
const colors = []
|
|
|
|
for (let i = 0; i < gsLst.length; i++) {
|
|
const lo_color = getSolidFill(gsLst[i], slideMasterContent['p:sldMaster']['p:clrMap']['attrs'], phClr, warpObj)
|
|
const pos = getTextByPathList(gsLst[i], ['attrs', 'pos'])
|
|
|
|
colors[i] = {
|
|
pos: pos ? (pos / 1000 + '%') : '',
|
|
color: lo_color,
|
|
}
|
|
}
|
|
const lin = grdFill['a:lin']
|
|
let rot = 0
|
|
let pathType = 'line'
|
|
if (lin) rot = angleToDegrees(lin['attrs']['ang']) + 0
|
|
else {
|
|
const path = grdFill['a:path']
|
|
if (path && path['attrs'] && path['attrs']['path']) pathType = path['attrs']['path']
|
|
}
|
|
return {
|
|
rot,
|
|
path: pathType,
|
|
colors: colors.sort((a, b) => parseInt(a.pos) - parseInt(b.pos)),
|
|
}
|
|
}
|
|
else if (phClr) {
|
|
return phClr.indexOf('#') === -1 ? `#${phClr}` : phClr
|
|
}
|
|
return null
|
|
}
|
|
|
|
export async function getSlideBackgroundFill(warpObj) {
|
|
const slideContent = warpObj['slideContent']
|
|
const slideLayoutContent = warpObj['slideLayoutContent']
|
|
const slideMasterContent = warpObj['slideMasterContent']
|
|
|
|
let bgPr = getTextByPathList(slideContent, ['p:sld', 'p:cSld', 'p:bg', 'p:bgPr'])
|
|
let bgRef = getTextByPathList(slideContent, ['p:sld', 'p:cSld', 'p:bg', 'p:bgRef'])
|
|
|
|
let background = '#fff'
|
|
let backgroundType = 'color'
|
|
|
|
if (bgPr) {
|
|
const bgFillTyp = getFillType(bgPr)
|
|
|
|
if (bgFillTyp === 'SOLID_FILL') {
|
|
const sldFill = bgPr['a:solidFill']
|
|
let clrMapOvr
|
|
const sldClrMapOvr = getTextByPathList(slideContent, ['p:sld', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
|
|
if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
|
|
else {
|
|
const sldClrMapOvr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
|
|
if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
|
|
else clrMapOvr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
|
|
}
|
|
const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
|
|
background = sldBgClr
|
|
}
|
|
else if (bgFillTyp === 'GRADIENT_FILL') {
|
|
const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
|
|
if (typeof gradientFill === 'string') {
|
|
background = gradientFill
|
|
}
|
|
else if (gradientFill) {
|
|
background = gradientFill
|
|
backgroundType = 'gradient'
|
|
}
|
|
}
|
|
else if (bgFillTyp === 'PIC_FILL') {
|
|
background = await getBgPicFill(bgPr, 'slideBg', warpObj)
|
|
backgroundType = 'image'
|
|
}
|
|
else if (bgFillTyp === 'PATTERN_FILL') {
|
|
const patternFill = getPatternFill(bgPr, warpObj)
|
|
if (patternFill) {
|
|
background = patternFill
|
|
backgroundType = 'pattern'
|
|
}
|
|
}
|
|
}
|
|
else if (bgRef) {
|
|
let clrMapOvr
|
|
const sldClrMapOvr = getTextByPathList(slideContent, ['p:sld', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
|
|
if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
|
|
else {
|
|
const sldClrMapOvr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
|
|
if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
|
|
else clrMapOvr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
|
|
}
|
|
const phClr = getSolidFill(bgRef, clrMapOvr, undefined, warpObj)
|
|
const idx = Number(bgRef['attrs']['idx'])
|
|
|
|
if (idx > 1000) {
|
|
const trueIdx = idx - 1000
|
|
const bgFillLst = warpObj['themeContent']['a:theme']['a:themeElements']['a:fmtScheme']['a:bgFillStyleLst']
|
|
const sortblAry = []
|
|
Object.keys(bgFillLst).forEach(key => {
|
|
const bgFillLstTyp = bgFillLst[key]
|
|
if (key !== 'attrs') {
|
|
if (bgFillLstTyp.constructor === Array) {
|
|
for (let i = 0; i < bgFillLstTyp.length; i++) {
|
|
const obj = {}
|
|
obj[key] = bgFillLstTyp[i]
|
|
if (bgFillLstTyp[i]['attrs']) {
|
|
obj['idex'] = bgFillLstTyp[i]['attrs']['order']
|
|
obj['attrs'] = {
|
|
'order': bgFillLstTyp[i]['attrs']['order']
|
|
}
|
|
}
|
|
sortblAry.push(obj)
|
|
}
|
|
}
|
|
else {
|
|
const obj = {}
|
|
obj[key] = bgFillLstTyp
|
|
if (bgFillLstTyp['attrs']) {
|
|
obj['idex'] = bgFillLstTyp['attrs']['order']
|
|
obj['attrs'] = {
|
|
'order': bgFillLstTyp['attrs']['order']
|
|
}
|
|
}
|
|
sortblAry.push(obj)
|
|
}
|
|
}
|
|
})
|
|
const sortByOrder = sortblAry.slice(0)
|
|
sortByOrder.sort((a, b) => a.idex - b.idex)
|
|
const bgFillLstIdx = sortByOrder[trueIdx - 1]
|
|
const bgFillTyp = getFillType(bgFillLstIdx)
|
|
if (bgFillTyp === 'SOLID_FILL') {
|
|
const sldFill = bgFillLstIdx['a:solidFill']
|
|
const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
|
|
background = sldBgClr
|
|
}
|
|
else if (bgFillTyp === 'GRADIENT_FILL') {
|
|
const gradientFill = getBgGradientFill(bgFillLstIdx, phClr, slideMasterContent, warpObj)
|
|
if (typeof gradientFill === 'string') {
|
|
background = gradientFill
|
|
}
|
|
else if (gradientFill) {
|
|
background = gradientFill
|
|
backgroundType = 'gradient'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
bgPr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:cSld', 'p:bg', 'p:bgPr'])
|
|
bgRef = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:cSld', 'p:bg', 'p:bgRef'])
|
|
|
|
let clrMapOvr
|
|
const sldClrMapOvr = getTextByPathList(slideLayoutContent, ['p:sldLayout', 'p:clrMapOvr', 'a:overrideClrMapping', 'attrs'])
|
|
if (sldClrMapOvr) clrMapOvr = sldClrMapOvr
|
|
else clrMapOvr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
|
|
|
|
if (bgPr) {
|
|
const bgFillTyp = getFillType(bgPr)
|
|
if (bgFillTyp === 'SOLID_FILL') {
|
|
const sldFill = bgPr['a:solidFill']
|
|
const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
|
|
background = sldBgClr
|
|
}
|
|
else if (bgFillTyp === 'GRADIENT_FILL') {
|
|
const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
|
|
if (typeof gradientFill === 'string') {
|
|
background = gradientFill
|
|
}
|
|
else if (gradientFill) {
|
|
background = gradientFill
|
|
backgroundType = 'gradient'
|
|
}
|
|
}
|
|
else if (bgFillTyp === 'PIC_FILL') {
|
|
background = await getBgPicFill(bgPr, 'slideLayoutBg', warpObj)
|
|
backgroundType = 'image'
|
|
}
|
|
else if (bgFillTyp === 'PATTERN_FILL') {
|
|
const patternFill = getPatternFill(bgPr, warpObj)
|
|
if (patternFill) {
|
|
background = patternFill
|
|
backgroundType = 'pattern'
|
|
}
|
|
}
|
|
}
|
|
else if (bgRef) {
|
|
const phClr = getSolidFill(bgRef, clrMapOvr, undefined, warpObj)
|
|
const idx = Number(bgRef['attrs']['idx'])
|
|
|
|
if (idx > 1000) {
|
|
const trueIdx = idx - 1000
|
|
const bgFillLst = warpObj['themeContent']['a:theme']['a:themeElements']['a:fmtScheme']['a:bgFillStyleLst']
|
|
const sortblAry = []
|
|
Object.keys(bgFillLst).forEach(key => {
|
|
const bgFillLstTyp = bgFillLst[key]
|
|
if (key !== 'attrs') {
|
|
if (bgFillLstTyp.constructor === Array) {
|
|
for (let i = 0; i < bgFillLstTyp.length; i++) {
|
|
const obj = {}
|
|
obj[key] = bgFillLstTyp[i]
|
|
if (bgFillLstTyp[i]['attrs']) {
|
|
obj['idex'] = bgFillLstTyp[i]['attrs']['order']
|
|
obj['attrs'] = {
|
|
'order': bgFillLstTyp[i]['attrs']['order']
|
|
}
|
|
}
|
|
sortblAry.push(obj)
|
|
}
|
|
}
|
|
else {
|
|
const obj = {}
|
|
obj[key] = bgFillLstTyp
|
|
if (bgFillLstTyp['attrs']) {
|
|
obj['idex'] = bgFillLstTyp['attrs']['order']
|
|
obj['attrs'] = {
|
|
'order': bgFillLstTyp['attrs']['order']
|
|
}
|
|
}
|
|
sortblAry.push(obj)
|
|
}
|
|
}
|
|
})
|
|
const sortByOrder = sortblAry.slice(0)
|
|
sortByOrder.sort((a, b) => a.idex - b.idex)
|
|
const bgFillLstIdx = sortByOrder[trueIdx - 1]
|
|
const bgFillTyp = getFillType(bgFillLstIdx)
|
|
if (bgFillTyp === 'SOLID_FILL') {
|
|
const sldFill = bgFillLstIdx['a:solidFill']
|
|
const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
|
|
background = sldBgClr
|
|
}
|
|
else if (bgFillTyp === 'GRADIENT_FILL') {
|
|
const gradientFill = getBgGradientFill(bgFillLstIdx, phClr, slideMasterContent, warpObj)
|
|
if (typeof gradientFill === 'string') {
|
|
background = gradientFill
|
|
}
|
|
else if (gradientFill) {
|
|
background = gradientFill
|
|
backgroundType = 'gradient'
|
|
}
|
|
}
|
|
else if (bgFillTyp === 'PIC_FILL') {
|
|
background = await getBgPicFill(bgFillLstIdx, 'themeBg', warpObj)
|
|
backgroundType = 'image'
|
|
}
|
|
else if (bgFillTyp === 'PATTERN_FILL') {
|
|
const patternFill = getPatternFill(bgFillLstIdx, warpObj)
|
|
if (patternFill) {
|
|
background = patternFill
|
|
backgroundType = 'pattern'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
bgPr = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:cSld', 'p:bg', 'p:bgPr'])
|
|
bgRef = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:cSld', 'p:bg', 'p:bgRef'])
|
|
|
|
const clrMap = getTextByPathList(slideMasterContent, ['p:sldMaster', 'p:clrMap', 'attrs'])
|
|
if (bgPr) {
|
|
const bgFillTyp = getFillType(bgPr)
|
|
if (bgFillTyp === 'SOLID_FILL') {
|
|
const sldFill = bgPr['a:solidFill']
|
|
const sldBgClr = getSolidFill(sldFill, clrMap, undefined, warpObj)
|
|
background = sldBgClr
|
|
}
|
|
else if (bgFillTyp === 'GRADIENT_FILL') {
|
|
const gradientFill = getBgGradientFill(bgPr, undefined, slideMasterContent, warpObj)
|
|
if (typeof gradientFill === 'string') {
|
|
background = gradientFill
|
|
}
|
|
else if (gradientFill) {
|
|
background = gradientFill
|
|
backgroundType = 'gradient'
|
|
}
|
|
}
|
|
else if (bgFillTyp === 'PIC_FILL') {
|
|
background = await getBgPicFill(bgPr, 'slideMasterBg', warpObj)
|
|
backgroundType = 'image'
|
|
}
|
|
else if (bgFillTyp === 'PATTERN_FILL') {
|
|
const patternFill = getPatternFill(bgPr, warpObj)
|
|
if (patternFill) {
|
|
background = patternFill
|
|
backgroundType = 'pattern'
|
|
}
|
|
}
|
|
}
|
|
else if (bgRef) {
|
|
const phClr = getSolidFill(bgRef, clrMap, undefined, warpObj)
|
|
const idx = Number(bgRef['attrs']['idx'])
|
|
|
|
if (idx > 1000) {
|
|
const trueIdx = idx - 1000
|
|
const bgFillLst = warpObj['themeContent']['a:theme']['a:themeElements']['a:fmtScheme']['a:bgFillStyleLst']
|
|
const sortblAry = []
|
|
Object.keys(bgFillLst).forEach(key => {
|
|
const bgFillLstTyp = bgFillLst[key]
|
|
if (key !== 'attrs') {
|
|
if (bgFillLstTyp.constructor === Array) {
|
|
for (let i = 0; i < bgFillLstTyp.length; i++) {
|
|
const obj = {}
|
|
obj[key] = bgFillLstTyp[i]
|
|
if (bgFillLstTyp[i]['attrs']) {
|
|
obj['idex'] = bgFillLstTyp[i]['attrs']['order']
|
|
obj['attrs'] = {
|
|
'order': bgFillLstTyp[i]['attrs']['order']
|
|
}
|
|
}
|
|
sortblAry.push(obj)
|
|
}
|
|
}
|
|
else {
|
|
const obj = {}
|
|
obj[key] = bgFillLstTyp
|
|
if (bgFillLstTyp['attrs']) {
|
|
obj['idex'] = bgFillLstTyp['attrs']['order']
|
|
obj['attrs'] = {
|
|
'order': bgFillLstTyp['attrs']['order']
|
|
}
|
|
}
|
|
sortblAry.push(obj)
|
|
}
|
|
}
|
|
})
|
|
const sortByOrder = sortblAry.slice(0)
|
|
sortByOrder.sort((a, b) => a.idex - b.idex)
|
|
const bgFillLstIdx = sortByOrder[trueIdx - 1]
|
|
const bgFillTyp = getFillType(bgFillLstIdx)
|
|
if (bgFillTyp === 'SOLID_FILL') {
|
|
const sldFill = bgFillLstIdx['a:solidFill']
|
|
const sldBgClr = getSolidFill(sldFill, clrMapOvr, undefined, warpObj)
|
|
background = sldBgClr
|
|
}
|
|
else if (bgFillTyp === 'GRADIENT_FILL') {
|
|
const gradientFill = getBgGradientFill(bgFillLstIdx, phClr, slideMasterContent, warpObj)
|
|
if (typeof gradientFill === 'string') {
|
|
background = gradientFill
|
|
}
|
|
else if (gradientFill) {
|
|
background = gradientFill
|
|
backgroundType = 'gradient'
|
|
}
|
|
}
|
|
else if (bgFillTyp === 'PIC_FILL') {
|
|
background = await getBgPicFill(bgFillLstIdx, 'themeBg', warpObj)
|
|
backgroundType = 'image'
|
|
}
|
|
else if (bgFillTyp === 'PATTERN_FILL') {
|
|
const patternFill = getPatternFill(bgFillLstIdx, warpObj)
|
|
if (patternFill) {
|
|
background = patternFill
|
|
backgroundType = 'pattern'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
type: backgroundType,
|
|
value: background,
|
|
}
|
|
}
|
|
|
|
export async function getShapeFill(node, warpObj, source, groupHierarchy = []) {
|
|
const fillType = getFillType(getTextByPathList(node, ['p:spPr']))
|
|
let type = 'color'
|
|
let fillValue = ''
|
|
if (fillType === 'NO_FILL') {
|
|
return null
|
|
}
|
|
else if (fillType === 'SOLID_FILL') {
|
|
const shpFill = node['p:spPr']['a:solidFill']
|
|
fillValue = getSolidFill(shpFill, undefined, undefined, warpObj)
|
|
type = 'color'
|
|
}
|
|
else if (fillType === 'GRADIENT_FILL') {
|
|
const shpFill = node['p:spPr']['a:gradFill']
|
|
fillValue = getGradientFill(shpFill, warpObj)
|
|
type = 'gradient'
|
|
}
|
|
else if (fillType === 'PIC_FILL') {
|
|
const shpFill = node['p:spPr']['a:blipFill']
|
|
const picBase64 = await getPicFill(source, shpFill, warpObj)
|
|
const opacity = getPicFillOpacity(shpFill)
|
|
fillValue = {
|
|
picBase64,
|
|
opacity,
|
|
}
|
|
type = 'image'
|
|
}
|
|
else if (fillType === 'PATTERN_FILL') {
|
|
const shpFill = node['p:spPr']['a:pattFill']
|
|
fillValue = getPatternFill({ 'a:pattFill': shpFill }, warpObj)
|
|
type = 'pattern'
|
|
}
|
|
else if (fillType === 'GROUP_FILL') {
|
|
return findFillInGroupHierarchy(groupHierarchy, warpObj, source)
|
|
}
|
|
if (!fillValue) {
|
|
const clrName = getTextByPathList(node, ['p:style', 'a:fillRef'])
|
|
fillValue = getSolidFill(clrName, undefined, undefined, warpObj)
|
|
type = 'color'
|
|
}
|
|
if (!fillValue) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
type,
|
|
value: fillValue,
|
|
}
|
|
}
|
|
|
|
async function findFillInGroupHierarchy(groupHierarchy, warpObj, source) {
|
|
for (const groupNode of groupHierarchy) {
|
|
if (!groupNode || !groupNode['p:grpSpPr']) continue
|
|
|
|
const grpSpPr = groupNode['p:grpSpPr']
|
|
const fillType = getFillType(grpSpPr)
|
|
|
|
if (fillType === 'SOLID_FILL') {
|
|
const shpFill = grpSpPr['a:solidFill']
|
|
const fillValue = getSolidFill(shpFill, undefined, undefined, warpObj)
|
|
if (fillValue) {
|
|
return {
|
|
type: 'color',
|
|
value: fillValue,
|
|
}
|
|
}
|
|
}
|
|
else if (fillType === 'GRADIENT_FILL') {
|
|
const shpFill = grpSpPr['a:gradFill']
|
|
const fillValue = getGradientFill(shpFill, warpObj)
|
|
if (fillValue) {
|
|
return {
|
|
type: 'gradient',
|
|
value: fillValue,
|
|
}
|
|
}
|
|
}
|
|
else if (fillType === 'PIC_FILL') {
|
|
const shpFill = grpSpPr['a:blipFill']
|
|
const picBase64 = await getPicFill(source, shpFill, warpObj)
|
|
const opacity = getPicFillOpacity(shpFill)
|
|
if (picBase64) {
|
|
return {
|
|
type: 'image',
|
|
value: {
|
|
picBase64,
|
|
opacity,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
else if (fillType === 'PATTERN_FILL') {
|
|
const shpFill = grpSpPr['a:pattFill']
|
|
const fillValue = getPatternFill({ 'a:pattFill': shpFill }, warpObj)
|
|
if (fillValue) {
|
|
return {
|
|
type: 'pattern',
|
|
value: fillValue,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return null
|
|
}
|
|
|
|
export function getSolidFill(solidFill, clrMap, phClr, warpObj) {
|
|
if (!solidFill) return ''
|
|
|
|
let color = ''
|
|
let clrNode
|
|
|
|
if (solidFill['a:srgbClr']) {
|
|
clrNode = solidFill['a:srgbClr']
|
|
color = getTextByPathList(clrNode, ['attrs', 'val'])
|
|
}
|
|
else if (solidFill['a:schemeClr']) {
|
|
clrNode = solidFill['a:schemeClr']
|
|
const schemeClr = 'a:' + getTextByPathList(clrNode, ['attrs', 'val'])
|
|
color = getSchemeColorFromTheme(schemeClr, warpObj, clrMap, phClr) || ''
|
|
}
|
|
else if (solidFill['a:scrgbClr']) {
|
|
clrNode = solidFill['a:scrgbClr']
|
|
const defBultColorVals = clrNode['attrs']
|
|
const red = (defBultColorVals['r'].indexOf('%') !== -1) ? defBultColorVals['r'].split('%').shift() : defBultColorVals['r']
|
|
const green = (defBultColorVals['g'].indexOf('%') !== -1) ? defBultColorVals['g'].split('%').shift() : defBultColorVals['g']
|
|
const blue = (defBultColorVals['b'].indexOf('%') !== -1) ? defBultColorVals['b'].split('%').shift() : defBultColorVals['b']
|
|
color = toHex(255 * (Number(red) / 100)) + toHex(255 * (Number(green) / 100)) + toHex(255 * (Number(blue) / 100))
|
|
}
|
|
else if (solidFill['a:prstClr']) {
|
|
clrNode = solidFill['a:prstClr']
|
|
const prstClr = getTextByPathList(clrNode, ['attrs', 'val'])
|
|
color = getColorName2Hex(prstClr)
|
|
}
|
|
else if (solidFill['a:hslClr']) {
|
|
clrNode = solidFill['a:hslClr']
|
|
const defBultColorVals = clrNode['attrs']
|
|
const hue = Number(defBultColorVals['hue']) / 100000
|
|
const sat = Number((defBultColorVals['sat'].indexOf('%') !== -1) ? defBultColorVals['sat'].split('%').shift() : defBultColorVals['sat']) / 100
|
|
const lum = Number((defBultColorVals['lum'].indexOf('%') !== -1) ? defBultColorVals['lum'].split('%').shift() : defBultColorVals['lum']) / 100
|
|
const hsl2rgb = hslToRgb(hue, sat, lum)
|
|
color = toHex(hsl2rgb.r) + toHex(hsl2rgb.g) + toHex(hsl2rgb.b)
|
|
}
|
|
else if (solidFill['a:sysClr']) {
|
|
clrNode = solidFill['a:sysClr']
|
|
const sysClr = getTextByPathList(clrNode, ['attrs', 'lastClr'])
|
|
if (sysClr) color = sysClr
|
|
}
|
|
|
|
let isAlpha = false
|
|
const alpha = parseInt(getTextByPathList(clrNode, ['a:alpha', 'attrs', 'val'])) / 100000
|
|
if (!isNaN(alpha)) {
|
|
const al_color = tinycolor(color)
|
|
al_color.setAlpha(alpha)
|
|
color = al_color.toHex8()
|
|
isAlpha = true
|
|
}
|
|
|
|
const hueMod = parseInt(getTextByPathList(clrNode, ['a:hueMod', 'attrs', 'val'])) / 100000
|
|
if (!isNaN(hueMod)) {
|
|
color = applyHueMod(color, hueMod, isAlpha)
|
|
}
|
|
const lumMod = parseInt(getTextByPathList(clrNode, ['a:lumMod', 'attrs', 'val'])) / 100000
|
|
if (!isNaN(lumMod)) {
|
|
color = applyLumMod(color, lumMod, isAlpha)
|
|
}
|
|
const lumOff = parseInt(getTextByPathList(clrNode, ['a:lumOff', 'attrs', 'val'])) / 100000
|
|
if (!isNaN(lumOff)) {
|
|
color = applyLumOff(color, lumOff, isAlpha)
|
|
}
|
|
const satMod = parseInt(getTextByPathList(clrNode, ['a:satMod', 'attrs', 'val'])) / 100000
|
|
if (!isNaN(satMod)) {
|
|
color = applySatMod(color, satMod, isAlpha)
|
|
}
|
|
const shade = parseInt(getTextByPathList(clrNode, ['a:shade', 'attrs', 'val'])) / 100000
|
|
if (!isNaN(shade)) {
|
|
color = applyShade(color, shade, isAlpha)
|
|
}
|
|
const tint = parseInt(getTextByPathList(clrNode, ['a:tint', 'attrs', 'val'])) / 100000
|
|
if (!isNaN(tint)) {
|
|
color = applyTint(color, tint, isAlpha)
|
|
}
|
|
|
|
if (color && color.indexOf('#') === -1) color = '#' + color
|
|
|
|
return color
|
|
} |