From bff7e6703fcdf7e90032e9fe49ecad6fd37aaea1 Mon Sep 17 00:00:00 2001 From: Kevin MacMartin Date: Mon, 13 Nov 2017 19:54:55 -0500 Subject: [PATCH] Add importable javascript "module" version --- README.md | 1 + contain-element-module.js | 149 ++++++++++++++++++++++++++++++++++++++ gulpfile.js | 13 +++- module-template.js | 1 + 4 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 contain-element-module.js create mode 100644 module-template.js diff --git a/README.md b/README.md index 85260fc..126a7f1 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ The plugin scales an element to the minimum size required for it to be completel * Pure JavaScript with no dependencies * Configures the horizontal and vertical alignment of the contained element * Can detect the native size or have it specified at runtime +* Importable javascript module version included as `contain-element-module.js` ## Usage diff --git a/contain-element-module.js b/contain-element-module.js new file mode 100644 index 0000000..de62501 --- /dev/null +++ b/contain-element-module.js @@ -0,0 +1,149 @@ +function ContainElement(options) { + var scaleFactor = 1, + element = options.element || document.getElementById(options.id), + elementWidth = options.width || element.offsetWidth, + elementHeight = options.height || element.offsetHeight, + valign = options.valign || "center", + halign = options.halign || "center", + fit = options.fit || "cover", + scale = options.scale; + + // Apply required attributes to the element + element.style.position = "absolute"; + element.parentElement.style.overflow = "hidden"; + + // Apply required transform-origin if the scale option is set to true + if (scale) { + element.style.transformOrigin = "left top"; + } + + // Apply relative position to the parent if it doesn't already have relative, absolute or fixed positioning + if ([ "relative", "absolute", "fixed" ].indexOf(window.getComputedStyle(element.parentElement, null).getPropertyValue("position")) === -1) { + element.parentElement.style.position = "relative"; + } + + function updateContain() { + var parentWidth = element.parentElement.offsetWidth, + parentHeight = element.parentElement.offsetHeight; + + // Run the scale/position functionality if able to determine the parent element's width and height + if (parentWidth && parentHeight) { + // Calculate the scale factor + if (fit === "cover") { + if (parentWidth > parentHeight / elementHeight * elementWidth) { + scaleFactor = parentWidth / elementWidth; + } else { + scaleFactor = parentHeight / elementHeight; + } + } else if (fit === "contain") { + if (parentHeight > parentWidth / elementWidth * elementHeight) { + scaleFactor = parentWidth / elementWidth; + } else { + scaleFactor = parentHeight / elementHeight; + } + } else { + scaleFactor = 1; + } + + // Scale the element using the scale factor + if (scale) { + element.style.transform = "scale(" + scaleFactor + ")"; + } else { + element.style.width = elementWidth * scaleFactor + "px"; + element.style.height = elementHeight * scaleFactor + "px"; + } + + // Anchor the element horizontally to the left/center/right + if (parentWidth !== elementWidth * scaleFactor) { + switch (halign) { + case "left": + // Anchor horizontally to the left of the parent element + element.style.left = "0px"; + break; + + case "right": + // Anchor horizontally to the right of the parent element + element.style.left = 0 - (elementWidth * scaleFactor - parentWidth) + "px"; + break; + + default: + // Anchor horizontally to the center of the parent element + element.style.left = 0 - (elementWidth * scaleFactor - parentWidth) / 2 + "px"; + } + } else { + element.style.left = "0px"; + } + + // Anchor the element vertically to the top/center/bottom + if (parentHeight !== elementHeight * scaleFactor) { + switch (valign) { + case "top": + // Anchor vertically to the top of the parent element + element.style.top = "0px"; + break; + + case "bottom": + // Anchor veritcally to the bottom of the parent element + element.style.top = 0 - (elementHeight * scaleFactor - parentHeight) + "px"; + break; + + default: + // Anchor vertically to the center of the parent element + element.style.top = 0 - (elementHeight * scaleFactor - parentHeight) / 2 + "px"; + } + } else { + element.style.top = "0px"; + } + } else { + // Try again in 30ms if the document didn't load enough to determine the parent element's width and height yet + window.setTimeout(updateContain, 30); + } + } + + // Run the function to scale and anchor the element + updateContain(); + + // External scale and anchor update function + this.update = updateContain; + + // External function to set elementWidth + this.setWidth = function(newWidth) { elementWidth = newWidth; }; + + // External function to set elementHeight + this.setHeight = function(newHeight) { elementHeight = newHeight; }; + + // External function to set valign + this.setValign = function(newValign) { valign = newValign; }; + + // External function to set halign + this.setHalign = function(newHalign) { halign = newHalign; }; + + // External function to set fit + this.setFit = function(newFit) { fit = newFit; }; + + // External function to return the elementWidth + this.getWidth = function() { return elementWidth; }; + + // External function to return the elementHeight + this.getHeight = function() { return elementHeight; }; + + // External function to return the current width + this.getCurrentWidth = function() { return scaleFactor * elementWidth; }; + + // External function to return the current height + this.getCurrentHeight = function() { return scaleFactor * elementHeight; }; + + // External function to return the current valign + this.getValign = function() { return valign; }; + + // External function to return the current halign + this.getHalign = function() { return halign; }; + + // External function to return the current fit + this.getFit = function() { return fit; }; + + // External function to return the current scale factor + this.getScale = function() { return scaleFactor; }; +} + +export default ContainElement; diff --git a/gulpfile.js b/gulpfile.js index 499e3ef..034411e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -2,11 +2,20 @@ const gulp = require("gulp"), ugly = require("gulp-uglify"), concat = require("gulp-concat"); -gulp.task("min", function() { +gulp.task("module", function() { + return gulp.src([ "contain-element.js", "module-template.js" ]) + .pipe(concat("contain-element-module.js")) + .pipe(gulp.dest("./")); +}); + +gulp.task("minify", function() { return gulp.src("contain-element.js") .pipe(ugly()) .pipe(concat("contain-element.min.js")) .pipe(gulp.dest("./")); }); -gulp.task("default", [ "min" ]); +gulp.task("default", [ + "module", + "minify" +]); diff --git a/module-template.js b/module-template.js new file mode 100644 index 0000000..7e40466 --- /dev/null +++ b/module-template.js @@ -0,0 +1 @@ +export default ContainElement;