Button always visible and same size even when zooming

Hello,
is there a smart way to keep a button always visible - even when you zoom in to a smaller part of the screen.

e.g. a floating button which would always be:

  • of the same size (not enlargement when zoomed in)
  • in the bottom left of your screen (in HTML5/SCORM) regardless of if you are zoomed in or not.

Tricky i guess?

Thanks in advance for any help, solution, or suggestions.
Regards,
Michael

Hi Michael,

In version 6, you can add the following script to the slide Event property to keep the button size and position unchanged when zooming:

var button = Prez.GetObject('Name_of_the_button');
button.Focus = function() {}; // to prevent scrolling button into view
button.UpdateZoomAreaEffect = function() {
  var dom = this.GetDOM(),
    scale = 1/ZoomUI.Scale,
    rect = this.ctrl.rect,
    x = rect.l * scale + ZoomUI.X,
    y = rect.t * scale + ZoomUI.Y;
  dom.css({
    left: 0,
    top: 0,
    transformOrigin: '0% 0%',
    transform: 'translate(' + x + 'px, ' + y + 'px) scale(' + scale + ', ' + scale + ')'
  });
};
button.UpdateZoomAreaEffect();

Regards

2 Likes

Hi,
This works just fine! brilliant!
thanks a lot for your help on my various requests - much appreciated.
Best regards,
Michael

Dear Toanis,
in fact this code works great when the slide is loaded from the previous slide but if I click on the slide in the navigation menu and there are zoom items on the slide the buttons are not visible until the first zoom occurs.
If there are no zoom items they are visible even when I arrive on the slide via the navigation menu.

Same goes when I use my go back 10 seconds button you help me with.
If zoom items on the slide the button disappear
If no zoom items it remains visible.

I’m not sure how clear this is?
any idea how to solve it?

thanks a lot,
regards,

Michael

Hi Michael,

I’ve just updated the script in my first answer, please try again to see if it works.

Regards

Hi,
that did the trick - thanks a lot,
Michael

Hi Toanis,
any change you could post the AP7 version of this code?
I’m trying to do it myself - but I’m struggling.
thanks a lot

Hi Michael,

This code depends on the internal implementation of the player so it’s not straightforward to convert between versions. For version 7, you can use the following code in On Load event of the slide:

var $zoomNode = $('.ap-slides', prez.container),
  zoomTransform = 'none',
  button = prez.object('Name_of_the_button'),
  $buttonNode = $(button.node);

function invertZoom() {
  if (prez.object('Name_of_the_button') != button) {
    // slide changed, should not update button anymore
    return;
  }
  // update button
  var currentZoomTransform = $zoomNode.css('transform');
  if (currentZoomTransform != zoomTransform) {
    zoomTransform = currentZoomTransform;
    var zoomMatrixData = zoomTransform.split(/\s*[(),]\s*/).slice(1, -1);
    var buttonCSS = {
      transformOrigin: '',
      transform: ''
    };
    if (zoomMatrixData.length == 6) { // matrix(a, b, c, d, tx, ty)
      var scale = 1 / zoomMatrixData[0];
      if (scale != 1) {
        var x = -zoomMatrixData[4];
        var y = -zoomMatrixData[5];
        buttonCSS.transform = 'scale(' + scale + ', ' + scale + ') translate(' + x + 'px, ' + y + 'px)';
        buttonCSS.transformOrigin = '-' + $buttonNode.css('left') + ' -' + $buttonNode.css('top');
      }
    }
    $buttonNode.css(buttonCSS);
  }
  // request update button in next animation frame
  requestAnimationFrame(invertZoom);
}

requestAnimationFrame(invertZoom);

Regards

Hello,
Thanks a lot for this code - it works fine!
But in AP6 I was able to copy it and modify it so that it works with 2 buttons (on the same slide)… I’m trying to do the same with this AP7 version but I’m struggling.
What should I change for this to work with 2 buttons?
thanks a lot,
Michael

Hi Michael,

Below is the code for multiple buttons, you just need to update the array of button names.

var $zoomNode = $('.ap-slides', prez.container),
  zoomTransform = 'none',
  buttonNames = ['Button_4', 'Button_6'],	// plz update this array
  firstButton = prez.object(buttonNames[0]),// cache to check slide change
  $buttonNodes = [];

// cache button jQuery object for faster speed
for (var i = 0; i < buttonNames.length; ++i)  
  $buttonNodes.push($(prez.object(buttonNames[i]).node));

