diff --git a/VERSION b/VERSION index cf8690732fe3ef1414b99886dc496065db8e8712..ef0f38abe163df4bd53e2514ff6bd53e74851eb9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.18.0 +2.19.0 diff --git a/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png b/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png index 9c8a007275b711d4a40c2ec5894d588b6ad99295..3dd05fcb306d8054fcccbda04ec22a850022c3e7 100644 Binary files a/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png and b/frontend/src/assets/template/back_in_full_force_tour_social_wide/background.png differ diff --git a/frontend/src/assets/template/make_a_wish_banner/background.png b/frontend/src/assets/template/make_a_wish_banner/background.png index 5f95bacfb639fa51c190385aadbdf40afd3e77db..63318e77b58f1f61d99a00b165ce28c1a2e11c9a 100644 Binary files a/frontend/src/assets/template/make_a_wish_banner/background.png and b/frontend/src/assets/template/make_a_wish_banner/background.png differ diff --git a/frontend/src/assets/template/make_a_wish_banner/background_inverted.png b/frontend/src/assets/template/make_a_wish_banner/background_inverted.png index cfc2af3d4e9169892a32a63e2dc02fe69b8478ff..8dabc3e3ecad9e4c264951d8b32f993265574fbb 100644 Binary files a/frontend/src/assets/template/make_a_wish_banner/background_inverted.png and b/frontend/src/assets/template/make_a_wish_banner/background_inverted.png differ diff --git a/frontend/src/assets/template/make_a_wish_banner/line.png b/frontend/src/assets/template/make_a_wish_banner/line.png new file mode 100644 index 0000000000000000000000000000000000000000..bad1684b374622e34daa3eae2d630401bc20c6e0 Binary files /dev/null and b/frontend/src/assets/template/make_a_wish_banner/line.png differ diff --git a/frontend/src/components/canvas/utils.js b/frontend/src/components/canvas/utils.js index 97fb8edc76cb81866ed1d461c9c56b8e382377a4..c06b758c9983e0ca56817c85ce232ff4ad868a16 100644 --- a/frontend/src/components/canvas/utils.js +++ b/frontend/src/components/canvas/utils.js @@ -17,6 +17,92 @@ const clearObjects = (clearableItems, canvas) => { } }; +const getSingleLineTextBoxWidth = (text, fontSize, fontFamily) => { + text = text.replace(/[^\S\r\n]+/g, " "); + text = text.replace(/\r\n/g, "\n"); + + let positionWithinString = -1; + + const splitWords = text.split(" "); + let wordIndexes = {}; + const spaceText = new fabric.Text(" ", { + fontFamily: fontFamily, + fontSize: fontSize, + }); + + // I stole this from another function and this breaks its line width checking system + // so that I don't have to modify the way it works because i remember none of this + // hacky browser font shit anymore. + const maxWidth = 999999999999999; + let currentWidth = 0; + + for (let wordPosition = 0; wordPosition < splitWords.length; wordPosition++) { + let currentWord = splitWords[wordPosition]; + let skipNewLineGeneration = false; + + if (currentWord.includes("\n")) { + skipNewLineGeneration = true; + + const breakSplitWord = currentWord.split("\n"); + + const firstLineWord = breakSplitWord[0]; + const secondLineWord = breakSplitWord[1]; + + // Word + \n + positionWithinString += firstLineWord.length + 1; + + currentWord = secondLineWord; + } + + const wordIsLast = wordPosition === splitWords.length - 1; + + positionWithinString += currentWord.length + (!wordIsLast ? 1 : 0); + + const wordText = new fabric.Text(currentWord, { + fontFamily: fontFamily, + fontSize: fontSize, + }); + + // This is really ugly, I have no idea why Chromium thinks the text is shorter than it really is. + // (Or why Firefox thinks it's longer.) + // But, it works. + currentWidth += wordText.width * (Boolean(window.chrome) ? 1.183 : 1); + + if (!skipNewLineGeneration && currentWidth > maxWidth) { + if ( + ["a", "i", "o", "u", "s", "se", "v", "z"].includes( + splitWords[ + wordPosition !== 0 ? wordPosition - 1 : wordPosition + ].replace("*", ""), + ) + ) { + // Previous word is not a, i, o, u, s, ... + const lineBreakPosition = + positionWithinString - + (!wordIsLast ? 1 : 0) - + currentWord.length - + 1 - + splitWords[wordPosition !== 0 ? wordPosition - 1 : wordPosition] + .length; + + text = setCharAt(text, lineBreakPosition, "\n"); + } else { + text = setCharAt( + text, + positionWithinString - (!wordIsLast ? 1 : 0) - currentWord.length, + "\n", + ); + } + + currentWidth = wordText.width; + } else if (!wordIsLast) { + currentWidth += spaceText.width; + } + } + + return currentWidth; +} + const sortObjects = (canvas) => { canvas._objects.sort((a, b) => (a.zIndex > b.zIndex ? 1 : -1)); canvas.renderAll(); @@ -284,5 +370,6 @@ export { sortObjects, transformHighlightedText, transformTextLineBreaks, + getSingleLineTextBoxWidth, checkTextBoxHeight, }; diff --git a/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js b/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js index db7fd5781df8bc9ad3c7c49c033bdf23ae13e0e5..f9aa91b6079e3b66a4dbc7ed0fb6727a3cea85b7 100644 --- a/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js +++ b/frontend/src/views/back_in_full_force_tour_social_wide/canvas.js @@ -61,26 +61,26 @@ const redraw = async (canvas, options) => { canvas.preserveObjectStacking = true; const textMarginLeft = Math.ceil(canvas.width * 0.1); - const textMarginRight = Math.ceil(canvas.width * 0.078); + const textMarginRight = Math.ceil(canvas.width * 0.04); - let mainTextMarginBottom = Math.ceil(canvas.height * 0.3) + Math.ceil(canvas.height * 0.13); - const dateTextMarginBottom = Math.ceil(canvas.height * 0.605) + Math.ceil(canvas.height * 0.305); - const timeTextBoxMarginBottom = Math.ceil(canvas.height * 0.535) + Math.ceil(canvas.height * 0.312); - const locationTextBoxMarginBottom = Math.ceil(canvas.height * 0.27) + Math.ceil(canvas.height * 0.12); - const attendeesTextBoxMarginBottom = Math.ceil(canvas.height * 0.09) + Math.ceil(canvas.height * 0.065); + let mainTextMarginBottom = Math.ceil(canvas.height * 0.47) + Math.ceil(canvas.height * 0.02); + const dateTextMarginBottom = Math.ceil(canvas.height * 0.8) + Math.ceil(canvas.height * 0.069); + const timeTextBoxMarginBottom = Math.ceil(canvas.height * 0.715) + Math.ceil(canvas.height * 0.075); + const locationTextBoxMarginBottom = Math.ceil(canvas.height * 0.43) + Math.ceil(canvas.height * 0.02); + const attendeesTextBoxMarginBottom = Math.ceil(canvas.height * 0.11) + Math.ceil(canvas.height * 0.12); - const mainTextSize = Math.ceil(canvas.height * 0.175); + const mainTextSize = Math.ceil(canvas.height * 0.210); const mainTextLineHeight = 1; - const dateTextSize = Math.ceil(canvas.height * 0.046); - const timeTextSize = Math.ceil(canvas.height * 0.04); - const attendeesTextSize = Math.ceil(canvas.height * 0.027); + const dateTextSize = Math.ceil(canvas.height * 0.062); + const timeTextSize = Math.ceil(canvas.height * 0.062); + const attendeesTextSize = Math.ceil(canvas.height * 0.035); const attendeesTextLineHeight = 1; - const locationTextSize = Math.ceil(canvas.height * 0.044); + const locationTextSize = Math.ceil(canvas.height * 0.055); const locationTextLineHeight = 1; - const contractedByTextSize = Math.ceil(canvas.height * 0.015); + const contractedByTextSize = Math.ceil(canvas.height * 0.02); const contractedByTextMaxWidth = Math.ceil(canvas.width * 0.9); const contractedByTextSidesMargin = Math.ceil(canvas.width * 0.03); diff --git a/frontend/src/views/make_a_wish_banner/canvas.js b/frontend/src/views/make_a_wish_banner/canvas.js index 620de28ed5d1195bcd51262d4e082281134c5698..883243c9b90d7af4edb14ee609c2f6677ee93104 100644 --- a/frontend/src/views/make_a_wish_banner/canvas.js +++ b/frontend/src/views/make_a_wish_banner/canvas.js @@ -4,10 +4,14 @@ import { sortObjects, transformHighlightedText, checkTextBoxHeight, + getSingleLineTextBoxWidth, } from "../../components/canvas/utils"; import { PaddedHighlightingTextbox } from "../../components/canvas/textbox"; import backgroundURL from "../../assets/template/make_a_wish_banner/background.png"; import backgroundURLInverted from "../../assets/template/make_a_wish_banner/background_inverted.png"; + +import lineURL from "../../assets/template/make_a_wish_banner/line.png"; + import COLORS from "../../colors"; let mainTextBox = null; @@ -16,6 +20,7 @@ let personNameText = null; let personPositionText = null; let mainImage = null; +let lineImage = null; let backgroundImage = null; let previousBackgroundImageColor = null; @@ -26,6 +31,7 @@ let mainImageSource = null; const redraw = async (canvas, options) => { clearObjects( [ + lineImage, mainTextBox, personNameText, personPositionText, @@ -34,6 +40,8 @@ const redraw = async (canvas, options) => { canvas, ); + lineImage = null; + canvas.preserveObjectStacking = true; const textMarginLeft = Math.ceil(canvas.width * 0.24); @@ -43,7 +51,7 @@ const redraw = async (canvas, options) => { const mainTextBackgroundMarginTop = Math.ceil(canvas.height * 0.14); const mainTextSize = Math.ceil(canvas.height * 0.07); const mainTextHeightLimit = Math.ceil(mainTextSize * 3.3); - const mainTextLineHeight = 1; + const mainTextLineHeight = 0.85; const bottomTextSize = Math.ceil(canvas.height * 0.035); const positionTextSize = Math.ceil(canvas.height * 0.025); @@ -112,7 +120,7 @@ const redraw = async (canvas, options) => { personNameText = new fabric.Textbox(options.personName, { left: nameTextMarginLeft, top: canvas.height - bottomTextSize - nameTextMarginBottom, - width: nameTextMaxWidth, + width: canvas.width, fontFamily: "Bebas Neue", fontSize: bottomTextSize, styles: styles, @@ -127,7 +135,7 @@ const redraw = async (canvas, options) => { personPositionText = new fabric.Textbox(options.personPosition, { left: positionTextSideGap, top: canvas.height - bottomTextSize - positionTextMarginBottom, - width: positionTextMaxWidth, + width: canvas.width, fontFamily: "Roboto Condensed", fontSize: positionTextSize, fill: options.colors.baseText.value, @@ -160,6 +168,14 @@ const redraw = async (canvas, options) => { /* BEGIN Main text render */ const mainTextWidth = canvas.width - textMarginLeft - textMarginRight; + let mainTextLeft = textMarginLeft; + + if (personNameText !== null) { + mainTextLeft = Math.max( + personNameText.left + getSingleLineTextBoxWidth(options.personName, bottomTextSize, "Roboto Condensed") + 150, + mainTextLeft + ); + } const highlightedData = transformHighlightedText( options.mainText, @@ -173,7 +189,7 @@ const redraw = async (canvas, options) => { mainTextBox = new PaddedHighlightingTextbox(highlightedData.text, { width: canvas.width, - left: textMarginLeft, + left: mainTextLeft, textAlign: "left", fontFamily: "Bebas Neue", fontSize: mainTextSize, @@ -185,18 +201,50 @@ const redraw = async (canvas, options) => { zIndex: 20, }); - checkTextBoxHeight(mainTextBox, 1); + checkTextBoxHeight(mainTextBox, 2); canvas.add(mainTextBox); const mainTextBoxTop = - canvas.height - mainTextBox.height - mainTextMarginBottom; + canvas.height - mainTextBox.height - mainTextMarginBottom + (mainTextSize * (mainTextBox._textLines.length - 1) * 0.5 * mainTextLineHeight); mainTextBox.top = mainTextBoxTop - highlightedData.paddingBottom; canvas.renderAll(); /* END Main text render */ + + /* BEGIN Line render */ + + if (lineImage === null || options.colors.background.value != previousBackgroundImageColor.value) { + lineImage = new Image(); + + await new Promise((resolve) => { + lineImage.onload = () => { + resolve(); + }; + + if (options.colors.background.value == COLORS.black.value) { + lineImage.src = lineURL; + } else { + lineImage.src = lineURLInverted; + } + }); + + lineImage = new fabric.Image(lineImage, { + top: 1690, + left: mainTextBox.left - 40, + zIndex: 10, + selectable: false, + }); + lineImage.scaleToHeight(mainTextLineHeight * mainTextSize * 2); + + console.log(lineImage); + + canvas.add(lineImage); + } + + /* END Line render */ } /* BEGIN Contracted by render */