Jump to content
Search Community

jgray

Members
  • Posts

    3
  • Joined

  • Last visited

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

jgray's Achievements

1

Reputation

  1. Thank you for addressing it so quickly, that's looking great! I'm already talking with my client to sign them up, all the more reason now. Thanks again!
  2. Hello, I am experiencing this issue as well with trying to use vector-effect="non-scaling-stroke" in combination with the DrawSVG plugin on a circle element and causing crazy behavior. I've created a codepen that links to the DrawSVGPlugin referenced above highlighting the two outcomes with/without the non-scaling-stroke attribute. Is this the same issue or something else? https://codepen.io/ventinus/pen/mjBbaO
  3. I know I'm coming to this post way late but I ran into the same issue where I was losing a class name I had wrapped part of the text I was then splitting into lines. I'm not sure if this is something that has since been supported and I'm also a noob at GSAP as I've only been using it for the past week. But, for any future visitors perhaps wondering if there's a workaround, I've devised a solution that grabs the text within elements of a specified class to then wrap that same text with spans with that same class. The only caveat (that I know of) is if a block of text (single word/character or more with the special class) occurs more than once in the entire split line text block, it will be applied to the first match. consider the following markup: <p class="target">this is some <span class="special">special</span> text.</p> would merit the following js: const target = document.querySelector('.target') // target needs to be cloned because splitText mutates the passed element as well as any references const original = target.cloneNode(true) const splitTarget = new SplitText(target, {type: 'lines'}) const preservedSplitTarget = preserveClass(splitTarget, original, '.special') // function to preserve a class on text split by lines. // ideally imported from a helper file function preserveClass(splitText, original, className) { const texts = Array.from(original.querySelectorAll(className)).map(val => val.innerText.split(' ')) // Check if any of the original element contains any children with the className if (texts.length === 0) return splitText // regex to match a text preceded by the beginning of the string or a space and has a space or non-word character or end of string after. const genWordRegex = word => new RegExp(`(?:^|\\s)${word}(?=\\s|\\W|$)`) // helper for quick splitting text on spaces and filtering out empty strings const splitInnerHTML = innerHTML => innerHTML.split(' ').filter(s => s.length > 0) const {lines} = splitText // template helper for wrapping text with spans using the className argument const spanTemplate = content => `<span class="${className.replace(/\./, '')}">${content}</span>` // tracks which occurrence of the class your tracking (the first level of the multidimensional array) let blockIndex = 0 // the current block of text to wrap let textToPreserve = texts[blockIndex] // tracks which word in the block to look for let textIndex = 0 // recursively checks the target text against the textArray (textToPreserve) and wraps matching text in target const recursiveSwap = (target, textArray) => { const textPiece = textArray[textIndex] const RE = genWordRegex(textPiece) // ensure that textPiece lives in the target before proceeding if (!RE.test(target)) return target const newTarget = target.replace(RE, first => { // since javascript doesnt support regex lookbehinds (yet), leading spaces are returned in the match so we want to preserve that const start = first.charAt(0) === ' ' ? ' ' : '' return `${start}${spanTemplate(textPiece)}` }) textIndex = textIndex + 1 // if we have reached the end of the current textBlock if (textIndex >= textArray.length) { blockIndex = blockIndex + 1 // if we have reached the end of all textBlocks if (blockIndex >= texts.length) return newTarget textToPreserve = texts[blockIndex] textIndex = 0 } return recursiveSwap(newTarget, textArray) } return { ...splitText, lines: lines.map((l, i, linesArray) => { let lineText = l.innerHTML // return the line if the next piece of text to preserve doesn't match if (!genWordRegex(textToPreserve[textIndex]).test(lineText)) return l // if we've already started replacing pieces in the current textBlock or there's only one item in the block if (textIndex > 0 || textToPreserve.length === 1) { l.innerHTML = recursiveSwap(lineText, textToPreserve) } else { let splitLine = splitInnerHTML(lineText) let currWordIndex = splitLine.indexOf(textToPreserve[textIndex]) let nextWord = textToPreserve[1] // check if there are more words in the current line if (currWordIndex < splitLine.length - 1) { // check if the next words of both the textToPreserve and line match to ensure we start replacing the correct occurrence of a common word if (nextWord === splitLine[currWordIndex + 1]) { l.innerHTML = recursiveSwap(lineText, textToPreserve) } // else we've reached the end of the current line } else { // check if there is a next line and that the next textToPreserve word matches the first word in the next line if (i < linesArray.length - 1 && nextWord === splitInnerHTML(linesArray[i + 1].innerHTML)[0]) { l.innerHTML = recursiveSwap(lineText, textToPreserve) } } } return l }) } } This is the first iteration of a workaround and certainly has room for improvement and I would love to hear any feedback/concerns regarding this approach. Hope this is of some help.
×
×
  • Create New...