Extend Tumult Hype with JavaScript: hypeDocument.extensions

Hello Everybody,

given some back and forth on a good way to extend Hype and allow modularity we (@MarkHunte, @MaxZieb) are starting this little project as a board thread. One could move things to GitHub or so but that adds another layer of abstraction and this thread is about inclusion. Anyways one will have to see if this thread picks up any traction anyways.

Purpose of the Project

A modular way to extend Hype with functions that follow some simple rules.

Rules of participation

  1. Try to keep an extension agnostic to the location of the call, structure or layout of the document (if a function targets certain elements they should be parameters). If that isn't possible consider not posting your solution as a extension and rather keep it as a project specific solution on an another thread. Your welcome to discuss it in this thread.

  2. Should a extension depend on another extension require it with a written statement in the function description as @require nameOfExtension so the whole set of functions in this thread can be picked like a cherry tree to ones project needs (copy&paste).

  3. An extension should be documented using @param, @return, @require helping people to understand what a function does. Please have a look at http://usejsdoc.org/ if you need more tags (like @example etc.)

  4. Should you find a error try maintaining your extension in your original post on this thread to avoid multiple reposts. If someone finds a bug please try contacting the author with a private message before posting to this thread.

  5. Post your extentsion to this thread once you have suggested and discussed them in the Extension category. Please try to follow the post format used by the other functions in this thread and link back to this index.

Preparing your project for extensions

Method: Bestcase

Copy & paste this to your Document-Tab → Head HTML (see Tumult Hype Documentation) and make sure to place the extensions in the extendHype function (location indicated with an comment):

<script>

	function extendHype(hypeDocument, element, event) {
		
		/* add the extentions here */
		
		return true;
	}

	if("HYPE_eventListeners" in window === false) {
		window.HYPE_eventListeners = Array();
	}
	
	window.HYPE_eventListeners.push({"type":"HypeDocumentLoad", "callback":extendHype});
	
</script>

Extension_Method_1.hypetemplate.zip (8,6 KB)

Method: Quick and dirty

Just drop the extensions from this thread into a Hype Function and load the function on the first scene load (scene-tab) from within Hype. No need for any of the above script code (bestcase). This method has some downsides but for single use, cases with no access to the HTML (in production) and quick prototyping it should work fine.
Extension_Method_2.hypetemplate.zip (8,9 KB)

Usage of extension

Once you prepared your document just copy and paste any extensions from this thread into the wrapper or your scene load function to make them work in your project. Also make sure to check if your extension requires another extension found in the statement @require nameOfExtension and also copy&paste that one to your project.


 

 


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.sceneInfo

Returns the Scene information: scene element ,current scene number, current scene name and total scene count (Object)


### hypeDocument.currentSceneElement
Returns the current scene element (HTMLDivElement).

hypeDocument.getSceneElementByName

Returns a scene element by name (HTMLDivElement).

hypeDocument.currentSceneIndex

Returns the current scene index (Number).

hypeDocument.getSymbolInstance

Returns the current symbol instance (symbolInstance)


hypeDocument.setElementProperties

Sets multiple properties at once (with the optional possibility to animate them)


hypeDocument.setInnerHtmlByClass

Sets all the all elements of a given class to the content one provides.


hypeDocument.goToTimeIndexInTimelineNamed

Jump to timeIndex as seen in the Hype frontend.
includes: hypeDocument.timeIndexToSeconds


hypeDocument.getCurrentSceneHeight

Gets the current scene height (CSS)

hypeDocument.setCurrentSceneHeight

Sets the current scene height (CSS)


hypeDocument.cloneElement

This Extension allows you to clone elements and append them to the scene or within a Group.


hypeDocument.startCustomBehaviourTicker

Hype Pro Extension: Starts a ticker based on a time interval that broadcasts a custom behaviour.

hypeDocument.stopCustomBehaviourTicker

Hype Pro Extension: Stops an active ticker broadcasting a custom behaviour.

hypeDocument.stopAllCustomBehaviourTicker

Hype Pro Extension: Stops all active ticker broadcasting custom behaviour.


hypeDocument.loadSound

Load soundfiles from the library and plays them back.

hypeDocument.stopAllSounds

Stops all playing soundfiles that have been loaded with hypeDocument.loadSound

hypeDocument.unloadAllSoundsByName

resets all (loadSound) audio elements with a given name and removes them from the DOM

hypeDocument.unloadSound

resets (loadSound) audio element by reference and removes it from the DOM


