Custom swipe between non-sequential slides

H!!
I have a custom script that grants me swipe control over slides by setting which slide can swipe forward/backward. here the code:

<script src="index.hyperesources/js/zepto.js"></script>
<script src="index.hyperesources/js/event.js"></script> 
<script src="index.hyperesources/js/touch.js"></script>
	
<script>

		var arrLeftRight = ['3','4','5','8','9','10','11','14','15','16']; //moves to slide both forward/bacward
		var arrLeft = ['1','2','7','13']; //moves slide only forward
		var arrRight = ['6','12','17']; //moves slide only backward
		
		function leftEnabled(idToCkeck){
			if($.inArray(idToCkeck, arrLeftRight) > -1){
				return true;
			}else	if($.inArray(idToCkeck, arrLeft) > -1){
				return true;
			}else{
				return false;
			}
			
		}
		function rightEnabled(idToCkeck){
			if($.inArray(idToCkeck, arrLeftRight) > -1){
				return true;
			}else	if($.inArray(idToCkeck, arrRight) > -1){
				return true;
			}else{
				return false;
			}
		}
        
// make sure the browser does not do any scrolling (avoids iOS6 timer bug)
		document.ontouchmove = function(event) {
		event.preventDefault();
		}
		
		function documentLoaded(hypeDocument, element, event) {
			var mainContainerID = element.id;
		
			// when swiping right show the previous scene
			$('#' + mainContainerID).swipeRight(function() {
				if (rightEnabled(hypeDocument.currentSceneName()) ) {
					hypeDocument.showPreviousScene(hypeDocument.kSceneTransitionPushLeftToRight);
				}
			});
			
			// when swiping left show the next scene
			$('#' + mainContainerID).swipeLeft(function() {
				if (leftEnabled(hypeDocument.currentSceneName()) ) {
					hypeDocument.showNextScene(hypeDocument.kSceneTransitionPushRightToLeft);
				}
			});
		}
		
		window.HYPE_eventListeners = [{"type":"HypeDocumentLoad", "callback":documentLoaded}];	
    

</script>

what I want to add to this code is the possibility to jump, at swipe on a specific slide, to another non-sequential. for example, I'm on slide 3 and I want to go back to slide 1 by swiping left. the code would be something like this:

if is slide 3, on swipe left, goto slide 1 (or maybe with the COUNT function: -2)

it is possibile somehow?

thank's in advance,
m

The answer is yes, but I am a little uncertain of the exact behavior that you're looking for.

In general, the missing pieces you need are a function that returns a new scene name given a current scene name and a swipe direction (or two separate functions for the direction, if you so chose). The result of this could then go into the hypeDocument.showSceneNamed() API.

What I wasn't clear was if you wanted:

  • a singular array that lets you go forward and backward
  • jumping to the next closest... let's say you're on '4' and the array has ['1', '2', '6'] and swipe back, this would find that '2' is the closest item, even though '4' isn't in the array at all.
  • or something like jumping to the last scene the user was at and keeping a memory of the full history that they visited

thank you for your answer! what I need is a script that grants me the control over all the slides, in addition to the forward/backward variable that I already provided.

to be more clear, an IF statement where I can say: if the active slide is number 4, there when I slide back I go to slide 2, or maybe 3, or even 1 (not history then). plus, I would need to add an IF ELSE statement, where I can say: if is slide 4 (active slide) and I swipe forward, go to slide 7. something that I add case by case at my purpose.

hope to was more clear now, unfortunately my english is not so good :frowning:

my work consist of a unique html that have 3 different flows of slides in the first part, but at the end all these paths merge at one specific slide, so I need to swipe back in a slide and skip many slide to jump at a slide far back. but not the history method is what I'm searching for (I prefer to have a script that give me total control over slides). attached the flow as example

really thank you for your time!
m

You can always just park hypeDocument functions in an underscored alias and overwrite them and forward the commands as needed.

What I’m saying is just use hypeDocument.showNextScene with your own logic, and invoke it on the swipe.

1 Like

Thanks for the additional info. You may want to look at the programming concept called State Machines. But for your graph, it appears that every scene only has a single next/prev value that is known ahead of time? If this is the case, then you could probably just keep a listing of it. I'd code it up as something like:

