From 20f74a8b56102dc7e53415b2fc346c8be97d1e0c Mon Sep 17 00:00:00 2001 From: thawk Date: Sun, 30 Jan 2022 23:17:56 +0800 Subject: [PATCH] Fix relative-to-screen-size calculation (h and w) (#799) --- js/impress.js | 47 +++++++++++------- karma.conf.js | 1 + qunit_test_runner.html | 1 + src/impress.js | 41 +++++++++------- src/plugins/rel/rel.js | 3 +- .../rel/relative_to_screen_size_tests.js | 40 ++++++++++++++++ ...ive_to_screen_size_tests_presentation.html | 48 +++++++++++++++++++ 7 files changed, 148 insertions(+), 33 deletions(-) create mode 100644 test/plugins/rel/relative_to_screen_size_tests.js create mode 100644 test/plugins/rel/relative_to_screen_size_tests_presentation.html diff --git a/js/impress.js b/js/impress.js index dce97a2..637da41 100644 --- a/js/impress.js +++ b/js/impress.js @@ -179,6 +179,9 @@ transitionDuration: 1000 }; + // Configuration options + var config = null; + // It's just an empty function ... and a useless comment. var empty = function() { return false; }; @@ -230,9 +233,6 @@ // Array of step elements var steps = null; - // Configuration options - var config = null; - // Scale factor of the browser window var windowScale = null; @@ -323,9 +323,28 @@ steps.forEach( initStep ); }; + // Build configuration from root and defaults + var buildConfig = function() { + var rootData = root.dataset; + return { + width: lib.util.toNumber( rootData.width, defaults.width ), + height: lib.util.toNumber( rootData.height, defaults.height ), + maxScale: lib.util.toNumber( rootData.maxScale, defaults.maxScale ), + minScale: lib.util.toNumber( rootData.minScale, defaults.minScale ), + perspective: lib.util.toNumber( rootData.perspective, defaults.perspective ), + transitionDuration: lib.util.toNumber( + rootData.transitionDuration, defaults.transitionDuration + ) + }; + }; + // `init` API function that initializes (and runs) the presentation. var init = function() { if ( initialized ) { return; } + + // Initialize configuration object to be used by pre-init plugins. + // Some config may be changed by pre-init plugins. + config = buildConfig(); execPreInitPlugins( root ); // First we set up the viewport for mobile devices. @@ -337,18 +356,9 @@ document.head.appendChild( meta ); } - // Initialize configuration object - var rootData = root.dataset; - config = { - width: lib.util.toNumber( rootData.width, defaults.width ), - height: lib.util.toNumber( rootData.height, defaults.height ), - maxScale: lib.util.toNumber( rootData.maxScale, defaults.maxScale ), - minScale: lib.util.toNumber( rootData.minScale, defaults.minScale ), - perspective: lib.util.toNumber( rootData.perspective, defaults.perspective ), - transitionDuration: lib.util.toNumber( - rootData.transitionDuration, defaults.transitionDuration - ) - }; + // Initialize configuration object. + // Pre-init plugins may make some change, so we calculate it again. + config = buildConfig(); windowScale = computeWindowScale( config ); @@ -890,6 +900,10 @@ preStepLeavePlugins[ weight ].push( plugin ); }; + impress.getConfig = function() { + return config; + }; + // Called at beginning of goto(), to execute all preStepLeave plugins. var execPreStepLeavePlugins = function( event ) { //jshint ignore:line for ( var i = 0; i < preStepLeavePlugins.length; i++ ) { @@ -3663,7 +3677,8 @@ return toNumber( numeric, fallback ); } else { var value = parseFloat( ratio[ 1 ] ); - var multiplier = ratio[ 2 ] === "w" ? window.innerWidth : window.innerHeight; + var config = window.impress.getConfig(); + var multiplier = ratio[ 2 ] === "w" ? config.width : config.height; return value * multiplier; } }; diff --git a/karma.conf.js b/karma.conf.js index 0848e3c..3f1f4e4 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -22,6 +22,7 @@ module.exports = function(config) { "test/core_tests.js", "test/non_default.js", "src/plugins/navigation/navigation_tests.js", + "test/plugins/rel/relative_to_screen_size_tests.js", // Presentation files, for the iframe {pattern: "test/*.html", watched: true, served: true, included: false}, {pattern: "test/plugins/*/*.html", watched: true, served: true, included: false}, diff --git a/qunit_test_runner.html b/qunit_test_runner.html index 749f7ef..358c271 100644 --- a/qunit_test_runner.html +++ b/qunit_test_runner.html @@ -20,5 +20,6 @@ + diff --git a/src/impress.js b/src/impress.js index aeeb36c..5578222 100644 --- a/src/impress.js +++ b/src/impress.js @@ -177,6 +177,9 @@ transitionDuration: 1000 }; + // Configuration options + var config = null; + // It's just an empty function ... and a useless comment. var empty = function() { return false; }; @@ -228,9 +231,6 @@ // Array of step elements var steps = null; - // Configuration options - var config = null; - // Scale factor of the browser window var windowScale = null; @@ -321,9 +321,27 @@ steps.forEach( initStep ); }; + // Build configuration from root and defaults + var buildConfig = function() { + var rootData = root.dataset; + return { + width: lib.util.toNumber( rootData.width, defaults.width ), + height: lib.util.toNumber( rootData.height, defaults.height ), + maxScale: lib.util.toNumber( rootData.maxScale, defaults.maxScale ), + minScale: lib.util.toNumber( rootData.minScale, defaults.minScale ), + perspective: lib.util.toNumber( rootData.perspective, defaults.perspective ), + transitionDuration: lib.util.toNumber( + rootData.transitionDuration, defaults.transitionDuration + ) + }; + }; + // `init` API function that initializes (and runs) the presentation. var init = function() { if ( initialized ) { return; } + + // Initialize the configuration object, so it can be used by pre-init plugins. + config = buildConfig(); execPreInitPlugins( root ); // First we set up the viewport for mobile devices. @@ -335,19 +353,6 @@ document.head.appendChild( meta ); } - // Initialize configuration object - var rootData = root.dataset; - config = { - width: lib.util.toNumber( rootData.width, defaults.width ), - height: lib.util.toNumber( rootData.height, defaults.height ), - maxScale: lib.util.toNumber( rootData.maxScale, defaults.maxScale ), - minScale: lib.util.toNumber( rootData.minScale, defaults.minScale ), - perspective: lib.util.toNumber( rootData.perspective, defaults.perspective ), - transitionDuration: lib.util.toNumber( - rootData.transitionDuration, defaults.transitionDuration - ) - }; - windowScale = computeWindowScale( config ); // Wrap steps with "canvas" element @@ -888,6 +893,10 @@ preStepLeavePlugins[ weight ].push( plugin ); }; + impress.getConfig = function() { + return config; + }; + // Called at beginning of goto(), to execute all preStepLeave plugins. var execPreStepLeavePlugins = function( event ) { //jshint ignore:line for ( var i = 0; i < preStepLeavePlugins.length; i++ ) { diff --git a/src/plugins/rel/rel.js b/src/plugins/rel/rel.js index ef54650..4f58ba7 100644 --- a/src/plugins/rel/rel.js +++ b/src/plugins/rel/rel.js @@ -72,7 +72,8 @@ return toNumber( numeric, fallback ); } else { var value = parseFloat( ratio[ 1 ] ); - var multiplier = ratio[ 2 ] === "w" ? window.innerWidth : window.innerHeight; + var config = window.impress.getConfig(); + var multiplier = ratio[ 2 ] === "w" ? config.width : config.height; return value * multiplier; } }; diff --git a/test/plugins/rel/relative_to_screen_size_tests.js b/test/plugins/rel/relative_to_screen_size_tests.js new file mode 100644 index 0000000..6d242b2 --- /dev/null +++ b/test/plugins/rel/relative_to_screen_size_tests.js @@ -0,0 +1,40 @@ +QUnit.module( "rel plugin relative to screen size tests" ); + +QUnit.test( "relative_to_screen_size", function( assert ) { + window.console.log( "Begin relative_to_screen_size" ); + var done = assert.async(); + + loadIframe( "test/plugins/rel/relative_to_screen_size_tests_presentation.html", assert, function() { + initPresentation( assert, function() { + var iframe = document.getElementById( "presentation-iframe" ); + var iframeDoc = iframe.contentDocument; + + var root = iframeDoc.querySelector( "div#impress" ); + + var origin = iframeDoc.querySelector( "div#origin" ); + var step1 = iframeDoc.querySelector( "div#step1" ); + var step2 = iframeDoc.querySelector( "div#step2" ); + var step3 = iframeDoc.querySelector( "div#step3" ); + + assert.equal( origin.dataset.x, 0, "origin data-x attribute" ); + assert.equal( origin.dataset.y, 0, "origin data-y attribute" ); + assert.equal( origin.dataset.z, 0, "origin data-z attribute" ); + + assert.equal( step1.dataset.x, 2000, "step1 data-x attribute" ); + assert.equal( step1.dataset.y, 1500, "step1 data-y attribute" ); + assert.equal( step1.dataset.z, -2000, "step1 data-z attribute" ); + + assert.equal( step2.dataset.x, -3000, "step2 data-x attribute" ); + assert.equal( step2.dataset.y, -4000, "step2 data-y attribute" ); + assert.equal( step2.dataset.z, 3000, "step2 data-z attribute" ); + + assert.equal( step3.dataset.x, 1000, "step3 data-x attribute" ); + assert.equal( step3.dataset.y, -750, "step3 data-y attribute" ); + assert.equal( step3.dataset.z, 1000, "step3 data-z attribute" ); + + done(); + console.log( "End relative_to_screen_size test (sync)" ); + } ) + } ); // LoadIframe() +} ); + diff --git a/test/plugins/rel/relative_to_screen_size_tests_presentation.html b/test/plugins/rel/relative_to_screen_size_tests_presentation.html new file mode 100644 index 0000000..f2f793e --- /dev/null +++ b/test/plugins/rel/relative_to_screen_size_tests_presentation.html @@ -0,0 +1,48 @@ + + + + + The presentation steps used in an iframe in rel/relative_to_screen_size_tests.js + + + + +
+
+
+
+
+ +
+
+ +
+ + + + +