Move 2 text elements vertically when the 1st text element next to it is set to element.style.width = "auto"

Hi Guys

I'm fairly new with Hype and would like if someone could assist me to move a text element next to a text element which is set to auto grow.

When i designed the title i have a text element that grows to the left and it is set to auto, i would like to add another text element next to it, the JavaScript i need would have to allow me to adjust the x position on text number 2, so that when a operator would add in a random name it will grow to what they have typed in but then the second text would need to move next to it.

Hope that i'm making any sense.

i'm unable to add the zip file it's bigger than 3MB

Hype doesn't really have ways to automatically change positioning based on other element bounds, but this can be done.

I think my two questions to help clarify a solution would be:

  • what is feeding the value that makes it change dynamically?
  • how arbitrary might it grow?
  • do you need to use another element? (Can you just have the other text as part of the inner html)?

Hi Jonathan

Thank you for taking time to reply and try and help me resolve this.

To answer your first question, we use CasparCG to fill in the text based on Unique ID, the text is set to grow purely because i don't know what the longest text we would use, if you set the Text element to a certain px would that help solve it?

i would think the longest it would grow is 24 characters.
The Reason for the Auto grow with border padding set is to try and have it look like a strap that would change based on what we feed it from CasparCG, i couldn't find a way to have a quad at the back with text on it and found in one of the video's the guys explained that you take a text element and add in a background which works perfectly.

The reason to use another text element is as shown in screen grab that we would like to either make the text different font and size, make it stand out. also be able to move a vector if need be.

if you could share your email address i could wetransfer the project to you to see what i'm trying to do if that would help?

Can you just post here a single scene no assets working example

You're welcome to send the document you are working with to support at tumult dot com.

Based on what you said though, it sounds like you probably already have some JavaScript that sets your specific element, and you can use that as a point to shift Hype elements. There's a Element.getBoundingClientRect() function which will let you get at the actual width of elements that can be used.

You might be able to use it like:

	// get metrics for text element
	var textElementBoundingRect = textElement.getBoundingClientRect();
	var textElementWidth = textElementBoundingRect.width;
	var textElementLeft = hypeDocument.getElementProperty(textElement, 'left');
	
	// calculate where the box element should go and set it
	var boxElementPosition = textElementLeft + textElementWidth + 10; // 10 for padding
	hypeDocument.setElementProperty(boxElement, 'left', boxElementPosition);

This is using Hype elements; one interesting note of Hype is that if you never explicitly use the drag handles to set the size of a text element it is also set to auto expand based on contents. Here's my basic example document:

RandomTextMovesBox.hype.zip (20.1 KB)

There's of course different ways to deal with this, but hopefully that gets you in the right direction.

1 Like
// get metrics for text element
textElement.style.whiteSpace = 'nowrap';
hypeDocument.setElementProperty(textElement, 'width', 0);
var textElementWidth = textElement.scrollWidth;
hypeDocument.setElementProperty(textElement, 'width', textElementWidth);

... can be used if autoexpand is not active any more

2 Likes

Which will happen as explained above, If you adjust the text boxes size in the Hype project using the drag handles. Which most of us do so it fits the initial text.

As far as I can tell the scrollWidth is the same as BoundingRect width.

So if you are forcing the a single line

or not then the code may as well be.

	
	// get our elements
	var textElement = hypeDocument.getElementById("textElement");
	var boxElement = hypeDocument.getElementById("boxElement");
	
	//- force single line
	 textElement.style.whiteSpace = 'nowrap';
	// generate random text that is 2-20 characters long
	var randomTextLength = Math.floor(Math.random() * 60) + 2;
	var randomText = "";
	for(var i = 0; i < randomTextLength; i++) {
		randomText += "a";
	}
	textElement.innerHTML = randomText;
	
	// get metrics for text element
	 var textElementWidth = textElement.scrollWidth;
		var textElementLeft = hypeDocument.getElementProperty(textElement, 'left');
	
	//calculate where the box element should go and set it
	var boxElementPosition = textElementLeft + textElementWidth + 10; // 10 for padding
	hypeDocument.setElementProperty(boxElement, 'left', boxElementPosition);