var navInfoByScene = {};
navInfoByScene["1"] = { "next" : "3", "prev" : "" };
navInfoByScene["2"] = { "next" : "3", "prev" : "" };
navInfoByScene["3"] = { "next" : "7", "prev" : "2" };
navInfoByScene["4"] = { "next" : "5", "prev" : "2" };
navInfoByScene["5"] = { "next" : "13", "prev" : "4" };
navInfoByScene["6"] = { "next" : "7", "prev" : "2" };
navInfoByScene["7"] = { "next" : "6", "prev" : "8" };
// ... complete with all scenes

function jumpToNextScene() {
	jumpToSceneWithDirection("next");
}

function jumpToPrevScene() {
	jumpToSceneWithDirection("prev");
}

function jumpToSceneWithDirection(direction) {
	var currentSceneName = hypeDocument.currentSceneName();
	var navInfo = navInfoByScene[currentSceneName];
	if(navInfo != null) {
		var sceneName = navInfo[direction];
		if(sceneName != null && sceneName != "") {
			hypeDocument.showSceneNamed(sceneName);
		}
	}
}

(of course all scene names must be named as these numbers)

1 Like

The solution from @jonathan is what I ment. I think that should work really good.

BTW I was looking at Xstate last year. I used it in a project (not Hype). Would be cool to integrate it with Hype , though.

1 Like

HI! thank you for your code! seems perfect! one thing: i've tried it, but it doesn't do anything if I swipe left/right. I think that I miss something.....

here my complete index.html file content:

<!DOCTYPE html>
<html>
  <head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
	<meta http-equiv="X-UA-Compatible" content="chrome=1,IE=edge" />
	<title>index</title>
	<style>
		html {
			height:100%;
		}
		body {
			background-color:#FFF;
			margin:0;
			height:100%;
		}
        #scalecontainer{
            -moz-transform-origin: left top;
            -webkit-transform-origin: left top;
            -ms-transform-origin: left top;
            -o-transform-origin: left top;
            transform-origin: left top;
            width: 1024px;
            margin: 0 auto;
          }
	</style>
	<!-- copy these lines to your document head: -->

	<meta name="viewport" content="user-scalable=yes, initial-scale=1.0, width=device-width" />
	<script src="index.hyperesources/js/zepto.js"></script>
	<script src="index.hyperesources/js/event.js"></script> 
	<script src="index.hyperesources/js/touch.js"></script>
	
	<script>

		var navInfoByScene = {};
		navInfoByScene["1"] = { "next" : "2", "prev" : "" };
		navInfoByScene["2"] = { "next" : "", "prev" : "1" };
		navInfoByScene["3"] = { "next" : "4", "prev" : "2" };
		navInfoByScene["4"] = { "next" : "5", "prev" : "3" };
		navInfoByScene["5"] = { "next" : "6", "prev" : "4" };
		navInfoByScene["6"] = { "next" : "7", "prev" : "5" };
		navInfoByScene["7"] = { "next" : "8", "prev" : "6" };
		navInfoByScene["8"] = { "next" : "", "prev" : "7" };
		navInfoByScene["9"] = { "next" : "10", "prev" : "2" };
		navInfoByScene["10"] = { "next" : "11", "prev" : "9" };
		navInfoByScene["11"] = { "next" : "12", "prev" : "10" };
		navInfoByScene["12"] = { "next" : "13", "prev" : "11" };
		navInfoByScene["13"] = { "next" : "", "prev" : "12" };
		navInfoByScene["14"] = { "next" : "15", "prev" : "2" };
		navInfoByScene["15"] = { "next" : "16", "prev" : "14" };
		navInfoByScene["16"] = { "next" : "17", "prev" : "15" };
		navInfoByScene["17"] = { "next" : "18", "prev" : "16" };
		navInfoByScene["18"] = { "next" : "", "prev" : "17" };
		navInfoByScene["19"] = { "next" : "20", "prev" : "1" };
		navInfoByScene["20"] = { "next" : "21", "prev" : "19" };
		navInfoByScene["21"] = { "next" : "22", "prev" : "19" };
		navInfoByScene["22"] = { "next" : "23", "prev" : "21" };
		navInfoByScene["23"] = { "next" : "", "prev" : "22" };
		navInfoByScene["24"] = { "next" : "25", "prev" : "1" };
		navInfoByScene["25"] = { "next" : "26", "prev" : "24" };
		navInfoByScene["26"] = { "next" : "27", "prev" : "25" };
		navInfoByScene["27"] = { "next" : "28", "prev" : "26" };
		navInfoByScene["28"] = { "next" : "29", "prev" : "27" };
		navInfoByScene["29"] = { "next" : "", "prev" : "28" };
		// ... complete with all scenes
		
		function jumpToNextScene() {
			jumpToSceneWithDirection("next");
		}
		
		function jumpToPrevScene() {
			jumpToSceneWithDirection("prev");
		}
		
		function jumpToSceneWithDirection(direction) {
			var currentSceneName = hypeDocument.currentSceneName();
			var navInfo = navInfoByScene[currentSceneName];
			if(navInfo != null) {
				var sceneName = navInfo[direction];
				if(sceneName != null && sceneName != "") {
					hypeDocument.showSceneNamed(sceneName);
				}
			}
		}