prez.invertZoom = function(force) {
  if (prez.object(buttonNames[0]) != firstButton) {
    // slide changed, should not update buttons anymore
    return;
  }
  // update buttons
  var currentZoomTransform = $zoomNode.css('transform');
  if (currentZoomTransform != zoomTransform || force === true) {
    zoomTransform = currentZoomTransform;
    var zoomMatrixData = zoomTransform.split(/\s*[(),]\s*/).slice(1, -1);
    var scale = 1, x = 0, y = 0;
    var buttonCSS = {
      transformOrigin: '',
      transform: ''
    };
    if (zoomMatrixData.length == 6) { // matrix(a, b, c, d, tx, ty)
      scale = 1 / zoomMatrixData[0];
      if (scale != 1) {
        x = -zoomMatrixData[4];
        y = -zoomMatrixData[5];
        buttonCSS.transform = 'scale(' + scale + ', ' + scale + ') translate(' + x + 'px, ' + y + 'px)';
      }
    }
	
    for (var i = 0; i < $buttonNodes.length; ++i) {
      var $buttonNode = $buttonNodes[i];
      if (scale != 1)
        buttonCSS.transformOrigin = -parseFloat($buttonNode.css('left')) + 'px ' + -parseFloat($buttonNode.css('top')) +'px';
      $buttonNode.css(buttonCSS);
    }
  }
  // request update button in next animation frame
  requestAnimationFrame(prez.invertZoom);
};

requestAnimationFrame(prez.invertZoom);

Hi Toan Le,
Thanks a lot - works perfectly.
regards,
Michael

Hi Ton Len,
I tried to implement the code to a masterslide in a PowerPoint Version. It works but the buttons are in the back, behind the video. Is there a way to set them into the front, although they are on a masterslide and the video in the regular presentation?
Best wishes
Selina

Hi Selina,

Objects in a master slide will have lower z-order than objects in a normal slide.
You can consider using placeholders (Slide Master tab > Insert Placeholder) so that you can adjust them in the normal slide.

Regards

Hi, thank you very much!
I have a new problem, I insterted the code below and it works good, except for the button ‘Button_Clear’. It is the only one which is actually a real button and not a picture, furthermore the button clear gets small with the zoom, but after using the button (the function is to dissapear with click and come back with another click) it is on the original position and not like the others in the fitting size for the zoom.
Do you have any advise for me? I checked allready that the name of ‘Button_Clear’ fits with the name in the code.

Best wishes and thank you for your help.
Selina (I am using the newest version 8.1.1 of AP)

var $zoomNode = $(’.ap-slides’, prez.container),
zoomTransform = ‘none’,
buttonNames = [‘Button_Pause’, ‘Button_Play’, ‘Button_10Sec’, ‘Button_Backwards’, ‘Button_Clear’], // plz update this array
firstButton = prez.object(buttonNames[0]),// cache to check slide change
$buttonNodes = [];

// cache button jQuery object for faster speed
for (var i = 0; i < buttonNames.length; ++i)
$buttonNodes.push($(prez.object(buttonNames[i]).node));

function invertZoom() {
if (prez.object(buttonNames[0]) != firstButton) {
// slide changed, should not update buttons anymore
return;
}
// update buttons
var currentZoomTransform = $zoomNode.css(‘transform’);
if (currentZoomTransform != zoomTransform) {
zoomTransform = currentZoomTransform;
var zoomMatrixData = zoomTransform.split(/\s*[(),]\s*/).slice(1, -1);
var scale = 1, x = 0, y = 0;
var buttonCSS = {
transformOrigin: ‘’,
transform: ‘’
};
if (zoomMatrixData.length == 6) { // matrix(a, b, c, d, tx, ty)
scale = 1 / zoomMatrixData[0];
if (scale != 1) {
x = -zoomMatrixData[4];
y = -zoomMatrixData[5];
buttonCSS.transform = ‘scale(’ + scale + ', ’ + scale + ‘) translate(’ + x + 'px, ’ + y + ‘px)’;
}
}

for (var i = 0; i < $buttonNodes.length; ++i) {
  var $buttonNode = $buttonNodes[i];
  if (scale != 1)
    buttonCSS.transformOrigin = '-' + $buttonNode.css('left') + ' -' + $buttonNode.css('top');
  $buttonNode.css(buttonCSS);
}

}
// request update button in next animation frame
requestAnimationFrame(invertZoom);
}

requestAnimationFrame(invertZoom);

Hi Selina,

Please send your project to our support email at support@atomisystems.com so that I can check.

Regards

Hi Selina,

The issue only occurs with Button objects (which have multiple built-in states and shows after zooming) on Chromium based browsers (such as Chrome, Edge 80+).
I’ve updated the script in my answer above to fix the issue.
You also need to call the following script when showing the button:

if (prez.invertZoom)
    prez.invertZoom(true);

Regards