hypeDocument.getPrivateContainer

This function creates a kind of "shadow DOM" (HTMLDivElement)


hypeDocument.TypeTextExtension

This Extension Allows you to have text Typed out


This thread is meant for posting extensions and linking them to the index :satellite:


14 Likes

I would really like this project to be pinnend :grinning:

3 Likes

↑ extension index


hypeDocument.startCustomBehaviourTicker

Hype Pro Extension: Starts a ticker based on a time interval that broadcasts a custom behaviour. You can specify the interval in seconds or pass a object containing the FPS and the extension calculates it for you. Beware these tickers live across scenes so start any given ticker once and stop him if not needed. But we make sure that no behaviour ticks twice if you repeat the command call.


/**
* hypeDocument.startCustomBehaviourTicker 1.1
* @param {String} behaviour name to fire
* @param {Number} time in seconds (can be fractional)
* @param {Object} Some optional settings like pattern
*/
hypeDocument.startCustomBehaviourTicker = function(behaviour, time, opt){
    var fnc;
    if (behaviour==null || time==null) return;
    if (!this.hasOwnProperty('_ticker')) { this._ticker={} }
    if (!this._ticker.hasOwnProperty(behaviour)) {
        var interval = (time.hasOwnProperty('FPS')) ? 1000/time.FPS : time*1000;
        opt = opt ? opt : {};
        if (opt.hasOwnProperty('pattern')) {
            opt._buf = opt.pattern.slice(0);
            if (opt.countdown==null) opt.countdown = Infinity;
            fnc=function(){
                if (opt._buf.length==0) opt._buf = opt.pattern.slice(0);
                if (opt._buf.shift()) hypeDocument.triggerCustomBehaviorNamed(behaviour);
            }
        } else {
            fnc=function(){
                hypeDocument.triggerCustomBehaviorNamed(behaviour);
            }
        }
        this._ticker[behaviour] = setInterval(fnc,interval);
        if ( !opt.omitFirst) fnc();
    }
}

Usage:
Let’s broadcast a behaviour called enterFrame at 60 FPS

hypeDocument.startCustomBehaviourTicker('enterFrame', {FPS:60});


Let’s broadcast a behaviour called redSquareToggle every second

hypeDocument.startCustomBehaviourTicker('redSquareToggle', 1);

The function supports tick pattern since version 1.1

hypeDocument.startCustomBehaviourTicker('bounceBall', 2, {pattern:[1,1,0]});

The function supports omitFirst since version 1.1 to wait one interval before start

hypeDocument.startCustomBehaviourTicker('turnClock', 1, {omitFirst:true});


startCustomBehaviourTicker.hype.zip (82,5 KB)

Updates:
1.0 initial release
1.1 code cleanup, added pattern and omitFirst options

1 Like

↑ extension index


hypeDocument.stopCustomBehaviourTicker

Hype Pro Extension: Stops an active ticker broadcasting a custom behaviour.


/**
* hypeDocument.stopCustomBehaviourTicker 1.1
* @param {String} behaviour name to stop firing
*/
hypeDocument.stopCustomBehaviourTicker = function(behaviour){
    if (this.hasOwnProperty('_ticker')) {
        if (this._ticker.hasOwnProperty(behaviour)) {
            clearInterval( this._ticker[behaviour]);
            delete this._ticker[behaviour];
        }
    }
}

Usage:

hypeDocument.stopCustomBehaviourTicker('enterFrame');

Updates:
1.0 inital release
1.1 code cleanup

1 Like

↑ extension index


hypeDocument.stopAllCustomBehaviourTicker

Hype Pro Extension: Stops all active ticker broadcasting custom behaviour.


/**
* hypeDocument.stopAllCustomBehaviourTicker
* @require stopCustomBehaviourTicker
*/
hypeDocument.stopAllCustomBehaviourTicker = function(){
    if (this.hasOwnProperty('_ticker')) {
        for (var behaviour in this._ticker) {
            this.stopCustomBehaviourTicker (behaviour);
        }
    }
}

Usage:

hypeDocument.stopAllCustomBehaviourTicker();

Updates:
1.0 initial release
1.1 code cleanup

1 Like

↑ extension index


hypeDocument.setCurrentSceneHeight

Sets the current scene height. Beware to do this it need to set the hypeDocument height as well so you should reset scene height on scene changes if you wish to the restore initial state.


