Extend Tumult Hype with JavaScript: hypeDocument.extensions

Updated hypeDocument.startCustomBehaviourTicker to version 1.1:

  • it now support patterns and omitFirst options
1 Like

↑ extension index


hypeDocument.sceneInfo

This Extension returns the scene element, scene number and scene count, scene name list
.

		
	
	
	
/* hypeDocument.sceneInfo 1.0
* @return {object} gives you the current scene, Name, number and the total count of scenes.  {sceneName: currentSceneName, sceneNumber:Number,sceneElement:Element,sceneCount: Number}

* @Returned object break down
  sceneName = The current scene's name Type: String 
 sceneNumber = The current scene's display order number Type: Number 
 sceneElement = The current Scene's Div Element  Type: Hype Element 
 sceneCount = Total count of all scenes  Type: Number 
*/

 hypeDocument.sceneInfo = function(){
 
var sceneElement;
 //-- get current scene
 var hypeContainer = document.getElementById(hypeDocument.documentId());
    var scenArray = hypeContainer.getElementsByClassName("HYPE_scene");
    for (i = 0; i < scenArray.length; i++) {
        if (scenArray[i].style.display === "block")  sceneElement = scenArray[i];
    }

 


 
  	var sceneNumber = sceneElement.getAttribute('hype_scene_index');// get the index number of the current scene name. Add 1 to make the index start from 1 instead of 0.
	var currentSceneName = hypeDocument.currentSceneName(); // get the curent scene name 
	var sceneNameArray = hypeDocument.sceneNames();  // get an array of all scene names 
	  

	return {sceneName: currentSceneName, sceneNumber: Number(sceneNumber)+1 ,sceneElement: sceneElement ,sceneCount: Number(sceneNameArray.length)}
  
  }

Returned object break down
sceneName = The current scene's name, Type: String
sceneNumber = The current scene's display order number, Type: Number
sceneElement = The current Scene's Div Element, Type: Hype Element
sceneCount = Total count of all scenes, Type: Number

Usage:

var sceneInfo = hypeDocument.sceneInfo()

You may want to set a navigation label to display scene name and numbers,

fooElement.innerHTML = sceneInfo.sceneName + " - " + sceneInfo.sceneNumber + " of " + sceneInfo.sceneCount ;

--> fooSceneName - (1 of 5)


Get the current scene element so you can target a child element that shares a class name with similar elements on other scenes.