</script>

	<!-- end copy -->
  </head>
  <body>
	<!-- copy these lines to your document: -->
<div id="scalecontainer">
	<div id="index_hype_container" class="HYPE_document" style="margin:auto;position:relative;width:1024px;height:768px;overflow:hidden;">
		<script type="text/javascript" charset="utf-8" src="index.hyperesources/index_hype_generated_script.js?48064"></script>
	</div>
</div>
      
    <script type="text/javascript">
	
		// make sure the browser does not do any scrolling (avoids iOS6 timer bug)
		document.ontouchmove = function(event) {
		event.preventDefault();
		}
		
		function documentLoaded(hypeDocument, element, event) {
			var mainContainerID = element.id;
		
			// when swiping right show the previous scene
			$('#' + mainContainerID).swipeRight(function() {
				if (jumpToPrevScene(hypeDocument.currentSceneName()) ) {
					hypeDocument.showPreviousScene(hypeDocument.kSceneTransitionPushLeftToRight);
				}
			});
			
			// when swiping left show the next scene
			$('#' + mainContainerID).swipeLeft(function() {
				if (jumpToNextScene(hypeDocument.currentSceneName()) ) {
					hypeDocument.showNextScene(hypeDocument.kSceneTransitionPushRightToLeft);
				}
			});
		}
		
		window.HYPE_eventListeners = [{"type":"HypeDocumentLoad", "callback":documentLoaded}];
        
      </script>

       <script src="index.hyperesources/js/jquery-1.11.0.min.js"></script>
      <script type="text/javascript">
	    var $j = jQuery.noConflict();
	</script>
      <script type="text/javascript">
        var alsoenlarge = true;
        $j(function(){
          if(isScalePossible()){
            $j('body').css({overflow:'hidden'}); //geen scrollbars
            $j('#scalecontainer').css({position: 'absolute', margin: 0}); 

        // Run scale function on start
            scaleSite();
            scaleSite();  

            // run scale function on browser resize
            $j(window).resize(scaleSite);
          }
        });
        function scaleSite()
        {
          windoww = $j(window).width();
          windowh = $j(window).height();
          sitew = $j('#scalecontainer').width();
          siteh = $j('#scalecontainer').height();
          f = windoww/sitew;
          f = windowh/siteh<f?windowh/siteh:f;
          if(!alsoenlarge && f>1) f = 1;
          $j('#scalecontainer').css({
            "-moz-transform"    : "scale("+f+")",
            "-webkit-transform" : "scale("+f+")",
            "-ms-transform"     : "scale("+f+")",
            "-o-transform"      : "scale("+f+")",
            "transform"         : "scale("+f+")",
            "left"              : ((windoww-(sitew*f))/2)+"px",
            "top"               : ((windowh-(siteh*f))/2)+"px"
          });
        }
        function isScalePossible()
        {
          can = 'MozTransform' in document.body.style;
          if(!can) can = 'webkitTransform' in document.body.style;
          if(!can) can = 'msTransform' in document.body.style;
          if(!can) can = 'OTransform' in document.body.style;
          if(!can) can = 'transform' in document.body.style;
          if(!can) can = 'Transform' in document.body.style;
          return can;
        }
	</script>
      
	<!-- end copy -->
  </body>
</html>

all my slides are named as numbers.

thank's!
m