/**
* hypeDocument.setCurrentSceneHeight v1.0
* @param {Number} height to set the scene element to
*/  
hypeDocument.setCurrentSceneHeight = function ( height) {
    var sceneElm = document.getElementById(this.currentSceneId());
    sceneElm.parentElement.style.height = height;
    sceneElm.style.height = height;
}

Usage:

hypeDocument.setCurrentSceneHeight( '1000px' );

setCurrentSceneHeight.hype.zip (272,0 KB)

Update: This was updated on 11. September 2020

1 Like

↑ extension index


hypeDocument.getCurrentSceneHeight

Gets the current scene height.


/**
* hypeDocument.getCurrentSceneHeight 1.0
* @return {Number} height of the scene element
* @require currentSceneElement
*/  
hypeDocument.getCurrentSceneHeight = function () {
    var cS = hypeDocument.currentSceneElement();
    return cS.style.height;
}

Usage:

var height = hypeDocument.getCurrentSceneHeight();

Requires:
hypeDocument.currentSceneElement

1 Like

↑ extension index


hypeDocument.setElementProperties

Sets multiple properties in one go (with the optional possibility to animate them)


20180412-dj7ka

/**
* setElementProperties v1.1
* @param {Element} target to be animated
* @param {Object} object with properties to be animated
* @param {Number} time in seconds for no animation (optional)
* @param {String} easing function (optional)
*/  
hypeDocument.setElementProperties = function ( target, obj, duration, ease) {
    for (var prop in obj) {
        var val = (typeof(obj[prop]) == 'string') ? this.getElementProperty(target, prop) + parseInt(obj[prop]) : parseInt(obj[prop]);
        this.setElementProperty(target, prop, val , duration, ease);
    }
}

Usage:
Given we have element in scene with the id “circle” we can animate it.

var target = hypeDocument.getElementById('someId');
hypeDocument.setElementProperties( target , {top:500, left:267, rotateZ:180}, 1, 'easeinout');

Given we have element in scene with the id “slider” we can slide it relativ to it’s position

var target = hypeDocument.getElementById('slider');
hypeDocument.setElementProperties( target , { left:"-500"}, 1, 'easeinout');

setElementProperties.hype.zip (55,7 KB)

Updates:
1.0 Initial release with multiple property animation
1.1 Added relativ motion if value is String

2 Likes

↑ extension index


hypeDocument.currentSceneIndex

Returns the current scene index (Number).


/**
* hypeDocument.currentSceneIndex 1.0
* @return {Number} gives you the current scene index
*/
hypeDocument.currentSceneIndex = function(){
    var hc = document.getElementById(hypeDocument.documentId());
    var sa = hc.getElementsByClassName("HYPE_scene");
    for (i = 0; i < sa.length; i++) {
        if (sa[i].style.display === "block") return parseInt(sa[i].getAttribute("hype_scene_index"));
    }
}

Usage:
The scene index can also be obtained through element.getAttribute(“hype_scene_index”) in an scene load function but this implementation is agnostic to it’s location and can be used in any Hype function.

var nr = hypeDocument.currentSceneIndex();
1 Like

↑ extension index


hypeDocument.currentSceneElement

Returns the current scene element (HTMLDivElement).


/**
* hypeDocument.currentSceneElement 1.1
* @return {HTMLDivElement} gives you the current scene element
*/
hypeDocument.currentSceneElement = function(){
    return document.querySelector('#'+this.documentId()+' > .HYPE_scene[style*="block"]');
}

As of Hype 4.0.2 (build 656) this new version is the way to go:

/**
* hypeDocument.currentSceneElement 1.2
* @return {HTMLDivElement} gives you the current scene element
*/
hypeDocument.currentSceneElement = function(){
    return document.getElementById(this.currentSceneId());
}

Usage:
Given one would like to share a button function across multiple scenes one could get the current scene element and search for the affected elements using a querySelector contained in the scene. This way you can reuse classes in every scene instead of having different ID’s that would have to be unique across the whole HTML page. This is just one example as I am sure there are more use cases.

var elm = hypeDocument.currentSceneElement();
var someButton = elm.querySelector('.someButton');

Update:
1.0 initial release using getElementById ( :pencil2: see edit history to recall)
1.1 updated version with only one function call

1 Like

↑ extension index


hypeDocument.loadSound

Load soundfiles from the library and plays them back.


