Adjust z-index at the end and beginning of a time line

So at the first key frame I would like the z index to change. Something like this?

function myFunction() {
var x = hypeDocument.getElementById("#3");
if (x.parentNode.style.zIndex = "20") {
x.parentNode.style.zIndex = "9999";
} else {
x.parentNode.style.zIndex = "20";
}

@lucid

If I understand You correctly… Hype Demo: LAYER Z SHUFFLE TEST JHS v1.hype.zip (15.9 KB)

Each one of your (3) functions (1 per “square”) has the same code allowing for the different element IDs:

setZindexEl = hypeDocument.getElementById('1');
setZindex = hypeDocument.getElementProperty(setZindexEl, 'z-index');
if (setZindex < 9999) {hypeDocument.setElementProperty(setZindexEl, 'z-index', 9999, 0);
	} else if (setZindex == 9999) {
   hypeDocument.setElementProperty(setZindexEl, 'z-index', 0, 0);}

Also an issue that presented itself was if one of the squares (say #3) was selected (zoom to large, z-index of “9999”) and another square (say #1) was immediately selected (zoom to large, z-index of “9999”) the two are presented in the overlapping large format.

Maybe that works with what You are trying to accomplish; but if not then it would be good to check to see if any of the other two squares have a “z-index” of “9999” and if so run their timelines backwards.

Ultimately I’m building a glorified image viewer. Where you click on an image and it grows large in the foreground covering the other image choices. Then when you click again, it shrinks back to thumbnail size.

I was trying to script the first frame of the timeline to “toggle” the z index of that element.
Because the image will cover all the others, there won’t be any overlap of elements.

So my script in theory looks to see if the index is less than 9999 the first time. If it’s not it changes.

Then when it hits that first frame script again, running the timeline backwards, it toggles the index back to less than 9999

So that is what my example does... is this not what You needed?

I personally would have a rectangle element, that sits above the image thumbs and loads a clicked image.
You then do you animations on that.

If you want the rectangle to look like it is sizing up from the image then just have the click action to move the rectangle to tha position first then size up.

This means you do not need to deal with z-index.

Simple example.

Simple example .hype.zip (29.8 KB)

2 Likes

@lucid

I've had a bit more time to look at my previous script and I tightened things up a bit...

LAYER Z SHUFFLE TEST JHS v2.hype.zip (15.9 KB)

Just one function {"changeZindex"} used by all the timelines so You do not need a unique function for each timeline. This one function approach makes for easier code management, especially as the number of your images increase.


Each thumbnail has an "On Mouse Click" handler that triggers the function "whatTarget" - which records the value of the thumbnail (element) being clicked and places it in the variable "setZindexEl":

window.setZindexEl = element;


Now just one function changes the z-index and is used by all the timelines: function "changeZindex".
This function uses the value in the "setZindexEl" variable from the "On Mouse Click" handler.

setZindex = hypeDocument.getElementProperty(setZindexEl, 'z-index');
    if (setZindex < 9999) {hypeDocument.setElementProperty(setZindexEl, 'z-index', 9999, 0);
	} else if (setZindex == 9999) {
	hypeDocument.setElementProperty(setZindexEl, 'z-index', 0, 0);} 


The next step for tightening the code - if You have a lot of images - might be to have the thumbnail animations completely controlled by JavaScript and dump the current scheme of one timeline per thumbnail ~ large image.


General idea (thought experiment): Triggered by clicking on a thumbnail or large size of a given image:

Based on the z-index of "0" for a thumbnail size...

Store the current (top, left, width, & height) values in matching variables (e.g.)
origLeft = hypeDocument.getElementProperty(setZindexEl, 'left');

then animate to the large size:
hypeDocument.setElementProperty(setZindexEl, 'left', 100, 1.0, 'easeinout');


If the z-index was "9999" (i.e. large size image) then...

animate to the thumbnail size & location using the info in the variables (e.g.)
hypeDocument.setElementProperty(setZindexEl, 'left', origLeft, 1.0, 'easeinout');

"origLeft" is the value of the original left position of the thumbnail.

Additional Note: Using "Scale (Height~Width)"_ would probably look the smoother than animating the width & height properties. I don't know - experiment!

1 Like

@lucid

Here is a Hype demo of a timeline-free “image viewer”: LAYER Z SHUFFLE TEST JHS v3.hype.zip (16.7 KB)
that uses JavaScript only to animate the “image viewer” - as I alluded to in my post above.

The advantage of dropping the timelines is it makes it easy to add images and maintain code. You do not need to set up a timeline + animation for every added image. In addition, suppose You change your mind about how the animations work? You’ll need to change all the timelines. Changing script is much quicker~efficient.

There is only one function that runs the show: “scaleImage”.


To add an image (graphic squares in the demo - as with your example):


1) Add an image at 100% to the Scene (i.e. the “full size” representation appropriate for the Scene size).
2) Scale it to a “standardized” size thumbnail using Hype’s interface (I used 40%).
3) Position the image where You want it to be in the Scene.
4) Associate a Mouse Event (e.g. “Mouse Click”) with that image and the JavaScript function “scaleImage”.