You would want to put this code in the HypeDocumentLoad documentLoaded() callback that you were using in the initial code you sent. This gives access to the hypeDocument variable, and also lets you set this up in your jquery swipeRight/swipeLeft setup calls. So that new section would instead look like:

		function documentLoaded(hypeDocument, element, event) {
			var mainContainerID = element.id;
			
			var navInfoByScene = {};
			navInfoByScene["1"] = { "next" : "2", "prev" : "" };
			navInfoByScene["2"] = { "next" : "", "prev" : "1" };
			navInfoByScene["3"] = { "next" : "4", "prev" : "2" };
			navInfoByScene["4"] = { "next" : "5", "prev" : "3" };
			navInfoByScene["5"] = { "next" : "6", "prev" : "4" };
			navInfoByScene["6"] = { "next" : "7", "prev" : "5" };
			navInfoByScene["7"] = { "next" : "8", "prev" : "6" };
			navInfoByScene["8"] = { "next" : "", "prev" : "7" };
			navInfoByScene["9"] = { "next" : "10", "prev" : "2" };
			navInfoByScene["10"] = { "next" : "11", "prev" : "9" };
			navInfoByScene["11"] = { "next" : "12", "prev" : "10" };
			navInfoByScene["12"] = { "next" : "13", "prev" : "11" };
			navInfoByScene["13"] = { "next" : "", "prev" : "12" };
			navInfoByScene["14"] = { "next" : "15", "prev" : "2" };
			navInfoByScene["15"] = { "next" : "16", "prev" : "14" };
			navInfoByScene["16"] = { "next" : "17", "prev" : "15" };
			navInfoByScene["17"] = { "next" : "18", "prev" : "16" };
			navInfoByScene["18"] = { "next" : "", "prev" : "17" };
			navInfoByScene["19"] = { "next" : "20", "prev" : "1" };
			navInfoByScene["20"] = { "next" : "21", "prev" : "19" };
			navInfoByScene["21"] = { "next" : "22", "prev" : "19" };
			navInfoByScene["22"] = { "next" : "23", "prev" : "21" };
			navInfoByScene["23"] = { "next" : "", "prev" : "22" };
			navInfoByScene["24"] = { "next" : "25", "prev" : "1" };
			navInfoByScene["25"] = { "next" : "26", "prev" : "24" };
			navInfoByScene["26"] = { "next" : "27", "prev" : "25" };
			navInfoByScene["27"] = { "next" : "28", "prev" : "26" };
			navInfoByScene["28"] = { "next" : "29", "prev" : "27" };
			navInfoByScene["29"] = { "next" : "", "prev" : "28" };
			// ... complete with all scenes

			function jumpToNextScene() {
				jumpToSceneWithDirection("next");
			}

			function jumpToPrevScene() {
				jumpToSceneWithDirection("prev");
			}

			function jumpToSceneWithDirection(direction) {
				var currentSceneName = hypeDocument.currentSceneName();
				var navInfo = navInfoByScene[currentSceneName];
				if(navInfo != null) {
					var sceneName = navInfo[direction];
					if(sceneName != null && sceneName != "") {
						hypeDocument.showSceneNamed(sceneName);
					}
				}
			}
		
			// when swiping right show the previous scene
			$('#' + mainContainerID).swipeRight(function() {
				jumpToPrevScene();
			});
			
			// when swiping left show the next scene
			$('#' + mainContainerID).swipeLeft(function() {
				jumpToNextScene();
			});
		}
		
		window.HYPE_eventListeners = [{"type":"HypeDocumentLoad", "callback":documentLoaded}];	

I haven't specifically tested this though, since I don't have your whole document setup... but hopefully that points you to where it can go!

many thank's! it works perfectly! very useful!!!
last thing if you may want to help me. I tried to add slide transition to slides when swipe left/right: hypeDocument.kSceneTransitionPushRightToLeft
and
hypeDocument.kSceneTransitionPushLeftToRight
but it doesn't works. I don't know exactly where to put it properly. could you be so kind to help me with this last thing? if not, no worries, I'll do it without it

best regards!
m

1 Like

Replace this line:

hypeDocument.showSceneNamed(sceneName);

With:

hypeDocument.showSceneNamed(sceneName, direction == "next" ? hypeDocument.kSceneTransitionPushRightToLeft : hypeDocument.kSceneTransitionPushLeftToRight, 1.1);

If you need to change the duration, change the 1.1 part.

1 Like

super!
thank you for all your support! very appreciated it!

:ok_hand:

1 Like