/**
* hypeDocument.loadSound 1.0
* @param {String} soundname without extention (mp3/ogg/wav)
* @param {String} uniqueId to load the same sound multiple times (optional)
* @require getPrivateContainer 
* @return {HTMLAudioElement}
*/
hypeDocument.loadSound = function(soundname, uniqueId){
    var soundId = soundname+'_-_'+( (uniqueId===undefined)?'':uniqueId);
    if (!hypeDocument.hasOwnProperty('_sounds')) {
        hypeDocument._sounds={};
    }
    if (!hypeDocument._sounds.hasOwnProperty(soundId)) {
        var pc = hypeDocument.getPrivateContainer('sounds');
        var sndElm = document.createElement('audio');
        if (!!(sndElm.canPlayType && sndElm.canPlayType('audio/mpeg;').replace(/no/, ''))) {
            sndElm.setAttribute('src','${resourcesFolderName}/'+soundname+'.mp3');
        } else {
            sndElm.setAttribute('src','${resourcesFolderName}/'+soundname+'.ogg');
        }
        pc.appendChild(sndElm);
        hypeDocument._sounds[soundId]=sndElm;
        
    }
    return hypeDocument._sounds[soundId];
}

Usage:
Given you have a file called “soundfile.mp3” in your library this function attaches it to your document for further use. The return value is a regular HTMLAudioElement with all it’s functions. Also this functions supports a built in ogg fallback given you supply the file in the library. Wav is currently unsupported (but easy to hack).

var snd = hypeDocument.loadSound('soundfile');
snd.play();

Requires:
hypeDocument.getPrivateContainer

1 Like

↑ extension index


hypeDocument.stopAllSounds

Stops all playing soundfiles that have been loaded with hypeDocument.loadSound


/**
* hypeDocument.stopAllSounds 1.0
*/
hypeDocument.stopAllSounds = function(){
    if (!hypeDocument.hasOwnProperty('_sounds')) {
        return;
    }
    for(var id in hypeDocument._sounds) {
        var snd = hypeDocument._sounds[id];
        snd.pause();
        snd.currentTime = 0;
    }
}

Usage:
Given you have have sounds running that go attached through hypeDocument.loadSound this function will stop them and rewind them to their beginning.

hypeDocument.stopAllSounds();

1 Like

↑ extension index


##hypeDocument.getPrivateContainer
This function creates a kind of “shadow DOM” to hold the audio elements. It’s required by loadSound but also works on it’s own to assist in any other extension.


/**
* hypeDocument.getPrivateContainer 1.0
* @param {String} name for container
* @return {HTMLDivElement}
*/
hypeDocument.getPrivateContainer = function(name){
    var hypeId = hypeDocument.documentId();             
    var hypeElm = document.querySelector('#'+hypeId);
    var pcId = hypeId+'_'+name;
    var pcElm = hypeElm.querySelector('#'+pcId);
    if (pcElm === null){
        pcElm = document.createElement('div');
        pcElm.setAttribute('id', pcId);
        pcElm.style.visibility='none';
        hypeElm.appendChild(pcElm);
    }
    return pcElm;
}

Usage:
Given you need a “shadow DOM” of sorts. This will create a HTMLDivElement inside your HypeDocument and hide it. The return value is a regular HTMLDivElement and can be manipulated as regular. Used for loadSound but should come in handy for other extensions as well. The name parameter is a must to keep each generated container ID unique.

var shadowDom = getPrivateContainer('uniqueName');

1 Like

↑ extension index


hypeDocument.unloadSound

resets the audio element and removes it from the DOM given a HTMLAudioElement to kill.
You will only need this if you are concerned with garbage collection.


/**
* hypeDocument.unloadSound 1.0
* @param soundname
*/
hypeDocument.unloadSound = function(audioRef){
    if (!hypeDocument.hasOwnProperty('_sounds')) return false;
    for(var id in hypeDocument._sounds) {
        if (audioRef === hypeDocument._sounds[id]) {
            var elm = hypeDocument._sounds[id];
            elm.src=''; elm.load();
            elm.parentNode.removeChild(elm);
            delete hypeDocument._sounds[id];
        }
    }
}

Usage:
Given you have a “soundfile.mp3” in your library and loaded it using HypeDocument.loadSound this function will remove the instances by reference. You need to store the reference todo so.

var snd = hypeDocument.loadSound('soundfile');
//makes no sense but let's unload it directly again :-)
hypeDocument.unloadSound(snd);

2 Likes

↑ extension index


hypeDocument.unloadAllSoundsByName

resets all the audio element and removes them from the DOM given the library name (without mp3/ogg)
You will only need this if you are concerned with garbage collection.