var someButton = sceneInfo.sceneElement.querySelector('.someButton’);


Example:

ScenInfo Extension.hype.zip (31.6 KB)

Extension code ( text file )

hypeDocument.sceneInfo 1.0.txt.zip (1.2 KB)

3 Likes

↑ extension index


hypeDocument.setInnerHtmlByClass

Sets all the all elements of a given class to the content one provides. Usefull to update content across scenes and layouts all at once. Elements that want to subscribe to content updates only need to be assigned the associated class


Reasons for using class based targeting over ID based targeting:

  1. Hype has a unique approach when it comes to responsive layouts. As with scenes themselves it keeps them in own HTML braches. Meaning when you have to repeat using elements per scene or layout … ID’s demand to be unique. Therefor it would be very annoying to have to choose a different ID per scene or layout for the same content.
  2. Addressing the content nodes per Class allows them to be in plentiful locations and they are all updated at once without the need to target any element specifically.
  3. One can also use persistent symbols and unique ID’s but one often needs to tweak the design beyond proportional symbol scaling and that is where this technic really helps.

/**
* hypeDocument.setInnerHtmlByClass 1.0
* @param {String} class name to overwrite (don't include dot)
* @param {String} content or HTML used to overwrite class
*/
hypeDocument.setInnerHtmlByClass = function(cl, content) {
    var hypeDiv = document.getElementById(this.documentId());
    var hypeElm = hypeDiv.getElementsByClassName(cl);
    for(var i=0; i<hypeElm.length; i++){
            hypeElm[i].innerHTML=content;
    }
}

Usage:
Presume you have a textfield with the class userName and want to update it:

hypeDocument.setInnerHtmlByClass ('userName', 'Max');

setInnerHtmlByClass.hype.zip (127,2 KB)

4 Likes

↑ extension index


hypeDocument.getSceneElementByName

Returns a scene element by name (HTMLDivElement).


/**
* hypeDocument.getSceneElementByName 1.0
* @return {HTMLDivElement} gives you the scene element by name
*/
hypeDocument.getSceneElementByName = function(name){
    var idx = this.sceneNames().indexOf(name);
    return document.querySelector('#'+this.documentId()+' > .HYPE_scene[hype_scene_index="'+idx+'"]');
}

Usage:
Lets assume you want to extract the text contained in an textfield in another scene called intro.

var elm = hypeDocument.getSceneElementByName('intro');
var txt = elm.querySelector('#mytextbox').value;

Update:
1.0 initial release

2 Likes

↑ extension index


hypeDocument.continueTimelineNamedFromTo

This Extension allows you to play a Timeline from a given time, To a given time on a named timeline

The timeline will start from the From time and stop at the To time.



      /* hypeDocument.continueTimelineNamedFromTo 1.0
     * @description This Extension allows you to play a Timeline **from** a given time,  **To** a given  time  on a **named**  timeline
     
     The  timeline will start from the **From time** and  stop at the  **To time**.
     
      *@param  (Number/String) timelineNamed = The Timeline name to act on
      *@param  (Number/String) timeFromSeconds = The time to start from
      *@param  (Object) playOptions =  play to time in time line , Dirctional play option -  {timeToSeconds: time (Number/String), kDirection: (hypeDocument.kDirection)}
     
     */



    hypeDocument.continueTimelineNamedFromTo = function(timelineNamed,timeFromSeconds,playOptions){
        
        
        //-- set the start time
        timeFromSeconds =	 timeType(timeFromSeconds)
        
        
        //-- set the direction
        var kDirection = hypeDocument.kDirectionForward;
        var restartTimeline = false;
        if (playOptions){
        
        if (playOptions.hasOwnProperty('kDirection'))  {
            
            
            kDirection = playOptions['kDirection'];
            
            
        }
        }
        
        //-- pause, Go to start time , continue timeline
        //hypeDocument.pauseTimelineNamed(timelineNamed)
        hypeDocument.goToTimeInTimelineNamed(timeFromSeconds, timelineNamed)
        hypeDocument.continueTimelineNamed(timelineNamed, kDirection,restartTimeline)
        
        
        //-- set the end time
         if (playOptions){
        if (playOptions.hasOwnProperty('timeToSeconds'))  {
            
            var timeToSeconds =	 timeType(playOptions['timeToSeconds']);
            
            //--- compare left, right = start time end time.
            
            //-- start the end time timer.
            var timeCodeStop = setInterval(function(){
                                           var compareLeft , compareRight;
                                           
                                           
                                           
                                           //-- set up the end time timer. Check which direction we are going in. If reverse swap the start and end time around. This is so we can use a single > symbol below.
                                           
                                           kDirection === hypeDocument.kDirectionReverse ? (
                                                                                            
                                                                                            
                                                                                            
                                                                                            //-- reverse
                                                                                            compareLeft = timeToSeconds ,
                                                                                            compareRight = hypeDocument.currentTimeInTimelineNamed(timelineNamed).toFixed(3)
                                                                                            
                                                                                            
                                                                                            ) : (
                                                                                                 
                                                                                                 compareLeft = hypeDocument.currentTimeInTimelineNamed(timelineNamed).toFixed(3) ,
                                                                                                 compareRight = timeToSeconds 
                                                                                                 
                                                                                                 );
                                           
                                           
                                           if (compareLeft >  compareRight ){
                                           console.log("stop"); //this one
                                           
                                           
                                           hypeDocument.pauseTimelineNamed(timelineNamed)
                                           
                                           clearInterval(timeCodeStop);
                                           
                                           
                                           
                                           };
                                           
                                           
                                           
                                           
                                           }, 20);
            
            
        };
        
    }//--End if playOptions
    };




     		 
    //-- Time split Functions  -->	
    function timeType(timeSeconds){
        
        switch (typeof(timeSeconds)) {
                
            case 'number':
                timeSeconds  = numberSplitTime(timeSeconds)
                break;	
            case 'string':
                timeSeconds  = stringTimeSplit(timeSeconds)
                break;
        }
        
        return timeSeconds
    }



    function numberSplitTime(timeM){
        
        var secs =  timeM.toFixed(0)  ;
        var mils =  (timeM  -  secs).toFixed(2).replace(".","")  
        
        
        return   mils =  Number(secs) + ( Number(mils) * 0.033 )
        
        
    }	





    function stringTimeSplit(tidx){
        
        
        var tempNumbers = [];
        var finalNumbers = []
        
        
        var tidxArrary = tidx.split('')
        tidxArrary.push(':');
        
        for (i = 0; i < tidxArrary.length; i++) { 
            
            if (!tidxArrary[i].match(/\D/)){
                tempNumbers.push(tidxArrary[i]);
                
            }else{
                
                var tempNum = tempNumbers.join('');
                finalNumbers.push(tempNum);
                tempNumbers =[];
            }
            
            
        }
        
        var splitTime = Number(finalNumbers[0]) * 60 + Number(finalNumbers[1]) + ( finalNumbers[2] * 0.033 )
        
        return [splitTime];		
        
    }



    //<---/

You can add an optional Direction to play timeline:

hypeDocument.kDirectionForward
hypeDocument.kDirectionReverse


Time Syntax

The Time syntax is Strict but can be done in a number format seconds.frames or in a String format “min:seconds.frame

The number format is the same as the standard hype API.

Examples of time using numbers.
seconds.frames

1.34
34.10
70.14

Frame index does not exceed 29.


Examples of time using String syntax.

min:seconds.frame

‘00:34.15’
‘00:34,15’

‘01:10,14’
‘01:10.14’

‘1:10,14’
‘1:10.14’

The seconds must not be greater than 59 and the frame must not be more than 29.


Call Syntax.
hypeDocument.continueTimelineNamedFromTo(timelineName (String) , time# (Number/Sting), {timeToSeconds: time# (Number/Sting), kDirection: (hypeDocument.kDirectionForward/ Reverse API) } )


Usage

Using numbers time.

We want the time line to play from the 34 seconds and 10 frames point and stop at the 70 seconds and 14 frames point. And forward

hypeDocument.continueTimelineNamedFromTo(“fooTimeline”, 34.10, {timeToSeconds:70.14 , kDirection: hypeDocument.kDirectionForward})


Using string time.

We want the time line to play from the 70 seconds and 14 frames point and stop at the 34 seconds and 10 frames point. And in Reverse

hypeDocument.continueTimelineNamedFromTo("test", '01:10:14’ , {timeToSeconds: '00:34.10’, kDirection: hypeDocument.kDirectionReverse})


Play Options

kDirection: is Optional. The default is forward.

hypeDocument.continueTimelineNamedFromTo(“fooTimeline”, 34.10, {timeToSeconds:70.14 })

But use hypeDocument.kDirectionReverse when you are starting down the time stream and playing back up time stream to a near time. (reverse)

hypeDocument.continueTimelineNamedFromTo("foo2",'00:08:10' , {timeToSeconds: '00:2.25', kDirection: hypeDocument.kDirectionReverse})


timeToSeconds : is Optional.

You can exclude this option and just use the start from time.
The timeline will then start from the given time and continue as normal.

hypeDocument.continueTimelineNamedFromTo(“fooTimeline”, 34.10)

hypeDocument.continueTimelineNamedFromTo(“fooTimeline”, 34.10, {kDirection: hypeDocument.kDirectionReverse})

You can use either one or the other options, Both or none.


Example project.

ContinueTimelineNamedFromTo.extension v1 Example.hypetemplate.zip (43.5 KB)

v1.00


Also see example in this post


Tip

You can use the current time of a timeline using this syntax.

var currentTime = hypeDocument.currentTimeInTimelineNamed(timeline).toFixed(3)


If you do need to use the current time API make sure you chain .toFixed(3) to the end.

var currentTime = hypeDocument.currentTimeInTimelineNamed(timeline).toFixed(3);

hypeDocument.continueTimelineNamedFromTo(timeline,'00:1.00' ,  {timeToSeconds: currentTime , kDirection: hypeDocument.kDirectionReverse})
6 Likes

↑ extension index

hypeDocument.TypeTextExtension

hypeDocument.TypeTextExtension = function(obj ){ 
/*

		Markhunte 2023  version 1.3.3
	@1.3.3  -- 
	-Removed Bullet characters in the comments as they could stop some export scripts working ??.

		Markhunte 2018  version 1.3.2 
			@1.3.2  -- 
			-Fixed bug that stopped no cursor runs from completing. - misplaced } and also needed extra check on if blinker is running 
			so we do not restart it by mistake at end of run.
			-change to touchend. iOS seemed to show the keyboard and then hide. (need to investigate further)
			-set the input div (iOS) to -200px top as it was showing through the Mobile Safai semi transparent menu bar
			
			
		@1.3.1  -- 
			-Put the blinker setInteval in a function so we can stop and start it. 
			This allows us to set the speed for auto type to give a better affect.
		
			-Added vertical-align:top to the blinker span. This sets the top of the span/cursor to the top of the parant div. 
			This helps stop jumping of the text as the span will try to adust the size of the text line
			
			-Added cursorVerticalAlign:   option to the cursor options. This allow for use manual control of vertical-align of the cursor
  			
  			-Added  cursorLineHeight: option to the cursor options. this allow for use manual control of line-height of the cursor
  			
		@version 1.3.0  -- 
			removed the need for jquery, Change Cursor options mapping
		
		
		
		
 @Construtor Example
  
  hypeDocument.TypeTextExtension({
        	textElement:textElement,
        	typeType:"keydown",
            hasCursor: {
        cursor:"*" ,
        cursorFontSize:120,
        cursorLineHeight:'120%',
    	cursorColour:"pink" },
        	 typeString:"Here is some text to type out <br> And this is a second line. <br><br><br> This is a third line with 3 returns above"
            	})
	

@Construtor object break down
		**Required Properties** 
		 
	*@param  textElement : (Element) = the Hype element that will show the Typed text. This normally will be a Text Box or a Rectangle.
   	*@param   typeString : (String) = is the text that will be typed out, You can add line breaks/newlines by using the standard html tag  `<br>`
   	
**Override Automatically Typing Options**

	*@param  (String) typeType =  You can turn off Automatically Typing and set the Typing behaviour to type one character per keydown
	*@param  (Number) autoTypingSpeed  =  You can change the Automatic Typing speed to you desired speed.
												The speed is measures in thousands of a second. The number 1000= 1s,  400 = 0.4s.
												Enter the Number in in Integer form. i.e  100, 122, 400

**Optional Cursor.**
												
*@param  (true:Bool) hasCursor  = . You can add a blinking cursor. The cursor can be use with Auto typing and Keydown typing.

**Override Cursor defualt Options**

------
For Cursor options replace  hasCursor:true,

with

 hasCursor: {
        cursor:"*" ,
        cursorFontSize:120,
        cursorLineHeight:'120%',
    	cursorColour:"pink" },
-----
*@param  (String) cursor =  Change the symbol for the cursor. A Character, String, Emoji can be used.
*@param  (Int:Number) cursorFontSize = 	This is handy if the Chosen font of the Text Element means the cursor symbol is appearing small.
											Enter a number here of the equivalent pixel size you want.
											
*@param  (String) cursorLineHeight = You can adjust this with the _cursorLineHeight_ option. 
											Enter either the pixels '`100px'` or percentage  '`120%'` you want the height to drop in cursor to.
											
*@param  (String) cursorColour = 	Change the cursor colour,Enter either a a Named colour "red" or a hex colour "#EDD039". Remember to try and use web safe colours.

**extra Cursor Option**

*@param  (String) cursorVerticalAlign =  This overrides the **top** default of **vertical-align**.

There may be times when you want or need to set the vertical-align to either `"middle"` or `"bottom"`

The cursor is set in it's own `<span>`  when the cursor blinks it is doing so by using display properties.
this means it may, depending on font and size, adjust the Text Box size/padding. This appears as jumping Text.
The default of top accounts for this in most cases.
									
*/


if(typeof obj.textElement == "undefined"){throw new Error("No Element has been added constructor hypeDocument.TypeTextExtension to recieve the string");return } 
if(typeof obj.typeString == "undefined"){ throw new Error("No typeString has been added to the constructor hypeDocument.TypeTextExtension");return }
if(typeof obj.autoTypingSpeed == "undefined"){ obj.autoTypingSpeed = 200}
if(typeof obj.autoTypingSpeed != "number"){ throw new Error("The  autoTypingSpeed added to the constructor hypeDocument.TypeTextExtension, must be a number. Not " + (typeof obj.autoTypingSpeed) );return }   

 
 window.blinkerOn = false; 
if (obj.hasOwnProperty('hasCursor')){
 
 
  if ( obj.hasCursor.hasOwnProperty('cursorFontSize') == false ){
   window.cursorFontSize =  parseInt(obj.textElement.style.fontSize,10)  } else { window.cursorFontSize =  obj.hasCursor.cursorFontSize}
 if(typeof  window.cursorFontSize != "number"){ throw new Error("The cursorFontSize added to the constructor hypeDocument.TypeTextExtension, must be a number. Not " + (typeof  window.cursorFontSize) );return }   
 //
 
 if ( obj.hasCursor.hasOwnProperty('cursorColour') == false ){
   window.cursorColour = "#2F9DEC"   } else { window.cursorColour =  obj.hasCursor.cursorColour}
 //
 if (obj.hasCursor.hasOwnProperty('cursor') == false ){
   window.cursor = "|"   } else { window.cursor =  obj.hasCursor.cursor}
 //
if (obj.hasCursor.hasOwnProperty('cursorVerticalAlign') == false ){
 window.cursorVerticalAlign = "top"   } else { window.cursorVerticalAlign =  obj.hasCursor.cursorVerticalAlign} 
  //
  
 if (obj.hasCursor.hasOwnProperty('cursorLineHeight') == false ){
 
 window.cursorLineHeight = obj.textElement.style.lineHeight   } else { window.cursorLineHeight =  obj.hasCursor.cursorLineHeight}
 if(typeof  window.cursorLineHeight != "string"){ throw new Error("The cursorLineHeight added to the constructor hypeDocument.TypeTextExtension, must be a Sting. i.e \"90px\" or \"90%\". Not " + (typeof  window.cursorFontSize) );return }   
 //

  }
  
   
  
  window.blinker = ""
  window.blinkspeed = 600	
  window.textElement = obj.textElement;
  window.charS = obj.typeString
  var newDiv = document.createElement("DIV");

 
	window.autoTypingSpeed = obj.autoTypingSpeed
	   
 	//**--ADD DIV AND INPUT Field FOR iOS. This allows the typed text to show without the IOS cursor showing.
 	//-- The text that hits the input which is off scene will be mirroed in the hype scene text.
	var newDiv = document.createElement("DIV");
	newDiv.setAttribute('style', 'top: -200px; position: absolute');
	
	 newInput = document.createElement("INPUT");
    newInput.id = "Input"  
     newInput.setAttribute('style','font-size: 48px')//- This is only for iOS so we do not get zooming whe we focus.

   window.foo_label = document.createElement("Label");
 		window.foo_label.htmlFor = "Input" 
     	window.foo_label.value= "";
    	window.foo_label.className = "foo_Label"
  
 		newDiv.appendChild(newInput)
    	newDiv.appendChild(window.foo_label)
    
  		document.body.appendChild(newDiv)
  		
  //*-End iOS DIV ADD
   
  //START BLINKER
  if (obj.hasOwnProperty('hasCursor')){
  
  
  //	window.blinker  = "<span id=\"blinker\" style=\"vertical-align:middle; font-size:" +  window.cursorFontSize + "px ;color:" + window.cursorColour + "!important\">" + window.cursor + "</span>";
	
	window.blinker  = "<span id=\"blinker\" style=\"line-height:" + window.cursorLineHeight + ";vertical-align:" + window.cursorVerticalAlign +"; font-size:" +  window.cursorFontSize + "px ;color:" + window.cursorColour + "!important\">" + window.cursor + "</span>";
	window.textElement.innerHTML = window.blinker
	
	 console.log('HERE')
	//-- Start the cursor blinking
	 startBlink()
	  window.blinkerOn = true
 //
	} //---<<<<
if(typeof obj.typeType == "undefined"){ 
 
  obj.typeType ="auto"
  
  }
   var typType = obj.typeType.toLowerCase()
  
  switch(typType) {
    case "auto":
        isAutoType()
      
        break;
    case "keydown":
       isKeydownType()
        break;
    default:
       isAutoType() 
}
  
////-----
  
  //
  
  	function isKeydownType(){
  	 
  	 //-- For iOS	   
  	window.textElement.addEventListener('touchend', function(event) {
 
  
   console.log('focus')
   window.foo_label.focus()
  
  });
  
  	
	 document.addEventListener('keydown', function(event) {
     
	
	var charArray = window.charS.split('');
	 
	if (! window.indexer){window.indexer =0};  
	  
	//-- start typing

 
 	 if (window.indexer == charArray.length){
	 
	  return;
	 }
	 
     var charItem = charArray[window.indexer];
     
    
    
     if  (charItem == "<" ) {
if  (charArray[window.indexer +1] == "b" && charArray[window.indexer +2] == "r" && charArray[window.indexer +3] == ">") {
     charItem = "\<br\>";
     window.indexer = window.indexer + 3
}
     }
  
    if (window.blinker != ""){
  var blinkR = document.querySelector("#blinker") ;
 blinkR.remove() 
 }
   
	 window.textElement.innerHTML =  window.textElement.innerHTML + charItem  + window.blinker
  		window.indexer++;
    }, false);
	
 
	  

  	}
  	
  	function isAutoType(){
  	window.blinkspeed = 300
  	clearInterval(window.thisBlinkerFire);
	 if (window.blinkerOn){
	 startBlink()	
	 }
	 
	var charArray = window.charS.split('');
	
	
	var counter;
	var i=0;


//-- add characters and remove last cursor/blinker, ad new blinker after last character
 window.thisFire =   setInterval(function(){
	 
	 if (i == charArray.length){
	 clearInterval( window.thisFire);
	 clearInterval(window.thisBlinkerFire);
	 window.blinkspeed = 600
	 if (window.blinkerOn){
	 startBlink()	
	 }	
	  return;
	 }
     var charItem = charArray[i];
     
     if   (charItem == "<" )     {

if  (charArray[i +1] == "b" && charArray[i +2] == "r" && charArray[i +3] == ">") {
 
     charItem = "\<br\>";
		i = i + 3
		
		}
     }
     
     
     if (window.blinker != ""){
  var blinkR = document.querySelector("#blinker") ;
  
    blinkR.remove()
 
 }
   
    
     
	 textElement.innerHTML =  textElement.innerHTML + charItem  + blinker;

  		i++;

	 }, window.autoTypingSpeed);
  	}	
  	
  	
  	function startBlink(){
  	
  	window.thisBlinkerFire =   setInterval(function(){
	  
	
	  
    var blinker = document.getElementById("blinker");
    
    if (blinker.style.display === "none") {
        blinker.style.display = "inline";
    } else {
       blinker.style.display = "none";
    }
  
	  
	  }, window.blinkspeed);
  
  
  }
  	
  
  	//-- Remove poly fill for IE
  	(function (arr) {
  arr.forEach(function (item) {
    if (item.hasOwnProperty('remove')) {
      return;
    }
    Object.defineProperty(item, 'remove', {
      configurable: true,
      enumerable: true,
      writable: true,
      value: function remove() {
        if (this.parentNode !== null)
          this.parentNode.removeChild(this);
         //console.log( 'ieremove');
      }
    });
  });
})([Element.prototype, CharacterData.prototype, DocumentType.prototype]);
  	
  }//Main END

This Extension allows you to have a text string be typed out like it would on a type writer.

You can choose with Auto Type (The text will automatically type out ) or by keydown. (The text will type 1 character for any keydown event.

Line breaks/newlines can be added to the string using the standard <br> code.

You will be able to set a blinking cursor's, colour and symbol.

Construtor Example

      hypeDocument.TypeTextExtension({
            	textElement:textElement,
            	typeType:"keydown",
                hasCursor: {
            cursor:"*" ,
            cursorFontSize:120,
            cursorLineHeight:'120%',
        	cursorColour:"pink" },
            	 typeString:"Here is some text to type out <br> And this is a second line. <br><br><br> This is a third line with 3 returns above"
                	})

Required Properties

hypeDocument.TypeTextExtension({
	textElement: aTextElement,
	 typeString:"Here is some text to type out <br> And this is a second line. <br><br><br> This is a third line with 3 returns above"
	})

required: textElement: : Element

The textElement property is for the Hype element that will show the Typed text. This normally will be a Text Box or a Rectangle.

Simply acquire the element object as normal.

var aTextElement = document.getElementById('textBox');


textElement: aTextElement,


required: typeString : String

The typeString is the text that will be typed out.

You can add line breaks/newlines by using the standard html tag <br>
The String will take on the Font and other properties set for the textElement text box/rect



The Default Typing behaviour

The default behaviour of the typing:

• Automatically typing of the text.

  • Typing speed is one Char every 200th of a second.
    • No Cursor.

Override Automatically Typing Option

optional: typeType : String

You can turn off Automatically Typing and set the Typing behaviour to type one character per keydown
The Keydown single Char typing will also Work on iOS. The default iOS cursor will not show and the Zooming should also not zoom. Limited testing on iOS. No testing done on other Mobile devices

typeType:"keydown",

hypeDocument.TypeTextExtension({
	textElement:textElement,
	typeType:"keydown",
	 typeString:"Here is some text to type out <br> And this is a second line. <br><br><br> This is a third line with 3 returns above"
    	})

Override Automatically Typing speed Option

optional: autoTypingSpeed : Number

You can change the Automatic Typing speed to you desired speed. The speed is measured in thousands of a second. The number 1000= 1s, 400 = 0.4s.

Enter the Number in in Integer form. i.e 100, 122, 400


autoTypingSpeed: 400,

hypeDocument.TypeTextExtension({
	textElement:textElement,
    autoTypingSpeed: 400,
	 typeString:"Here is some text to type out <br> And this is a second line. <br><br><br> This is a third line with 3 returns above"
    	})


Optional Cursor.

optional: hasCursor : Bool > true

You can add a blinking cursor. The cursor can be use with Auto typing and Keydown typing.


hasCursor: true,

 hypeDocument.TypeTextExtension({
    	textElement:textElement,
    	typeType:"keydown",
        hasCursor: true,
       typeString:"Here is some text to type out <br> And this is a second line. <br><br><br> This is a third line with 3 returns above"
        	})

The Default Cursor behaviour

  • Blinking

  • Symbol = | ( a pipe)

  • Colour = #2F9DEC

  • vertical-align= Top

  • line-height = The same as the Text Box/Rect.

The cursor by default will blink, It will appear as a line similar to a normal typing cursor, It will have a default slightly blue colour, It's will normally try to align to the top of the Text. ( depending on fonts etc.) It's line height will match the Text's line height.

Override Cursor Options

You can override some default properties of the cursor.

hasCursor: {
    cursor:"*" ,
    cursorFontSize:120,
    cursorLineHeight:'120%',
	cursorColour:"pink" },

optional: cursor : String > Character ,String, Emoji etc

Change the symbol for the cursor. A Character, String, Emoji can be used.


optional: cursorFontSize : Number >Int

This is handy if the Chosen font of the Text Element means the cursor symbol is appearing small.
Enter a number here of the equivalent pixel size you want.


optional: cursorLineHeight : String

Sometimes the Size of the cursor may affect the height of the cursor in relation to the Text.
For example It may ride slightly above the text.

You can adjust this with the cursorLineHeight option. Enter either the pixels '100px' or percentage '120%' you want the height to drop in string form.


optional: cursorColour : String

This allows you to Change the colour of the Cursor Symbol. If you use an Emoji the colour will not change.

Enter either a a Named colour "red" or a hex colour "#EDD039". Remember to try and use web safe colours.


extra Cursor Option

optional: cursorVerticalAlign : String

This overrides the top default of vertical-align.

There may be times when you want or need to set the vertical-align to either "middle" or "bottom"

The cursor is set in it's own <span> when the cursor blinks it is doing so by using display properties. this means it may, depending on font and size, adjust the Text Box size/padding. This appears as jumping Text. The default of top accounts for this in most cases.

Example project.

Version: 1.3.3 (27-01-2023)
-Removed Bullet characters in the comments as they could stop some export scripts working ??.

TypeTextExtension_v133.hypetemplate.zip (20.7 KB)


Reloading scene:
The extension runs on document load.
There may be an occasion where you want to reload the scene with the typing and have the typing start from scratch.

You will need to shut down the current typing text when the scene loads, otherwise you will get multiple instances of typing text competing for space.

Simply add

clearInterval( window.thisFire);
clearInterval(window.thisBlinkerFire);

to the top of you construction function.

i.e

clearInterval( window.thisFire);
clearInterval(window.thisBlinkerFire);
 
var textElement = document.getElementById('textBox');
  
  hypeDocument.TypeTextExtension({
	textElement:textElement,
		typeType:"auto",
	autoTypingSpeed:400,
	 typeString:"Here a sentence <br>will be written ",
	 
hasCursor: {
    cursor:"|" ,
    cursorFontSize:70,
    cursorLineHeight:'130%',
	cursorColour:"white" },
	 
	})

You can use the.

clearInterval( window.thisFire);
clearInterval(window.thisBlinkerFire);

where ever you need to stop the typing.

i.e on scene unload.
Or on a button, note if the scene is still visible and the intervals are cleared, the text that has already been will remain but will not progress.


Update:

1.3.3 - 27-01-2023
•Removed Bullet characters in the comments as they could stop some export scripts working ??.

1.3.2 - 2018
•Fixed bug that stopped no cursor runs from completing. ( misplaced } ) and needed extra check on if blinker is running so we do not restart it by mistake at end of run.

•change to touchend. iOS seemed to show the keyboard and then hide. (need to investigate further)

•set the input div (iOS) to -200px top as it was showing through the Mobile Safai semi transparent menu bar

Note TypeTextExtension_v132_indent in a below post includes extra code for indents

1.3.1
•Put the blinker setInteval in a function so we can stop and start it. This allows us to set the speed for auto type to give a better affect.

•Added vertical-align:top to the blinker span. This sets the top of the span/cursor to the top of the parent div. This helps stop jumping of the text as the span will try to adjust the size of the text line

•Added cursorVerticalAlign: option to the cursor options. This allow for use manual control of vertical-align of the cursor

•Added cursorLineHeight: option to the cursor options. this allow for use manual control of line-height of the cursor

1.3.0 •removed the need for jquery, Change Cursor options mapping

3 Likes

This is just a slightly edited version that shows how to do a facsimile of an indent.

In the extension we would add code like this to Auto type.

	///<indent>
	if  (charArray[i +1] == "i" && charArray[i +2] == "n" && charArray[i +6] == "t" && charArray[i +7] == ">") {
 
     charItem = "\<span style=\"padding-left:2em\"\><\/span>";
		i = i + 7
		
		}

The Keydown type would have something similar.

The tag I use is just the made up one of <indent>

What we put in it's place is a span with padding. This seems the simplest way.

More ideas and measure can be found here.

The one thing you will have an issue with and why I used a span here is if you want to use open and closing tags.

i.e <blockquote> blalalalah </blockquote>

You will find that it will be probably hard to code. Partly because as soon as you insert the first tag the browser may automatically close it. The other issue is the type is moving by 1 char at a time and you need to keep the correct chars inside the tags as it types. Not saying it cannot be done..

But what this does show you and others is how to set up you own single tags.

TypeTextExtension_v132_indent.hypetemplate.zip (13.9 KB)

see this thread post in regards to the request for this edit

Also see this thread post for an example of creating a conversation .

Hello Mark,

Thanks for the extension. One issue that I’ve found is that when cloning an element and its subelements from one scene to another, the hype_scene_index is copied over from the originating scene index to the target scene. Could you edit your extension to address the from/to scene indices?

In lieu of a modified extension, could you tell me how to make the change to an already cloned element which happens to contain hundreds of elements?

This is how I addressed the issue:

    var sceneIndex = hypeDocument.currentSceneIndex(); // hype extension
    var sceneElement = hypeDocument.currentSceneElement();  // hype extension
    var cloneElement = sceneElement.querySelector(cloneElementID);  // the id specified in the hypeDocument.cloneElement extension (assumes the cloned element has been created)
    var matches = cloneElement.querySelectorAll("[hype_scene_index]");
    
    changeSceneIndexForClone(sceneIndex);
    
    function changeSceneIndexForClone(sceneIndex) { 
        $(cloneElement).attr("hype_scene_index", sceneIndex);  
        _.each(matches, function(element, index) { 
            $(element).attr("hype_scene_index", sceneIndex);
        });
        return;
    }
3 Likes

hypeDocument.getSymbolInstance

This function is needed if you assign click handler or use Javascript inside a symbol and want to run for example timelines of the symbol. This code is from @stephen and put into extension form by @MaxZieb.

/**
 * hypeDocument.getSymbolInstance 1.0 (by Stephen)
 * @param {HTMLDivElement} element The starting point for the search
 * @return {symbolInstance} Is either the symbolInstance or null
 */
hypeDocument.getSymbolInstance = function(element){
	var symbolInstance = null;
	var parentSymbolElement = element.parentNode;
	while (symbolInstance == null && parentSymbolElement != null) {
		symbolInstance = this.getSymbolInstanceById(parentSymbolElement.id);
		parentSymbolElement = parentSymbolElement.parentNode;
	} 
	return symbolInstance;
}

Update: Here is an upgrade version (in my opinion). It also works if the current element is already the symbol you are searching for.

/**
 * hypeDocument.getSymbolInstance 1.1 (by Stephen, modified by Max Ziebell)
 * @param {HTMLDivElement} element The starting point for the search
 * @return {symbolInstance} Is either the symbolInstance or null
 */
hypeDocument.getSymbolInstance = function(element){
	var symbolInstance = null;
	while (symbolInstance == null && element != null) {
		symbolInstance = hypeDocument.getSymbolInstanceById(element.id);
		element = element.parentNode;
	} 
	return symbolInstance;
}

Usage:

symbolInstance = hypeDocument.getSymbolInstance(element);
1 Like

The upcoming official hypeDocument.currentSceneId() will replace hypeDocument.currentSceneElement()!

Getting the element is then only a matter of writing…

var sceneElm = document.getElementById(hypeDocument.currentSceneId());

3 Likes

Here is a way to determine if an element is a persistent symbol over a regular symbol using a rather quirky oversight in the way the runtime generates class names when preparing the persistent symbols. I'd rather see this added to the regular API with a more stable approach:


Using an element

hypeDocument.isElementPersistentSymbol = function(element){
	return element && hypeDocument.getSymbolInstanceById(element.id) && element.classList.contains('HYPE_scene');
}

Using an symbolInstance

hypeDocument.isPersistentSymbol = function(symbolInstance){
	return symbolInstance && symbolInstance.element().classList.contains('HYPE_scene');
}
2 Likes

What max means ,
Although using this should not be an issue be aware that runtime class names may change in future builds. What would be good is if we got an official symbol class name to target

1 Like

3 posts were split to a new topic: Building a slider

A post was merged into an existing topic: Building a slider

hypeDocument.TypeTextExtension ->
Updated to version 1.3.3

-Removed Bullet characters in the comments as they could stop some export scripts working ??.