Done.

The square image centers itself in the screen as it expands to full rez. (But please see “Notes:” below).

If You are interested I will go into more detail about how this set-up works - in the interim You have an example.


Notes:
The image - as it expands - centers itself in the screen. However the current code is based on a square image (graphic). Images of course can be rectangular - and in different orientations (landscape or portrait). The script currently does not account for this.

There is a transparent element (id “clickShield”) that coves the entire Scene when a thumbnail is clicked and begins to enlarge to full size. “ClickShield” is placed just one z-index number (9998) under the image (9999) and prevents mouse-based interactivity with anything underneath the full size image.

This “clickShield” element could, instead of being transparent, fade into a deep translucent black where the underlying scene is subtly apparent… and now we are on our way to creating the classic “lightbox” effect.

4 Likes

This actually works great!!
I’ve adjusted the scale for vertical rectangles.
I didn’t see where the "clickshield actually expands, but I added a timeout function to it. If not, you can click on an image underneath as the scaling animation returns to it’s original position.
Now, I have to sort out a pause between clicks. Limit it to the time of the scaling animation, because multiple clicks will change the z- order and then corrupt the animation.
They finished project will have children poking at it all day as this will be a touch screen installation.

setZindexEl = element; // the image just that's just been clicked
setZindex = hypeDocument.getElementProperty(setZindexEl, 'z-index');
// get the clicked image's z-index

clickBlocker = hypeDocument.getElementById('clickShield');
// will be used to remove interaction with all elements on page except clicked image (z-index manipulation)

if (setZindex < 9999) { //record clicked thumbnail image's original size & position
	origLeft = hypeDocument.getElementProperty(setZindexEl, 'left');
	origTop = hypeDocument.getElementProperty(setZindexEl, 'top');
	origScaleX = hypeDocument.getElementProperty(setZindexEl, 'scaleX');
	origScaleY = hypeDocument.getElementProperty(setZindexEl, 'scaleY');
		
	// now expand the clicked thumbnail to the large image (z-index, postion, scale)
	hypeDocument.setElementProperty(setZindexEl, 'z-index', 9999);
	hypeDocument.setElementProperty(clickBlocker,'z-index', 9998);
	hypeDocument.setElementProperty(setZindexEl, 'left', 0, 1.0, 'easeinout');
	hypeDocument.setElementProperty(setZindexEl, 'top', 150, 1.0, 'easeinout');
	hypeDocument.setElementProperty(setZindexEl, 'scaleX', .7, 1.0, 'easeinout');
	hypeDocument.setElementProperty(setZindexEl, 'scaleY', .7, 1.0, 'easeinout');
	}
else if (setZindex == 9999){ //reset clicked image to original size (thumbnail) & position
	hypeDocument.setElementProperty(setZindexEl, 'left', origLeft, 1.0, 'easeinout');
	hypeDocument.setElementProperty(setZindexEl, 'top', origTop, 1.0, 'easeinout');
	hypeDocument.setElementProperty(setZindexEl, 'scaleX', origScaleX, 1.0, 'easeinout');
	hypeDocument.setElementProperty(setZindexEl, 'scaleY', origScaleY, 1.0, 'easeinout');
	
	setTimeout(function(){ // wait 1 second (i.e. 1000 milliseconds) before setting clicked image's z-index back to "0"
	hypeDocument.setElementProperty(setZindexEl, 'z-index', 5);
	}, 1000);
	
	
	setTimeout(function(){ // wait 1 second (i.e. 1000 milliseconds) before setting clickblocker image's z-index back to "0"
	hypeDocument.setElementProperty(clickBlocker, 'z-index', -1);
	}, 1500);
	
	//hypeDocument.setElementProperty(clickBlocker, 'z-index', -1); // restore clickability to all elements on page
}

@lucid
Glad this is working for You!

A few comments...
The "clickShield" does not expand - it appears instantly while the thumbnail is expanding to full size (sorry for the confusion). This prevents the corruption of the "z" order - they won't be able to activate anything else once they click the target thumbnail. Only when the thumbnail is back to normal size and the z-index is set to "0" (utilizing a timeout that matches the animation time of 1 second/1000 milliseconds) is the "clickBlocker" effect removed by setting it to a z-index of "-1" (at very bottom of code).