/**
* hypeDocument.unloadAllSoundsByName 1.0
* @param soundname
*/
hypeDocument.unloadAllSoundsByName = function(soundname){
    if (!hypeDocument.hasOwnProperty('_sounds')) return false;
    var success = false;
    for(var id in hypeDocument._sounds) {
        if(id.indexOf(soundname+'_-_') == 0){
            var elm = hypeDocument._sounds[id];
            elm.src=''; elm.load();
            elm.parentNode.removeChild(elm);
            delete hypeDocument._sounds[id];
            success = true;
        }
   }
   return success; 
}


Usage:
Given you have a “soundfile.mp3” in your library and are using it multiple times (see loadSound for details) this function will remove all instances by name.

hypeDocument.unloadAllSoundsByName('soundfile');

1 Like

↑ extension index

hypeDocument.cloneElement

This Extension allows you to clone elements and append them to the scene or within a Group.
You will specify the Element to clone, where to append the clone, it’s ID, Class Name, Top, Left and z-Index.
The clones HYPE_element_container class name, Child Nodes ID and HYPE_element classes are removed from the clones to avoid clashes with the Hype runtime.

/**
    * cloneElement, can be single Element or Group
    * @param {element} Hype Element to  clone
     * @param {element} Hype Element to append the clone
    * @param {String} The clone's id
    * @param {String} The clone's class name
    * @param {numnber} The clone's Top placement
    * @param {numnber} The clone's Left placement
    * @param {numnber} The clone's z-index
    * @return the specified element is cloned and appended to the specified element. The clones HYPE_element_container class name, Child Nodes ID and HYPE_element classes are removed from the clones to avoid clashes with the Hype runtime.
    */	  
    	hypeDocument.cloneElement = function(elementToClone,clonTo,elementID,elementClassName,elementTop,elementLeft,elementZIndex){
    	var elementClone =   elementToClone.cloneNode(true, true);
      
    	elementClone.id = elementID ;
    	elementClone.className = elementClassName;

    	elementClone.style.top = elementTop.toString() +'px';
    	elementClone.style.left = elementLeft.toString() +'px';
    	elementClone.style.zIndex = elementZIndex.toString();  
    		  
    	clonTo.appendChild(elementClone);
    	
    	
    	var clonedChildren = elementClone.childNodes

    for (i = 0; i < clonedChildren.length; i++) { 
     
    clonedChildren[i].classList.remove("HYPE_element_container");
     
      	var thisChild = clonedChildren[i].childNodes[0];
      	thisChild.classList.remove("HYPE_element");
     	thisChild.id  = "" ;

 } 
	
	return elementClone;
    	
    	
    	}

Usage:
You may have a form that you want to dynamically add elements to it’s list.

Constructor:
hypeDocument.cloneElement(original_to_clone,append_the_clone_To, id,className,top,left,z-index)

In Use:

if (!window.start_Top) { window.start_Top = 0 }; //-- This will be the space between the new clones and we will also use this number in the new ids.
    		
    		if ( window.start_Top < 200 ){ //-- Limit to 2 new clones
    		
    		window.start_Top +=100
    			
    		var original_to_clone  = hypeDocument.getElementById('infoBoxGroup'); 
     
     		/* We use the Scene element here to append the clones but we could use any Div/Group in the scene i.e  hypeDocument.getElementById('clonToFoo'); */
     		var append_the_clone_To = hypeDocument.currentSceneElement(); //-  @REQUIERS  currentSceneElement  Extension.

     //-- clone
    hypeDocument.cloneElement(original_to_clone,append_the_clone_To,'infoBoxGroupClone'+ window.start_Top,'infoBoxGroupClone',window.start_Top,0,2000)

     
    }

In this example we want a couple of clones so we also use the top’s number as an index to limit the cloning to two and also we use it in the new ids to keep them original.

Note: This example also uses currentSceneElement Extension.


Version update 1.1

Added a return of the clone element. You will now be able to add the returned clone element to a var or send it instructions.

clone Extension_Example_v1_MH.hype.zip (27.9 KB)

3 Likes

Awesome Max

I added relativ motion to hypeDocument.setElementProperties (if value is given as string)

1 Like

↑ extension index


hypeDocument.goToTimeIndexInTimelineNamed

Jump to timeIndex as seen in the Hype frontend.


