var cardMasterList = new Array() var uniqueNumberTracker = 0 var frameImageList = new Array() var maskImageList = new Array() var maskNameList = new Array() var canvasList = new Array() var contextList = new Array() var loadedVersions = new Array() var currentVersion var cardMaster = document.getElementById('cardMaster') var selectedFrameImage var selectedMaskImage = 0 var selectedCardMasterElement = -1 var selectedTextObject var cardTextList = new Array() var manaSymbolCodeList = [] var manaSymbolImageList = [] var deletingCardObject = false var skipResizeCardArt = 0 var skipLoadTextList = 0 var usedManaSymbols = [] var totalShift = [0, 0] date = new Date() var cornerCutout = new Image() cornerCutout.src = '/data/images/cardImages/cornerCutout.png' //URL Parameters var URLParams = new URLSearchParams(window.location.search) function addToManaSymbolList(folderPath, newManaSymbolList) { for (var i = 0; i < newManaSymbolList.length; i ++) { if (!manaSymbolCodeList.includes(newManaSymbolList[i].replace('.svg', ''))) { if (newManaSymbolList[i].includes('.svg')) { manaSymbolCodeList.push(newManaSymbolList[i].replace('.svg', '')) manaSymbolImageList.push(new Image()) manaSymbolImageList[manaSymbolImageList.length - 1].src = folderPath + newManaSymbolList[i] } else { manaSymbolCodeList.push(newManaSymbolList[i]) manaSymbolImageList.push(new Image()) manaSymbolImageList[manaSymbolImageList.length - 1].src = folderPath + newManaSymbolList[i] + '.png' } } } } addToManaSymbolList('/data/images/cardImages/manaSymbols/', ["0.svg", "1.svg", "2.svg", "3.svg", "4.svg", "5.svg", "6.svg", "7.svg", "8.svg", "9.svg", "10.svg", "11.svg", "12.svg", "13.svg", "14.svg", "15.svg", "16.svg", "17.svg", "18.svg", "19.svg", "20.svg", "w.svg", "u.svg", "b.svg", "r.svg", "g.svg", "2w.svg", "2u.svg", "2b.svg", "2r.svg", "2g.svg", "pw.svg", "pu.svg", "pb.svg", "pr.svg", "pg.svg", "wu.svg", "wb.svg", "ub.svg", "ur.svg", "br.svg", "bg.svg", "rg.svg", "rw.svg", "gw.svg", "gu.svg", "x.svg", "s.svg", "c.svg", "t.svg","untap.svg", "e.svg", "y.svg", "z.svg", "half.svg", "inf.svg", "chaos.svg", "l+", "l-", "l0", "oldtap.svg", "artistbrush.svg", "bar", "whitebar", "whiteBrush", "blackBrush", 'star.svg']) function newCanvas(name) { window[name + 'Canvas'] = document.createElement('canvas') window[name + 'Canvas'].width = cardWidth window[name + 'Canvas'].height = cardHeight canvasList.push(window[name + 'Canvas']) window[name + 'Context'] = window[name + 'Canvas'].getContext('2d') contextList.push(window[name + 'Context']) } function resizeCanvases(newCardWidth, newCardHeight) { canvasList.forEach(element => {element.width = newCardWidth; element.height = newCardHeight}) } var previewCanvas = document.getElementById('previewCanvas') previewCanvas.width = 750 previewCanvas.height = 1050 var previewContext = previewCanvas.getContext('2d') newCanvas('main') newCanvas('frameMasks') newCanvas('textLine') newCanvas('textParagraph') newCanvas('text') newCanvas('bottomInfo') newCanvas('manaCost') newCanvas('watermark') newCanvas('temp') newCanvas('autoCrop') var artWidth = cardWidth, artHeight = cardHeight var setSymbolDrawX, setSymbolDrawY, setSymbolDrawWidth, setSymbolDrawHeight var watermarkDrawX = 0, watermarkDrawY = 0, watermarkDrawWidth = 0, watermarkDrawHeight = 0 var cardArt = new Image() cardArt.src = '/data/images/cardImages/blank.png' var setSymbol = new Image() setSymbol.src = '/data/images/cardImages/blank.png' var watermark = new Image() watermark.src = '/data/images/cardImages/blank.png' cardArt.crossOrigin = "anonymous" setSymbol.crossOrigin = "anonymous" watermark.crossOrigin = "anonymous" cardArt.onload = function() { cardMasterList[0].width = this.width / cardWidth cardMasterList[0].height = this.height / cardHeight if (skipResizeCardArt < 1) { if (this.width / this.height > artWidth / artHeight) { document.getElementById('inputCardArtZoom').value = artHeight / this.height * 100 } else { document.getElementById('inputCardArtZoom').value = artWidth / this.width * 100 } document.getElementById('inputCardArtX').value = artX document.getElementById('inputCardArtY').value = artY } else { skipResizeCardArt -= 1 } cardArtUpdated() } function setSymbolFromGatherer() { if (document.getElementById('inputSetCode').value.toLowerCase() == 'cc') { var newSetSymbolSource = '/data/images/cardImages/misc/cc-' + document.getElementById('inputSetRarity').value.toLowerCase() if (document.getElementById('inputSetRarity').value == '') { newSetSymbolSource += 'c' } setSymbol.src = newSetSymbolSource + '.png' } else if (document.getElementById('inputSetCode').value.toLowerCase() == 'none') { setSymbol.src = '/data/images/cardImages/blank.png' } else { setSymbol.src = 'https://cors-anywhere.herokuapp.com/http://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=' + document.getElementById('inputSetCode').value + '&size=large&rarity=' + document.getElementById('inputSetRarity').value // autoCrop(setSymbol, 'https://cors-anywhere.herokuapp.com/http://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=' + document.getElementById('inputSetCode').value + '&size=large&rarity=' + document.getElementById('inputSetRarity').value) } } setSymbol.onerror = function () { this.src = '/data/images/cardImages/blank.png' } setSymbol.onload = function() { if (setSymbol.width / setSymbol.height > setSymbolWidth / setSymbolHeight) { setSymbolDrawWidth = setSymbolWidth setSymbolDrawHeight = setSymbolWidth * setSymbol.height / setSymbol.width } else { setSymbolDrawHeight = setSymbolHeight setSymbolDrawWidth = setSymbolHeight * setSymbol.width / setSymbol.height } setSymbolDrawX = setSymbolX[0] if (setSymbolX[1] == 'right') { setSymbolDrawX -= setSymbolDrawWidth } else if (setSymbolX[1] == 'center') { setSymbolDrawX -= setSymbolDrawWidth / 2 } setSymbolDrawY = setSymbolY[0] if (setSymbolY[1] == 'center') { setSymbolDrawY -= setSymbolDrawHeight / 2 } drawCardObjects() } watermark.onload = function() { watermarkUpdated() } function loadVersion(versionToLoad) { totalShift = [0, 0] if (cardWidth / cardHeight == 7/5) { cardWidth *= 5/7 cardHeight *= 7/5 resizeCanvases(cardWidth, cardHeight) previewContext.rotate(Math.PI / 2) previewContext.translate(0, -cardHeight / 2) } else if (cardWidth != mainCanvas.width) { cardWidth = 1500 cardHeight = cardWidth * 7/5 resizeCanvases(cardWidth, cardHeight) } loadScript('/data/scripts/versions/' + versionToLoad + '/version.js') } class cardPlaceholder { constructor(displayName, whatToDraw, x = 0, y = 0, width = 1, height = 1, zoom = 1) { this.name = displayName this.whatToDraw = whatToDraw this.x = x this.y = y this.width = width this.height = height this.zoom = zoom this.uniqueNumber = uniqueNumberTracker uniqueNumberTracker += 1 } draw() { mainContext.globalCompositeOperation = 'source-over' mainContext.globalAlpha = 1 if (this.whatToDraw == textCanvas) { if (currentVersion.includes('m15Planeswalker/')) { mainContext.drawImage(planeswalkerCanvas, scaleX(totalShift[0]), scaleY(totalShift[1]), cardWidth, cardHeight) } else if (currentVersion.includes('saga')) { mainContext.drawImage(sagaCanvas, scaleX(totalShift[0]), scaleY(totalShift[1]), cardWidth, cardHeight) } mainContext.globalAlpha = parseInt(document.getElementById('inputWatermarkOpacity').value) / 100 mainContext.drawImage(watermarkCanvas, scaleX(totalShift[0]), scaleY(totalShift[1]), cardWidth, cardHeight) mainContext.globalAlpha = 1 mainContext.drawImage(manaCostCanvas, scaleX(totalShift[0]), scaleY(totalShift[1]), cardWidth, cardHeight) } else { mainContext.globalAlpha = 1 } mainContext.drawImage(this.whatToDraw, scaleX(this.x + totalShift[0]), scaleY(this.y + totalShift[1]), scaleX(this.width) * this.zoom, scaleY(this.height) * this.zoom) } cardMasterElement() { var temporaryElement = document.createElement('div') temporaryElement.id = 'uniqueNumber' + this.uniqueNumber temporaryElement.classList.add('cardMasterElement', 'interactable') temporaryElement.innerHTML = '|||
' + this.name + '
' return temporaryElement } } class cardImage { constructor(displayName = 'cardImage', imageSource = '/data/images/cardImages/blank.png', x = 0, y = 0, width = 1, height = 1, opacity = 1, masks = ['Full'], erase = false) { this.name = displayName this.image = new Image() this.image.src = imageSource this.imageSource = imageSource this.x = x this.y = y this.width = width this.height = height this.opacity = opacity this.masks = masks this.erase = erase this.uniqueNumber = uniqueNumberTracker uniqueNumberTracker += 1 } draw() { frameMasksContext.clearRect(0, 0, frameMasksCanvas.width, frameMasksCanvas.height) if (this.masks.length > 0 && this.masks != 'Full') { frameMasksContext.drawImage(maskImageList[maskNameList.indexOf(this.masks[0])], scaleX(totalShift[0]), scaleY(totalShift[1]), cardWidth, cardHeight) frameMasksContext.globalCompositeOperation = 'source-in' for (var i = 1; i < this.masks.length; i++) { frameMasksContext.drawImage(maskImageList[maskNameList.indexOf(this.masks[i])], scaleX(totalShift[0]), scaleY(totalShift[1]), cardWidth, cardHeight) } frameMasksContext.drawImage(this.image, scaleX(this.x + totalShift[0]), scaleY(this.y + totalShift[1]), scaleX(this.width), scaleY(this.height)) frameMasksContext.globalCompositeOperation = 'source-over' } else { frameMasksContext.drawImage(this.image, scaleX(this.x + totalShift[0]), scaleY(this.y + totalShift[1]), scaleX(this.width), scaleY(this.height)) } mainContext.globalAlpha = this.opacity if (this.erase) { mainContext.globalCompositeOperation = 'destination-out' } else { mainContext.globalCompositeOperation = 'source-over' } mainContext.drawImage(frameMasksCanvas, 0, 0, frameMasksCanvas.width, frameMasksCanvas.height) // mainContext.globalCompositeOperation = 'source-over' } cardMasterElement() { var temporaryElement = document.createElement('div') temporaryElement.id = 'uniqueNumber' + this.uniqueNumber temporaryElement.classList.add('cardMasterElement', 'interactable') temporaryElement.innerHTML = '
|||
' + this.name + ' - ' + this.masks.toString().replace(',', ', ') + '
X' temporaryElement.onclick = function() { if (document.getElementById('cardMasterElementEditor').classList.contains('hidden') && !deletingCardObject) { document.getElementById('cardMasterElementEditor').classList.remove('hidden') } else { deletingCardObject = false } selectedCardMasterElement = parseInt(this.id.replace('uniqueNumber', '')) var selectedObject = cardMasterList[selectedCardMasterElement] document.getElementById('cardMasterElementEditorX').value = scaleX(selectedObject.x) document.getElementById('cardMasterElementEditorY').value = scaleY(selectedObject.y) document.getElementById('cardMasterElementEditorScale').value = scaleX(selectedObject.width) document.getElementById('cardMasterElementEditorOpacity').value = selectedObject.opacity * 100 document.getElementById('cardMasterElementEditorErase').checked = selectedObject.erase Array.from(document.getElementById('cardMaster').children).forEach(element => element.classList.remove('selected')) this.classList.add('selected') } return temporaryElement } } class cardText { constructor(displayName, text, x, y, width, height, font, fontSize, fontColor, other = []) { this.name = displayName this.text = text this.x = x this.y = y this.width = width this.height = height this.font = font this.fontSize = fontSize this.fontColor = fontColor this.otherParameters = other } } function scaleX(xToScale) { return Math.round(xToScale * cardWidth) } function scaleY(yToScale) { return Math.round(yToScale * cardHeight) } function drawCardObjects() { mainContext.clearRect(0, 0, mainCanvas.width, mainCanvas.height) previewContext.clearRect(0, 0, cardWidth, cardHeight) var cardMasterChildren = cardMaster.children for (var i = cardMasterChildren.length - 1; i >= 0; i--) { var uniqueNumber = parseInt(cardMasterChildren[i].id.replace('uniqueNumber', '')) for (var n = 0; n < cardMasterList.length; n++) { if (cardMasterList[n].uniqueNumber == uniqueNumber) { cardMasterList[n].draw() } } } mainContext.drawImage(setSymbol, setSymbolDrawX + getFloat('inputSetSymbolX') + scaleX(totalShift[0]), setSymbolDrawY + getFloat('inputSetSymbolY') + scaleY(totalShift[1]), setSymbolDrawWidth * getFloat('inputSetSymbolZoom') / 100, setSymbolDrawHeight * getFloat('inputSetSymbolZoom') / 100) mainContext.drawImage(bottomInfoCanvas, scaleX(totalShift[0]), scaleY(totalShift[1]), cardWidth, cardHeight) mainContext.globalCompositeOperation = 'destination-over' mainContext.drawImage(cardArt, scaleX(cardMasterList[0].x + totalShift[0]), scaleY(cardMasterList[0].y + totalShift[1]), scaleX(cardMasterList[0].width) * cardMasterList[0].zoom, scaleY(cardMasterList[0].height) * cardMasterList[0].zoom) mainContext.globalCompositeOperation = 'destination-out' //draw the corner cutters if (currentVersion != 'bleedEdge/version') { mainContext.drawImage(cornerCutout, 0, 0, scaleX(59/1500), scaleX(59/1500)) mainContext.rotate(Math.PI / 2) mainContext.drawImage(cornerCutout, 0, -cardWidth, scaleX(59/1500), scaleX(59/1500)) mainContext.rotate(Math.PI / 2) mainContext.drawImage(cornerCutout, -cardWidth, -cardHeight, scaleX(59/1500), scaleX(59/1500)) mainContext.rotate(Math.PI / 2) mainContext.drawImage(cornerCutout, -cardHeight, 0, scaleX(59/1500), scaleX(59/1500)) mainContext.rotate(Math.PI / 2) } //preview the card mainContext.globalCompositeOperation = 'source-over' if (cardWidth < cardHeight) { previewContext.drawImage(mainCanvas, 0, 0, previewCanvas.width, previewCanvas.height) } else { previewContext.drawImage(mainCanvas, 0, 0, previewCanvas.height, previewCanvas.width) } } class frameImage { constructor(displayName = 'custom', imageSource = '', x = 0, y = 0, width = 1, height = 1, masks = [], frameImageListIndex, frameClass) { this.name = displayName this.image = new Image() if (this.name == 'custom') { this.image.crossOrigin = 'anonymous' } this.image.src = imageSource this.x = x this.y = y this.width = width this.height = height this.masks = masks this.framePickerElement = document.createElement('div') this.framePickerElement.id = 'frameIndex' + frameImageListIndex this.framePickerElement.classList.add(frameClass, 'interactable') this.framePickerElement.onclick = this.frameOptionClicked this.framePickerElement.innerHTML = '' document.getElementById('framePicker').appendChild(this.framePickerElement) } frameOptionClicked() { Array.from(document.getElementById('framePicker').children).forEach(element => element.classList.remove('selected')) this.classList.add('selected') if (parseInt(this.id.replace('frameIndex', '')) != selectedFrameImage) { selectedFrameImage = parseInt(this.id.replace('frameIndex', '')) document.getElementById('maskPicker').innerHTML = '' frameImageList[parseInt(this.id.replace('frameIndex', ''))].masks.forEach(array => document.getElementById('maskPicker').innerHTML += '
' + array + '
') document.getElementById('maskPicker').children[0].classList.add('selected') selectedMaskImage = parseInt(document.getElementById('maskPicker').children[0].id.replace('maskOption', '')) updateSelectedFramePreview() } } } function maskOptionClicked(event) { Array.from(document.getElementById('maskPicker').children).forEach(element => element.classList.remove('selected')) if (event.target.nodeName == 'IMG') { event.target.parentElement.classList.add('selected') selectedMaskImage = parseInt(event.target.parentElement.id.replace('maskOption', '')) } else { event.target.classList.add('selected') selectedMaskImage = parseInt(event.target.id.replace('maskOption', '')) } updateSelectedFramePreview() } function updateSelectedFramePreview() { document.getElementById('previewSelectedFrame').innerHTML = '(Selected: ' + frameImageList[selectedFrameImage].name + ' with a ' + maskNameList[selectedMaskImage] + ' mask.)' } function loadFramePackOptions(listOfFramePacks) { var framePackHTML = '' for (var i = 0; i < listOfFramePacks.length; i++) { var framePackOptionDisabled = '' if (listOfFramePacks[i][0] == 'disabled') { framePackOptionDisabled = 'disabled ' } framePackHTML += '' } document.getElementById('inputFramePack').innerHTML = framePackHTML loadScript('/data/scripts/versions/' + document.getElementById('inputFrameVersion').value + '/regular.js') } function loadMaskImages(listOfMasks) { for (var i = 0; i < listOfMasks.length; i++) { if (!maskNameList.includes(listOfMasks[i][0])) { var maskImage = new Image() maskImage.src = listOfMasks[i][1] maskImageList.push(maskImage) maskNameList.push(listOfMasks[i][0]) } } } function loadFrameImages(listOfFrames, frameClass) { var firstFrameIndex = 0 for (var i = 0; i < listOfFrames.length; i++) { if (i == 0) { firstFrameIndex = frameImageList.length } frameImageList.push(new frameImage(...listOfFrames[i], frameImageList.length, frameClass)) } frameImageList[firstFrameIndex].framePickerElement.click() } //Loads up anything that uses Sortable.js var sortable = Sortable.create(cardMaster, {animation: 150, ghostClass: 'cardMasterElementMoving', handle: '.handle'}) function deleteCardObject(event) { var isItPT = event.target.parentElement.children[2].innerHTML.includes('Power/Toughness') cardMaster.removeChild(document.getElementById('uniqueNumber' + parseInt(event.target.parentElement.id.replace('uniqueNumber', '')))) selectedCardMasterElement = -1 if (isItPT) { bottomInfoUpdated() } else { drawCardObjects() } deletingCardObject = true document.getElementById('cardMasterElementEditor').classList.add('hidden') } function addSelectedFrame(additionalMasks = []) { var selectedFrameObject = frameImageList[selectedFrameImage] var masksToUse = additionalMasks masksToUse.unshift(maskNameList[selectedMaskImage]) var objectToInsert = cardMasterList.push(new cardImage(selectedFrameObject.name, selectedFrameObject.image.src, selectedFrameObject.x, selectedFrameObject.y, selectedFrameObject.width, selectedFrameObject.height, 1, masksToUse, false)) cardMaster.insertBefore(cardMasterList[objectToInsert - 1].cardMasterElement(), cardMaster.children[1]) if (selectedFrameObject.name.includes('Power/Toughness')) { bottomInfoUpdated() } else { drawCardObjects() } // setTimeout(drawCardObjects, 100) } function cardMasterElementEdited() { var selectedObject = cardMasterList[selectedCardMasterElement] selectedObject.x = getFloat('cardMasterElementEditorX') / cardWidth selectedObject.y = getFloat('cardMasterElementEditorY') / cardHeight selectedObject.height = selectedObject.height / selectedObject.width * getFloat('cardMasterElementEditorScale') / cardWidth selectedObject.width = getFloat('cardMasterElementEditorScale') / cardWidth selectedObject.opacity = getFloat('cardMasterElementEditorOpacity') / 100 selectedObject.erase = document.getElementById('cardMasterElementEditorErase').checked drawCardObjects() } function getFloat(input) { var getFloatResponse = parseFloat(document.getElementById(input).value) if (getFloatResponse) { return getFloatResponse } else { return 0 } } function loadTextOptions(textArray = []) { document.getElementById('textPicker').innerHTML = '' var backupTextValues = cardTextList if (skipLoadTextList < 1) { cardTextList = textArray } for (var i = 0; i < cardTextList.length; i++) { for (var n = 0; n < backupTextValues.length; n++) { if (cardTextList[i].name == backupTextValues[n].name && skipLoadTextList < 1) { cardTextList[i].text = backupTextValues[n].text } } document.getElementById('textPicker').innerHTML += '
' + cardTextList[i].name + '
' } document.getElementById('textPicker').children[0].click() cardTextEdited() if (setSymbol.src != '') { setSymbol.onload() } if (cardArt.src != '') { cardArt.onload() } else if (skipResizeCardArt > 0) { skipResizeCardArt -= 1 } if (skipLoadTextList > 0) { skipLoadTextList -= 1 } manaCostUpdated() bottomInfoUpdated() } function textOptionClicked(event, index) { Array.from(document.getElementById('textPicker').children).forEach(element => element.classList.remove('selected')) event.target.classList.add('selected') selectedTextObject = cardTextList[index] document.getElementById('textEditorText').value = selectedTextObject.text document.getElementById('textEditorX').value = scaleX(selectedTextObject.x) document.getElementById('textEditorY').value = scaleY(selectedTextObject.y) document.getElementById('textEditorWidth').value = scaleX(selectedTextObject.width) document.getElementById('textEditorHeight').value = scaleY(selectedTextObject.height) } function cardTextEdited() { selectedTextObject.text = document.getElementById('textEditorText').value selectedTextObject.x = document.getElementById('textEditorX').value / cardWidth selectedTextObject.y = document.getElementById('textEditorY').value / cardHeight selectedTextObject.width = document.getElementById('textEditorWidth').value / cardWidth selectedTextObject.height = document.getElementById('textEditorHeight').value / cardHeight drawCardText() if (selectedTextObject.name == 'Power/Toughness') { bottomInfoUpdated() } } function drawCardTextReal() { textContext.clearRect(0, 0, cardWidth, cardHeight) writeText(cardTextList, textContext) } function drawCardText() { clearTimeout(updateTextDelay) updateTextDelay = setTimeout(drawCardTextReal, 250) } function writeText(textObjectList, targetContext) { var textCanvasBuffer = 100 var rewritingLine = false var textSize, textFont var savedTextX = 0 outerloop: for (var i = 0; i < textObjectList.length; i++) { //FINDME - TESTING PURPOSES ONLY if (URLParams.get('copyright') != null && textObjectList[i].text.includes('\u2122 & \u00a9 ' + date.getFullYear() + ' Wizards of the Coast') && currentVersion.includes('bleedEdge')) { textObjectList[i].text = textObjectList[i].text.replace('\u2122 & \u00a9 ' + date.getFullYear() + ' Wizards of the Coast', URLParams.get('copyright')) } if (!rewritingLine) { textSize = scaleY(textObjectList[i].fontSize) } else { var fontSizeCode = textObjectList[i].text.split(/\n| |{line}/)[0].toLowerCase() if (fontSizeCode.includes('{fontsize') && fontSizeCode.includes('}') && fontSizeCode.split('{fontsize')[1].indexOf('}') != -1 && fontSizeCode.split('{fontsize')[1].indexOf('}') < 4) { textSize = scaleY(textObjectList[i].fontSize) var fontSizeCodeStart = fontSizeCode.indexOf('{fontsize') + 9 var fontSizeCodeValueLength = fontSizeCode.split('{fontsize')[1].indexOf('}') var fontSizeCodeValue = fontSizeCode.slice(fontSizeCodeStart, fontSizeCodeValueLength + fontSizeCodeStart) if (!parseInt(fontSizeCodeValue) && parseInt(fontSizeCodeValue) != 0) { textObjectList[i].text = textObjectList[i].text.replace('{fontsize' + fontSizeCodeValue + '}', '{fontsize0}') if (document.getElementById('textPicker').children[i].classList.contains('selected')) { var savedCursorPosition = document.getElementById('textEditorText').selectionStart - document.getElementById('textEditorText').value.length document.getElementById('textEditorText').value = textObjectList[i].text savedCursorPosition += document.getElementById('textEditorText').value.length document.getElementById('textEditorText').selectionStart = savedCursorPosition document.getElementById('textEditorText').selectionEnd = savedCursorPosition } rewritingLine = true i -= 1 continue outerloop } else { fontSizeCodeValue = parseInt(fontSizeCodeValue) if (!fontSizeCodeValue) { fontSizeCodeValue = 0 } textObjectList[i].text = textObjectList[i].text.replace('{fontsize' + fontSizeCodeValue + '}', '{fontsize' + (fontSizeCodeValue - 1) + '}') if (document.getElementById('textPicker').children[i].classList.contains('selected')) { var savedCursorPosition = document.getElementById('textEditorText').selectionStart - document.getElementById('textEditorText').value.length document.getElementById('textEditorText').value = textObjectList[i].text savedCursorPosition += document.getElementById('textEditorText').value.length document.getElementById('textEditorText').selectionStart = savedCursorPosition document.getElementById('textEditorText').selectionEnd = savedCursorPosition } } } else { textSize -= 1 } } rewritingLine = false textLineCanvas.width = scaleX(textObjectList[i].width) + 2 * textCanvasBuffer textLineCanvas.height = textSize + 2 * textCanvasBuffer textParagraphCanvas.width = scaleX(textObjectList[i].width) + 2 * textCanvasBuffer textParagraphCanvas.height = scaleY(textObjectList[i].height) + 2 * textCanvasBuffer textLineContext.clearRect(0, 0, textLineCanvas.width, textLineCanvas.height) textParagraphContext.clearRect(0, 0, textParagraphCanvas.width, textParagraphCanvas.height) var outlineColor = 'black', outline = false, shadow = 0, oneLine = false, outlineThickness = 2, textAlign = 'left', finishLine = false, paragraphSpace = 0, permanentLineShift = 0, temporaryLineShift = 0, fontStyle = '', textFontExtension = '', manaCost = false, canWriteText = true textObjectList[i].otherParameters.forEach(item => eval(item)) textLineContext.shadowOffsetX = shadow textLineContext.shadowOffsetY = shadow textLineContext.shadowBlur = 0 textLineContext.shadowColor = 'black' textLineContext.strokeStyle = outlineColor textLineContext.lineWidth = outlineThickness textFont = textObjectList[i].font textLineContext.font = fontStyle + textSize + 'px ' + textFont + textFontExtension var currentFontColor = textObjectList[i].fontColor textLineContext.fillStyle = currentFontColor var textX = textCanvasBuffer var textY = 0 var currentLineWidth = 0 var splitText = textObjectList[i].text.replace(/\n/g, '{line}').replace(/{flavor}/g, '{lns}{bar}{lns}{i}').replace(/{/g, 'fh48a3h2{').replace(/}/g, '}fh48a3h2').replace(/ /g, 'fh48a3h2 fh48a3h2').split('fh48a3h2') if (manaCost) { splitText = '{' + textObjectList[i].text.replace(/\n/g, '').replace(/{/g, ' ').replace(/}/g, ' ').replace(/ /g, '}fh48a3h2{right4}fh48a3h2{') + '}' splitText = splitText.split('fh48a3h2') } splitText.push('') innerloop: for (var n = 0; n < splitText.length; n++) { if (splitText[n] != '' || n == splitText.length - 1) { wordToWrite = '' if (splitText[n][0] == '{' && splitText[n][splitText[n].length - 1] == '}') { var possibleCodeLower = splitText[n].substr(1, splitText[n].length - 2).toLowerCase() if (possibleCodeLower == 'line' && !oneLine) { finishLine = true paragraphSpace += textSize * 0.35 } else if ((possibleCodeLower == 'linenospace' || possibleCodeLower == 'lns') && !oneLine) { finishLine = true } else if ((possibleCodeLower == 'bar' || possibleCodeLower == 'flavor') && !oneLine) { var barWidth = scaleX(textObjectList[i].width) * 0.95 var barHeight = scaleY(0.002) var barImageName = 'bar' if (currentFontColor == 'white') { barImageName = 'whitebar' } textLineContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf(barImageName)], textCanvasBuffer + (scaleX(textObjectList[i].width) - barWidth) / 2, textSize * 0.8 + textCanvasBuffer, barWidth, barHeight) currentLineWidth = scaleX(textObjectList[i].width) } else if (possibleCodeLower == 'i') { if (textFont == 'mplantin' && !textFontExtension.includes('i')) { textFontExtension += 'i' textLineContext.font = fontStyle + textSize + 'px ' + textFont + textFontExtension } else if (!fontStyle.includes('italic')) { fontStyle += 'italic ' textLineContext.font = fontStyle + textSize + 'px ' + textFont + textFontExtension } } else if (possibleCodeLower == '/i') { if (textFont == 'mplantin') { textFontExtension = textFontExtension.replace('i', '') textLineContext.font = fontStyle + textSize + 'px ' + textFont + textFontExtension } else { fontStyle = fontStyle.replace('italic ', '') textLineContext.font = fontStyle + textSize + 'px ' + textFont + textFontExtension } } else if (possibleCodeLower.includes('fontsize')) { if (parseInt(possibleCodeLower.slice(8, possibleCodeLower.length))) { textSize += parseInt(possibleCodeLower.slice(8, possibleCodeLower.length)) textLineContext.font = fontStyle + textSize + 'px ' + textFont + textFontExtension } } else if (possibleCodeLower == 'left') { textAlign = 'left' } else if (possibleCodeLower == 'center') { textAlign = 'center' } else if (possibleCodeLower == 'right') { textAlign = 'right' } else if (possibleCodeLower.includes('right')) { textX += parseInt(possibleCodeLower.replace('right', '')) currentLineWidth += parseInt(possibleCodeLower.replace('right', '')) permanentLineShift += parseInt(possibleCodeLower.replace('right', '')) } else if (possibleCodeLower.includes('left')) { textX -= parseInt(possibleCodeLower.replace('left', '')) currentLineWidth -= parseInt(possibleCodeLower.replace('left', '')) permanentLineShift -= parseInt(possibleCodeLower.replace('left', '')) } else if (possibleCodeLower.includes('up')) { finishLine = true paragraphSpace -= parseInt(possibleCodeLower.replace('up', '')) + textSize temporaryLineShift += currentLineWidth } else if (possibleCodeLower.includes('down')) { finishLine = true paragraphSpace += parseInt(possibleCodeLower.replace('down', '')) - textSize temporaryLineShift += currentLineWidth } else if (possibleCodeLower == 'savetextx') { savedTextX = textX } else if (possibleCodeLower == 'loadtextx') { textX = savedTextX } else if (possibleCodeLower.includes('outline:')) { if (parseInt(possibleCodeLower.replace('outline:', '').split(',')[1]) == 0) { outline = false } else { outline = true textLineContext.strokeStyle = possibleCodeLower.replace('outline:', '').split(',')[0] textLineContext.lineWidth = parseInt(possibleCodeLower.replace('outline:', '').split(',')[1]) } } else if (possibleCodeLower.includes('shadow')) { var shadowOffset = parseInt(possibleCodeLower.replace('shadow', '')) textLineContext.shadowOffsetX = shadowOffset textLineContext.shadowOffsetY = shadowOffset } else if (possibleCodeLower.includes('fontcolor')) { currentFontColor = possibleCodeLower.slice(9, possibleCodeLower.length) textLineContext.fillStyle = currentFontColor } else if (possibleCodeLower == 'star') { var starWidth = textSize * 0.7 var starSpace = textSize * 0.18 textLineContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf('star')], textX + starSpace, textCanvasBuffer + textSize - starWidth * 1.01, starWidth, starWidth * 91/96) textX += starWidth + starSpace * 2 currentLineWidth += starWidth + starSpace * 2 } else if (possibleCodeLower == 'artistbrush') { var artistBrushWidth = textSize * 1.08 textLineContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf('artistbrush')], textX, textCanvasBuffer + textSize - artistBrushWidth * 0.63, artistBrushWidth, artistBrushWidth * 59 / 101) textX += artistBrushWidth * 1.1 currentLineWidth += artistBrushWidth * 1.1 } else if (possibleCodeLower == 'oldartistbrush') { var artistBrushWidth = textSize * 2.4 if (textLineContext.fillStyle == '#ffffff' || textLineContext.fillStyle == 'white') { textLineContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf('whiteBrush')], textX, textCanvasBuffer + textSize - artistBrushWidth * 13 / 63, artistBrushWidth, artistBrushWidth * 13 / 63); } else { textLineContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf('blackBrush')], textX, textCanvasBuffer + textSize - artistBrushWidth * 13 / 63, artistBrushWidth, artistBrushWidth * 13 / 63); } textX += artistBrushWidth * 1.1 currentLineWidth += artistBrushWidth * 1.1 } else if (possibleCodeLower.includes('font')) { textFont = possibleCodeLower.replace('font', '') textLineContext.font = fontStyle + textSize + 'px ' + textFont + textFontExtension } else if (possibleCodeLower == 'planechase') { textLineContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf('chaos')], textX, textCanvasBuffer + textSize - scaleX(40/2100), scaleX(102/2100), scaleX(85/2100)) textX += scaleX(125/2100) currentLineWidth += scaleX(125/2100) permanentLineShift += scaleX(125/2100) } else if (manaSymbolCodeList.includes(possibleCodeLower.split('/').reverse().join(''))) { //THIS HAS TO BE THE LAST ONE var manaSymbolDiameter = textSize * 0.78 if (manaCost && manaCostShadowOffset != 'none') { var shadowOffset = eval(manaCostShadowOffset) textLineContext.beginPath() textLineContext.arc(textX + manaSymbolDiameter / 2 + shadowOffset[0], textCanvasBuffer + textSize - manaSymbolDiameter * 0.45 + shadowOffset[1], manaSymbolDiameter / 2, 0, 2 * Math.PI) textLineContext.fill() } textLineContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf(possibleCodeLower.split('/').reverse().join(''))], textX, textCanvasBuffer + textSize - manaSymbolDiameter * 0.95, manaSymbolDiameter, manaSymbolDiameter) currentLineWidth += manaSymbolDiameter * 1.13 textX += manaSymbolDiameter * 1.13 } else { wordToWrite = splitText[n] } } else { wordToWrite = splitText[n] } if (!canWriteText) { wordToWrite = '' } if (wordToWrite != '' || n == splitText.length - 1 || finishLine) { var currentWordWidth = textLineContext.measureText(wordToWrite).width if (currentWordWidth + currentLineWidth > scaleX(textObjectList[i].width) || n == splitText.length - 1 || finishLine) { if (oneLine && currentWordWidth + currentLineWidth > scaleX(textObjectList[i].width) && textSize > 1) { rewritingLine = true i -= 1 continue outerloop } var textAlignShift = 0 if (textAlign == 'center') { textAlignShift = (scaleX(textObjectList[i].width) - currentLineWidth) / 2 } else if (textAlign == 'right') { textAlignShift = scaleX(textObjectList[i].width) - currentLineWidth } textParagraphContext.drawImage(textLineCanvas, 0 + textAlignShift, textY, textLineCanvas.width, textLineCanvas.height) if (n != splitText.length - 1) { textLineContext.clearRect(0, 0, textLineCanvas.width, textLineCanvas.height) textX = textCanvasBuffer + permanentLineShift + temporaryLineShift currentLineWidth = 0 + permanentLineShift + temporaryLineShift textY += textSize + paragraphSpace paragraphSpace = 0 temporaryLineShift = 0 finishLine = false if (wordToWrite == " ") { continue innerloop } } } if (outline == true) { textLineContext.strokeText(wordToWrite, textX, textCanvasBuffer + textSize) } textLineContext.fillText(wordToWrite, textX, textCanvasBuffer + textSize) currentLineWidth += currentWordWidth textX += currentWordWidth } } if (n == splitText.length - 1) { //Finally, center the paragraph vertically if (textY + textSize > scaleY(textObjectList[i].height) && !oneLine && textSize > 1) { rewritingLine = true i -= 1 continue outerloop } targetContext.drawImage(textParagraphCanvas, scaleX(textObjectList[i].x) - textCanvasBuffer, scaleY(textObjectList[i].y) - textCanvasBuffer - textSize + (scaleY(textObjectList[i].height) - textY - textSize) / 2, textParagraphCanvas.width, textParagraphCanvas.height) } } } drawCardObjects() } function uploadImage(event, destination) { var input = event.target var reader = new FileReader() reader.onload = function() { var dataURL = reader.result destination.src = dataURL } reader.readAsDataURL(input.files[0]) } function cardArtUpdated() { cardMasterList[0].x = getFloat('inputCardArtX') / cardWidth cardMasterList[0].y = getFloat('inputCardArtY') / cardHeight cardMasterList[0].zoom = getFloat('inputCardArtZoom') / 100 drawCardObjects() } var savedArtList = [], cardArtUrlList = [], cardArtArtistList = [] function inputCardArtName(cardArtNameInput) { var xhttp = new XMLHttpRequest() xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { savedArtList = this.responseText.split('"art_crop":"') savedArtList.splice(0, 1) document.getElementById('inputCardArtNameNumber').max = savedArtList.length document.getElementById('inputCardArtNameNumber').value = 1 for (i = 0; i < savedArtList.length; i ++) { cardArtUrlList[i] = savedArtList[i].split('","border_crop":')[0] } for (i = 0; i < savedArtList.length; i ++) { cardArtArtistList[i] = savedArtList[i].slice(savedArtList[i].indexOf('"artist":"') + 10, savedArtList[i].indexOf('","artist_id')) } inputCardArtNameNumber(1) } else if (this.readyState == 4 && this.status == 404 && cardArtNameInput != '') { notify("Sorry, but we can't seem to find any art for '" + cardArtNameInput + "'", '#ffffaae0') } } xhttp.open('GET', 'https://api.scryfall.com/cards/search?order=released&unique=art&q=name%3D' + cardArtNameInput.replace(/ /g, '_'), true) xhttp.send() } function inputCardArtNameNumber(cardArtNameNumberInput) { var temporaryCardArt = new Image() temporaryCardArt.crossOrigin = 'anonymous' temporaryCardArt.onload = function() { cardArt.src = this.src } temporaryCardArt.src = cardArtUrlList[cardArtNameNumberInput - 1] //config.hosts << "img.scryfall.com" //environment configuration document.getElementById('inputInfoArtist').value = cardArtArtistList[cardArtNameNumberInput - 1] document.getElementById('inputInfoArtist2').value = document.getElementById('inputInfoArtist').value bottomInfoUpdated() } function initialize() { //Card stuff cardMasterList.push(new cardPlaceholder('Card Art Placeholder', cardArt)) cardMasterList.push(new cardPlaceholder('Text Placeholder', textCanvas)) cardMaster.insertBefore(cardMasterList[0].cardMasterElement(), cardMaster.children[0]) cardMaster.insertBefore(cardMasterList[1].cardMasterElement(), cardMaster.children[0]) document.getElementById('inputInfoNumber').value = date.getFullYear() window.updateTextDelay = setTimeout(drawCardTextReal, 250) setTimeout(bottomInfoUpdated, 500) textCodeReference() notify("Card Conjurer will be moving to a new hosting provider sometime this month. Along with the move, there will be some major updates to the card creator. Unfortunately, previously saved cards will not be compatible new system... But fear not! I will continue hosting the old version under cardconjurer.com/old for the foreseeable future. So, you may want to download all saved cards if you'd like to continue editing them. Regardless, please forgive any downtime/problems during the month of December as we move.", '#ffffaae0') } function bottomInfoUpdated() { window[bottomInfoFunction]() } function uploadLocalFrameImage(event) { var input = event.target var reader = new FileReader() reader.onload = function() { addUploadedFrameImage(reader.result) } reader.readAsDataURL(input.files[0]) } function addUploadedFrameImage(imageSource) { frameImageList.push(new frameImage('custom', imageSource, 0, 0, 1, 1, maskNameList, frameImageList.length, 'frameClassCustom')) } function manaCostUpdated() { usedManaSymbols = [] manaCostContext.clearRect(0, 0, cardWidth, cardHeight) var manaCostList = document.getElementById('inputManaCost').value.toLowerCase().replace(/{/g, ' ').replace(/}/g, ' ').split(' ') var manaSymbolIndex = -1 manaCostCanvas.fillStyle = 'black' if (manaCostDirection == 'reverse') { manaCostList.reverse() } for (var i = 0; i < manaCostList.length; i++) { if (manaSymbolCodeList.includes(manaCostList[i].split('/').reverse().join(''))) { usedManaSymbols.push(manaCostList[i]) manaSymbolIndex += 1 var x = eval(manaCostXPath) var y = eval(manaCostYPath) var diameter = eval(manaCostDiameter) if (manaCostShadowOffset != 'none' && !manaCostList[i].includes('m21')) { var shadowOffset = eval(manaCostShadowOffset) manaCostContext.beginPath() manaCostContext.arc(x + diameter / 2 + shadowOffset[0], y + diameter / 2 + shadowOffset[1], diameter / 2, 0, 2 * Math.PI) manaCostContext.fill() } manaCostContext.drawImage(manaSymbolImageList[manaSymbolCodeList.indexOf(manaCostList[i].split('/').reverse().join(''))], x, y, diameter, diameter) } } drawCardObjects() } function watermarkUpdated() { if (document.getElementById('inputWatermarkPrimary').value != 'none') { watermarkContext.clearRect(0, 0, cardWidth, cardHeight) if (watermarkWidth / watermarkHeight < watermark.width / watermark.height) { watermarkDrawWidth = watermarkWidth watermarkDrawHeight = watermarkWidth / watermark.width * watermark.height } else { watermarkDrawHeight = watermarkHeight watermarkDrawWidth = watermarkHeight / watermark.height * watermark.width } watermarkDrawX = watermarkX - watermarkDrawWidth / 2 watermarkDrawY = watermarkY - watermarkDrawHeight / 2 watermarkContext.drawImage(watermark, watermarkDrawX, watermarkDrawY, watermarkDrawWidth, watermarkDrawHeight) watermarkContext.globalCompositeOperation = 'source-in' if (document.getElementById('inputWatermarkPrimary').value != 'default') { watermarkContext.fillStyle = document.getElementById('inputWatermarkPrimary').value watermarkContext.fillRect(0, 0, cardWidth, cardHeight) } if (document.getElementById('inputWatermarkSecondary').value != 'none') { watermarkContext.globalCompositeOperation = 'source-atop' tempContext.clearRect(0, 0, cardWidth, cardHeight) tempContext.drawImage(maskImageList[maskNameList.indexOf('Right Half')], 0, 0, cardWidth, cardHeight) tempContext.globalCompositeOperation = 'source-in' if (document.getElementById('inputWatermarkSecondary').value == 'default') { tempContext.drawImage(watermark, watermarkDrawX, watermarkDrawY, watermarkDrawWidth, watermarkDrawHeight) } else { tempContext.fillStyle = document.getElementById('inputWatermarkSecondary').value tempContext.fillRect(0, 0, cardWidth, cardHeight) } tempContext.globalCompositeOperation = 'source-over' watermarkContext.drawImage(tempCanvas, 0, 0, cardWidth, cardHeight) } watermarkContext.globalCompositeOperation = 'source-over' } else { watermarkContext.clearRect(0, 0, cardWidth, cardHeight) } drawCardObjects() } var savedImportResponse = '' function inputCardNameTextImport(cardName) { var xhttp = new XMLHttpRequest() xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { savedImportResponse = this.responseText.split('{"object":"card"') inputCardNameNumberTextImport(1) document.getElementById('inputCardNameNumberTextImport').max = savedImportResponse.length - 1 document.getElementById('inputCardNameNumberTextImport').value = 1 } else if (this.readyState == 4 && this.status == 404 && cardName != '') { savedImportResponse = '' notify("Sorry, but we can't seem to find any card named '" + cardName + "'", '#ffffaae0') } } xhttp.open('GET', 'https://api.scryfall.com/cards/search?order=released&q=name%3D' + cardName.replace(/ /g, '+'), true) xhttp.send() } function inputCardNameNumberTextImport(index) { var importCardTextResponse = savedImportResponse[index] importText(beforeAfter(importCardTextResponse, '"name":"', '",'), 'Card Title') importText(beforeAfter(importCardTextResponse, '"type_line":"', '",'), 'Card Type') var flavorText = '{flavor}' + beforeAfter(importCardTextResponse, '"flavor_text":"', '","') var flavorTextStarCount = 0 if (flavorText.match(/\*/g)) { flavorTextStarCount = flavorText.match(/\*/g).length } for (var i = 0; i < flavorTextStarCount; i ++) { if (i % 2 == 0) { flavorText = flavorText.replace('*', '{/i}') } else { flavorText = flavorText.replace('*', '{i}') } } if (flavorText.length < 10 || URLParams.get('noflavor') != null) { flavorText = '' } importText((beforeAfter(importCardTextResponse, '"oracle_text":"', '",') + flavorText.replace(/\\n\u2014/g, '{lns}\u2014')).replace(/\n\\"/g, '\n\u201C').replace(/{flavor}\\"/g, '{flavor}\u201C').replace(/\\n/g, '\n').replace(/ \\"/g, ' \u201C').replace(/\\"/g, '\u201D').replace(/\(/g, '{i}(').replace(/\)/g, '){/i}'), 'Rules Text') if (importCardTextResponse.includes('"power":"')) { importText(beforeAfter(importCardTextResponse, '"power":"', '",') + '/' + beforeAfter(importCardTextResponse, '"toughness":"', '",'), 'Power/Toughness') } else { importText('', 'Power/Toughness') } if (importCardTextResponse.includes('"loyalty":"') && currentVersion.includes('m15Planeswalker/')) { importText(beforeAfter(importCardTextResponse, '"loyalty":"', '",'), 'Loyalty') var abilityList = beforeAfter(importCardTextResponse, '"oracle_text":"', '",').replace(/\u2212/g, '-').replace(/ \\"/g, ' \u201C').replace(/\\"/g, '\u201D').split(/\\n/g) for (var i = 0; i < abilityList.length; i++) { if (abilityList[i].slice(0, 4).includes(':')) { importText(abilityList[i].split(/: (.+)?/)[1], 'Ability ' + (i+1)) document.getElementById('inputPlaneswalker' + (i + 1) + 'Icon').value = abilityList[i].split(/: (.+)?/)[0] } else { importText('{left' + parseInt(scaleX(24/750)) + '}' + abilityList[i], 'Ability ' + (i+1)) document.getElementById('inputPlaneswalker' + (i + 1) + 'Icon').value = '' } if (document.getElementById('inputPlaneswalker' + (i + 1)).value < 1) { document.getElementById('inputPlaneswalker' + (i + 1)).value = 1 } } planeswalkerAbilities() } document.getElementById('inputManaCost').value = beforeAfter(importCardTextResponse, '"mana_cost":"', '",') document.getElementById('inputCardArtName').value = beforeAfter(importCardTextResponse, '"name":"', '",') document.getElementById('inputSetCode').value = beforeAfter(importCardTextResponse, '"set":"', '",') document.getElementById('inputSetRarity').value = beforeAfter(importCardTextResponse, '"rarity":"', '",')[0] setSymbolFromGatherer() // autoCrop(setSymbol, 'https://cors-anywhere.herokuapp.com/http://gatherer.wizards.com/Handlers/Image.ashx?type=symbol&set=' + document.getElementById('inputSetCode').value + '&size=large&rarity=' + document.getElementById('inputSetRarity').value) inputCardArtName(beforeAfter(importCardTextResponse, '"name":"', '",')) manaCostUpdated() drawCardText() } function importText(text, target) { for (var i = 0; i < cardTextList.length; i++) { if (cardTextList[i].name == target) { cardTextList[i].text = text } } document.getElementById('textPicker').children[0].click() drawCardObjects() } function beforeAfter(targetString, beforeString, afterString) { if (targetString.includes(beforeString) && targetString.includes(afterString)) { return targetString.split(beforeString)[1].split(afterString)[0] } else { return '' } } function toggleTabs(clickedElement, targetId) { Array.from(clickedElement.parentElement.children).forEach(element => element.classList.remove('selected')) clickedElement.classList.add('selected') Array.from(document.getElementById(targetId).parentElement.children).forEach(element => element.classList.add('hidden')) document.getElementById(targetId).classList.remove('hidden') } function downloadCardImage(linkElement) { if (document.getElementById("inputInfoArtist").value.replace(/ /g, "") != "") { var savedFileName = '' if (cardTextList[0].name == 'Card Nickname') { savedFileName = cardTextList[1].text + ' (' + cardTextList[0].text + ").png" } else { savedFileName = cardTextList[0].text + '.png' } linkElement.download = savedFileName if (linkElement.download == ".png") { linkElement.download = "card.png" } } else { event.preventDefault() notify("You must properly credit an artist before downloading!", '#ffaaaae0') } var cardImageData = mainCanvas.toDataURL() if (cardImageData == undefined) { notify("Sorry, but it seems that you cannot download your card. Please try using a different browser/device.", '#ffffaae0') } linkElement.href = cardImageData } function hideFrameImages(frameClass) { Array.from(document.getElementById('framePicker').children).forEach(element => { if (!element.classList.contains(frameClass)) { element.classList.add('hidden') } else { element.classList.remove('hidden') } }) manaCostUpdated() //Forces mana cost to update when loading new version (especially important for loading saved cards w/ special mana symbols) } function autoCrop(targetImage, source = targetImage.src) { var autoCropImage = new Image() autoCropImage.crossOrigin = 'anonymous' autoCropImage.src = source autoCropImage.onload = function() { var width = this.width var height = this.height autoCropCanvas.width = width autoCropCanvas.height = height autoCropContext.drawImage(this, 0, 0,) var pixels = {x:[], y:[]} var imageData = autoCropContext.getImageData(0, 0, width, height) var x, y, index if (imageData.data.length > 4) { for (y = 0; y < height; y++) { //scans from left to right, top to bottom for (x = 0; x < width; x++) { index = (y * width + x) * 4 + 3 //calculuates the alpha value index if (imageData.data[index] > 0) { pixels.x.push(x) pixels.y.push(y) //stores visible pixel coordinates } } } pixels.x.sort(function(a, b){return a - b}) pixels.y.sort(function(a, b){return a - b}) var n = pixels.x.length - 1 width = pixels.x[n] - pixels.x[0] height = pixels.y[n] - pixels.y[0] var cropped = autoCropContext.getImageData(pixels.x[0], pixels.y[0], width + 1, height + 1) autoCropCanvas.width = width + 1 autoCropCanvas.height = height + 1 autoCropContext.putImageData(cropped, 0, 0) setTimeout(function(){targetImage.src = autoCropCanvas.toDataURL()}, 100) } } } var textCodeReferenceArray = [ ['Code', 'Result'], ['{linenospace}', 'Moves to the next line without an extra space ({lns} for short)'], ['{bar}', 'Draws the flavor text bar on the current line'], ['{flavor}', 'Moves to the next line, draws the flavor text bar, and italicizes the following text'], ['{i}', 'Italicizes the text'], ['{/i}', 'Removes italicization'], ['{fontsize#}', 'Changes the font size by # pixels (relative - use negative integers to shrink text)'], ['{fontcolor#}', 'Changes the font color to #'], ['{left}', 'Aligns the text to the left'], ['{center}', 'Aligns the text to the center'], ['{right}', 'Aligns the text to the right'], ['{left#}', 'Shifts the following text # pixels to the left'], ['{right#}', 'Shifts the following text # pixels to the right'], ['{up#}', 'Shifts the following text # pixels up'], ['{down#}', 'Shifts the following text # pixels down'], ['{outline:*,#}', 'Outlines the following text by # pixels in * color'], ['{shadow#}', 'Adds a shadow # pixels away from the following text'], ['Notes:', 'For colors, you may use HTML color codes (ie \'green\'), hex color codes (ie \'#00ff00\'), or rgb (ie \'rgb(0,255,0)\')'] ] function textCodeReference() { textCodeReferenceArray.forEach(item => document.getElementById('textCodeReference').innerHTML += '
' + item[0] + '
' + item[1] + '
') } function notify(message, color) { document.getElementsByClassName('notificationContainer')[0].innerHTML += `
` + message + `
X
` }//notify('MessageGoesHere', '#aaffaadd') function artistNameUpdated(artistName) { document.getElementById('inputInfoArtist').value = artistName document.getElementById('inputInfoArtist2').value = artistName bottomInfoUpdated() } //svg cropper function cropSVG(set, targetImage) { xhttp = new XMLHttpRequest() xhttp.open('GET', 'https://raw.githubusercontent.com/andrewgioia/keyrune/4073ac89bb943978c29be504275e6f3160a07255/svg/' + set + '.svg', true) xhttp.overrideMimeType('image/svg+xml') xhttp.onload = function(event) { if (this.readyState == 4 && this.status == 200) { var svg = document.body.appendChild(xhttp.responseXML.documentElement) var box = svg.getBBox(svg) svg.setAttribute('viewBox', [box.x, box.y, box.width, box.height].join(' ')) svg.setAttribute('width', box.width) svg.setAttribute('height', box.height) targetImage.src = 'data:image/svg+xml,'+encodeURIComponent(svg.outerHTML) svg.remove() } } xhttp.send() } //Must run last: initialize() //Redundant function loadScript(scriptPath){ var script = document.createElement('script') script.setAttribute('type','text/javascript') script.setAttribute('src', scriptPath) if (typeof script != 'undefined') { document.getElementsByTagName('head')[0].appendChild(script) } }