Pertinent section from the code with an added comment flagging the "clickShield" for purposes of this post (not in the actual code):

clickBlocker = hypeDocument.getElementById('clickShield');
	// will be used to remove interaction with all elements on page except clicked image (z-index manipulation)
	
	if (setZindex < 9999) { //record clicked thumbnail image's original size & position
		origLeft = hypeDocument.getElementProperty(setZindexEl, 'left');
		origTop = hypeDocument.getElementProperty(setZindexEl, 'top');
		origScaleX = hypeDocument.getElementProperty(setZindexEl, 'scaleX');
		origScaleY = hypeDocument.getElementProperty(setZindexEl, 'scaleY');
			
		// now expand the clicked thumbnail to the large image (z-index, postion, scale)
		hypeDocument.setElementProperty(setZindexEl, 'z-index', 9999);

// Here's the "clickShield" (i.e. the variable clickBlocker) appearing instantly
    		hypeDocument.setElementProperty(clickBlocker, 'z-index', 9998);

    		hypeDocument.setElementProperty(setZindexEl, 'left', 175, 1.0, 'easeinout');
    		hypeDocument.setElementProperty(setZindexEl, 'top', 75, 1.0, 'easeinout');
    		hypeDocument.setElementProperty(setZindexEl, 'scaleX', 1.5, 1.0, 'easeinout');
    		hypeDocument.setElementProperty(setZindexEl, 'scaleY', 1.5, 1.0, 'easeinout');
    		}

else if (setZindex == 9999){ //reset clicked image to original size (thumbnail) & position
		hypeDocument.setElementProperty(setZindexEl, 'left', origLeft, 1.0, 'easeinout');
		hypeDocument.setElementProperty(setZindexEl, 'top', origTop, 1.0, 'easeinout');
		hypeDocument.setElementProperty(setZindexEl, 'scaleX', origScaleX, 1.0, 'easeinout');
		hypeDocument.setElementProperty(setZindexEl, 'scaleY', origScaleY, 1.0, 'easeinout');
		
		setTimeout(function(){ // wait 1 second (i.e. 1000 milliseconds) before setting clicked image's z-index back to "0"
		hypeDocument.setElementProperty(setZindexEl, 'z-index', 0);
		}, 1000);
		
		hypeDocument.setElementProperty(clickBlocker, 'z-index', -1); // restore clickability to all elements on page
}

Everything works correct, except if you rapidly click the image while it’s returning to it’s normal size, you will see image drop behind the other images.
To avoid that I’m thinking of adding a click disable until the animation is done.
LAYER Z SHUFFLE TEST JHS v3a.zip (24.2 KB)

Definitely not to detract from the great work @JimScott has done here,

I just want to show better than I did above that you do not always need to mess with z-index which in my opinion can be a pain.

Here is a better example of what my basic example above was getting at…
The thumbs load using code.
Click blocking is code.
There is a rect/viewer that is above the thumbs which change size etc to show the current image.

Really lazy image Gallery v1.hypetemplate.zip (181.7 KB)

1 Like

Nice Mark - it definitely passes the “child torture test”! No matter how erratic and relentless my clicking it did not skip a beat.

What I find the most interesting is how conditioned we become as we grow up - not always a bad thing. As an adult (in theory), I would never have considered brutalizing a click routine - wasn’t in my event horizon - but kids are constantly testing their environment.

My fallback idea was to shut off the clicks entirely - no timeout (which seems to have a problem) - and I saw in your code:
viewer.style.pointerEvents = "none";

Thank You for the phrasing - and your efforts!

1 Like

@lucid

Just following through on my “non-child proof” solution above…
I definitely learned something about “click control” & using “setTimeout”.

And @MarkHunte has a solid offering to consider with a different approach.


New Demo (v3.5): LAYER Z SHUFFLE TEST JHS v3.5.hype.zip (16.8 KB)

Main difference: turning off the pointer event for the selected element (square) while it is animating:

viewer.style.pointerEvents = "none";

…along with slight adjustments in the code to accommodate this change; “setTimeout” still used.

This seems to pass my clicking torture test > z-index stays intact…
but I know I’m no match for a seven year old. :open_mouth:

1 Like

I think they are fine. They are showing alternative approaches to the real issue. The OP was using JS and only using the timeline as a trigger.

Yours still uses z-index and mine is a suggestion to achieve the goal it without using z-index

We have small individuals who love to test the limits of our installations.
With that in mind, and after some real world testing, how would you suggest getting the image to return to it’s original size? I’m thinking a time out of 10secs in the actually code, or run a second script to do that?

@lucid

I’m not clear if You were referring to me or @MarkHunte

If it was me - the last demo I posted was the best I can do - I could not break it.

If You have found otherwise then I pass this challenge on to others.