/**
* hypeDocument.goToTimeIndexInTimelineNamed 1.0
* @param {String, Object, Number} timeIndex as seen in Hype GUI
* @param {String} time line to adress
* @param {Boolean} convert overbound values
*/
hypeDocument.goToTimeIndexInTimelineNamed = function (timeIndex, timelineName, convert) {
    this.goToTimeInTimelineNamed( this.timeIndexToSeconds(timeIndex, convert), timelineName);
}

/**
* hypeDocument.timeIndexToSeconds 1.2
* @param {String, Object, Number} timeIndex in various formats
* @param {Boolean} convert overbound values 
*/
hypeDocument.timeIndexToSeconds = function (tidx, convert) {
	var min=0, sec=0, frm=0, FPS=30;
	switch (typeof(tidx)) {
		case 'object':
		 min = tidx.minutes ? tidx.minutes : 0;
		 sec = tidx.seconds ? tidx.seconds : 0;
		 frm = tidx.frames ? tidx.frames : 0;
		 FPS = tidx.FPS ? tidx.FPS : FPS;
		 break;
		case 'number':
		 sec = Math.floor(tidx);
		 frm = Math.floor((tidx-sec)*100);
		 break;	
		case 'string':
		 var temp = tidx.split(':');
		 min = temp.length > 1 ? temp[0] : 0;
		 temp = (temp.length > 1) ? temp[1] : temp[0];
		 temp = temp.split(temp.indexOf('.') > -1 ? '.' : ',');
		 sec = temp[0] ? temp[0] : 0;
		 frm = temp.length > 1 ? temp[1] : 0;
		 break;
	}
	sec = (convert) ? sec : sec %60;
	min = (convert) ? min : min %60;
	frm = (convert) ? frm : frm %FPS;
	return min*60+sec+frm/FPS;
}

Usage of hypeDocument.timeIndexToSeconds:
Let’s assume we want to jump to 3 seconds and 14 frames :wink:

// EU notation
hypeDocument.goToTimeIndexInTimelineNamed ('03,14', 'Main Timeline');
// US notation
hypeDocument.goToTimeIndexInTimelineNamed ('03.14', 'Main Timeline');

Let’s assume we want to jump to frame number 75 on test timeline (Object-Interface)

hypeDocument.goToTimeIndexInTimelineNamed ({frame:75}, 'test', true);

See possible formats for the timeIndex-String in the timeIndexToSeconds usage.

 

 

Usage of hypeDocument.timeIndexToSeconds:

// New FPS option in Object-Interface since 1.2 
// Converting 120 frames at 60 FPS (works with other examples as well)
console.log(hypeDocument.timeIndexToSeconds( {frames:120, FPS:60 } , true ));

// New object interface since 1.1
console.log(hypeDocument.timeIndexToSeconds( {minutes:1, seconds:10} ));
console.log(hypeDocument.timeIndexToSeconds( {minutes:1} ));

// with conversion 45 frame equals 1.5 seconds
console.log(hypeDocument.timeIndexToSeconds( {frames:45 } , true ));

// Number interface since 1.1 (limited to sec.frames)
console.log(hypeDocument.timeIndexToSeconds( 4.15 ));

// New String interface since 1.1 (valid tests with US dot notation)
console.log(hypeDocument.timeIndexToSeconds('01:40.15'));
console.log(hypeDocument.timeIndexToSeconds('30.00'));
console.log(hypeDocument.timeIndexToSeconds('02:43.29'));

// String interface since 1.0 (valid tests)
console.log(hypeDocument.timeIndexToSeconds('01:40,15'));
console.log(hypeDocument.timeIndexToSeconds('30,00'));
console.log(hypeDocument.timeIndexToSeconds('02:43,29'));

// wrong range tests (fixed with modulor %60, %30
console.log(hypeDocument.timeIndexToSeconds('00:61,40'));

// partial format (no minutes)
console.log(hypeDocument.timeIndexToSeconds('25,02'));

// partial format (no frame)
console.log(hypeDocument.timeIndexToSeconds('1:15'));

// partial format (only one int)
console.log(hypeDocument.timeIndexToSeconds('15'));

// conversion (45 frames)
console.log(hypeDocument.timeIndexToSeconds(',45', true));

// conversion (120 minutes)
console.log(hypeDocument.timeIndexToSeconds('120:', true));

Credits:
This extension has been initialized by @MarkHunte :sparkles:
The version bump came about through input from @DBear

Update:
1.0 inital relase from MarkHunte and MaxZieb
1.1 fixed .frames (US) and ,frames (EU) + Number/Object interface
1.2 timeIndexToSeconds now supports higher FPS (for example 60)

4 Likes