Also note this can be done with MutationObserver run once on scene load.
And the text generation is done somewhere else..

	 

	// get our elements
	var textElement = hypeDocument.getElementById("textElement");
	var textElementLeft = hypeDocument.getElementProperty(textElement, 'left');
	var boxElement = hypeDocument.getElementById("boxElement");
	
	//- force single line
	 textElement.style.whiteSpace = 'nowrap';
	 
	var observer = new MutationObserver(function(mutations) {
	    
	    mutations.forEach(function(mutationRecord) {
	 
	    var textElementScrollWidth = textElement.scrollWidth;
		 
		var textElementWidth = textElementScrollWidth +10
	 	hypeDocument.setElementProperty(boxElement, 'left', textElementLeft +  textElementWidth)
	 
	        
    });    
});

var target = textElement
observer.observe(target, { attributes : true, characterData: true,
    childList: true, attributeFilter : ['style'] });
2 Likes

Hi Guys

Here is the auto_left_SizeTextWithBG

	Place TextField, and then enclose it in a group if you Animate.

	Add this function to "On Enter Viewport", in Actions. (To the textfield (f[n]))


element.style.width = "auto"
element.style.overflow = "hidden"
element.style.textOverflow = "ellipsis"
element.style.whiteSpace = "nowrap"
// Max Width maybe

When you assign this to text element it would grow based on input

Managed to finally get this project uploaded,
you'll see that the auto_left_SizeTextWithBG is assigned to a TextElement called ='RaceVenueTitle'
i need the RaceVenueNumber to moved based on what the 'RaceVenueTitle' sizes is.

title.zip (410.3 KB)

There is a simple way of doing this with no calculations etc.

Remove the RaceVenueNumber element from the project.

Remove the id from the RaceVenueTitle element

Set the InnerHtml of RaceVenueTitle element to:

<span id="RaceVenueTitle">RACE COURSE&nbsp;</span><span id="RaceVenueNumber">RACE 12</span>

In the head or a css file.

Set the style for the RaceVenueNumber span to

  <style>
   
        #RaceVenueNumber {
		pointer-events: auto;
		letter-spacing: 0px;
		word-wrap: break-word;
		font-family: Helvetica, Arial, sans-serif;
		font-size: 21px;
		word-spacing: 0px;
		font-style: normal;
		font-weight: bold;
		color: rgb(255, 255, 255);
		text-shadow: none;
		padding-left : 20px
		            
        }
    </style>

That's it.

title_mhv1.hype.zip (198.5 KB)

1 Like

Mark this is insane!!! one problem i would have is that we need the Unique ID's to fill in the data from casperCG

Would i be able to do the same concept with a vector or box element?

You are not losing any id's just moving it to a span element.

If you mean that CasperCG needs to find a Hype Element rather than s document element then you may need to explain more. But it should be simple to include a little code to achieve the innerText data

You cannot use innerHtml of a vector but you can for a rectangle element (box)

This should be very adjustable.

The Reason for the vector is the give the text element a sharp end, with Restangle Elements you can only make the box round.

Anyway to make the vector move like you have done with Span?

When I say

I mean you cannot access the innerText/Html directly via Hype UI.

You can do

document.getElementById('vector').innerText = "RACE 12"


Did not see a vector in project.

Can you post to show what you mean...


Hi Mark

I want to add in the Vector at the end like in screenshot, but this needs to move like the RaceVenueNumber

Using the internals of a vector will probably prove problematic.

I think you could get away with using a clip-path on the text element

 <style>
   
        #RaceVenueNumber {
		pointer-events: auto;
		letter-spacing: 0px;
		word-wrap: break-word;
		font-family: Helvetica, Arial, sans-serif;
		font-size: 21px;
		word-spacing: 0px;
		font-style: normal;
		font-weight: bold;
		color: rgb(255, 255, 255);
		text-shadow: none;
		padding-left : 20px
		           
        }
        
        .textElement{
       
        clip-path: polygon(0 0, 100% 0%, 90% 100%, 0% 100%);
        }
    </style>

You can put the same clip-path on any element that you give the class textElement
Clip path title.hype.zip (198.4 KB)

2 Likes

Thank you Guys appreciate the support have been struggling for months to get this solved in couple of days.

2 Likes