diff --git a/README.md b/README.md index 91e2e9d..a3e78f1 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,17 @@ You can check here in use: https://www.miragenews.com/ghost-flight-pilots-fall-a ``` +## Sharing Images + +You can share an image a few ways: + +- Share an image at a URL, using `data-share-image-url` to specify the URL +- Share a DOM element, either a `canvas` or an `img`, using `data-share-image-id` to specify the DOM element ID + +The image name will either be the filename of the image from the URL, or the DOM element id. To override this, use `data-share-image-name`. + +When sharing a remote image, all browser restrictions apply for fetching (e.g. CORS). + ## Options ### data-share-title @@ -91,6 +102,19 @@ The URL to be shared. ``data-share-url="https://nasa.gov"`` +### data-share-image-url +The URL of the image to be shared. + +``data-share-image-url="https://www.nasa.gov/sites/all/themes/custom/nasatwo/images/nasa-logo.svg"`` + +### data-share-image-id +The DOM element ID of the image to be shared. Both `canvas` (the canvas itself, as a PNG) and `img` (the image reference in the `src`) are supported. + +``data-share-image-id="myCanvas"`` + +### data-share-image-name +The name to use for the shared image. If sharing a `canvas` the extension `.png` will be appended if it doesn't exist. + ## Screenshots ### 1. buttons diff --git a/demo.html b/demo.html index 3686368..f940814 100755 --- a/demo.html +++ b/demo.html @@ -24,6 +24,15 @@

Title, text and URL defined

This share button will share a defined title, text and url set by data attributes.

+

Title, URL, and image URL defined

+

This share button will share a defined title and url set by data attributes and include an image from the given image URL.

+ + +

Title, URL, and image ID (to an IMG tag) defined

+

This share button will share a defined title and url set by data attributes and include an image from the referenced DOM element.

+ + + diff --git a/img/nasa-logo.svg b/img/nasa-logo.svg new file mode 100644 index 0000000..f69ca39 --- /dev/null +++ b/img/nasa-logo.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js/better-share.js b/js/better-share.js index bcbff15..13eab0d 100644 --- a/js/better-share.js +++ b/js/better-share.js @@ -1,171 +1,213 @@ function betterShare() { - var that = this; - this.btnSelector = '.better-share'; - this.closeBtnSelector = '.close-btn'; - this.modalID = 'better-share-modal'; - if (!$(this.btnSelector).length) return; - this.buttons = [{ - facebook: '' - }, { - twitter: '' - }, { - email: '' - }, { - whatsapp: '' - }, { - telegram: '' - }]; - - this.buttonsHtml = ''; - this.getTitle = function() { - if (this.button.data('share-title')) { - return this.button.data('share-title'); - } - if ($('head meta[property="og:title"]').length) { - return $('head meta[property="og:title"]').first().attr('content'); - } - return document.title; - }; - - this.getUrl = function() { - if (this.button.data('share-url')) { - return this.button.data('share-url'); - } - if ($('head meta[property="og:url"]').length) { - return $('head meta[property="og:url"]').first().attr('content'); - } - return window.location.href; - }; - - this.getText = function() { - if (this.button.data('share-description')) { - return this.button.data('share-description'); - } - if ($('head meta[property="og:description"]').length) { - return $('head meta[property="og:description"]').first().attr('content'); - } - }; - - this.modalWidth = function() { - return Math.min($(window).width() - 16, 550); - } - - - this.shareModal = function(close) { - //create share modal html - //social media icons - var overlayID = this.modalID + '-overlay'; - $('#' + this.modalID).remove(); - $('body').removeClass(this.modalID + '-open'); - $('#' + overlayID).remove(); - - if (typeof close == 'undefined') { - if (!that.buttonsHtml) { - $.each(this.buttons, function(index, data) { - for (key in data) { - if (data.hasOwnProperty(key)) { - var value = data[key]; - that.buttonsHtml += ''; - } - } - }); - - } - - var div = '
'; - $('body').addClass(this.modalID + '-open'); - - $('body').append(div); - } - } - - this.openFaux = function() { - this.shareModal(); - }; - - this.close = function() { - this.shareModal(1); - }; - - this.telegram = function() { - window.open("https://t.me/share/url?url=" + this.getUrl(), 'share-telegram', 'width=' + this.modalWidth() + ',height=296'); - }; - - this.whatsapp = function() { - window.open("https://api.whatsapp.com/send?text=" + this.getUrl(), 'share-whatsapp', 'width=' + this.modalWidth() + ',height=296'); - }; - - this.facebook = function() { - window.open("https://www.facebook.com/sharer/sharer.php?u=" + this.getUrl(), 'share-facebook', 'width=' + this.modalWidth() + ',height=296'); - }; - - this.twitter = function() { - var params = this.getTitle(); - if (this.getText()) { - params += ' / ' + this.getText(); - } - params += "&url=" + this.getUrl(); - console.log(params); - window.open( - "https://twitter.com/intent/tweet?text=" + params, 'share-twitter', 'width=' + this.modalWidth() + ',height=235' - ); - }; - - this.email = function() { - //check if share text exists - var params = this.getUrl() + "&subject=" + this.getTitle(); - if (this.getText()) { - params = this.getText() + '%0D%0A%0D%0A' + params; - } - - window.open( - "mailto:?&body=" + params, 'share-email' - ); - }; - - - this.share = function() { - if (navigator.share && navigator.userAgent.match(/SamsungBrowser/i) === null) { - //web share API is supported - navigator.share({ - title: this.getTitle(), - text: this.getText(), - url: this.getUrl() - }).then(() => { - console.log('Thanks for sharing!'); - }) - .catch(console.error); - - } else { - this.openFaux(); - var overlayID = this.modalID + '-overlay'; - $('#' + this.modalID + ' button').on('click', function() { - var action = $(this).data('for'); - if (action) - that[action](); - - }); - - $("#" + overlayID).click(function() { - if (!$(this).closest('#' + this.modalID).length) { - that.close(); - } - }); - - } - }; - this._init = function() { - - $(this.btnSelector).on('click', function() { - that.button = $(this); - that.share(); - }); - }; - this._init(); + var that = this; + this.btnSelector = '.better-share'; + this.closeBtnSelector = '.close-btn'; + this.modalID = 'better-share-modal'; + if (!$(this.btnSelector).length) return; + this.buttons = [{ + facebook: '' + }, { + twitter: '' + }, { + email: '' + }, { + whatsapp: '' + }, { + telegram: '' + }]; + + this.buttonsHtml = ''; + this.getTitle = function () { + if (this.button.data('share-title')) { + return this.button.data('share-title'); + } + if ($('head meta[property="og:title"]').length) { + return $('head meta[property="og:title"]').first().attr('content'); + } + return document.title; + }; + + this.getUrl = function () { + if (this.button.data('share-url')) { + return this.button.data('share-url'); + } + if ($('head meta[property="og:url"]').length) { + return $('head meta[property="og:url"]').first().attr('content'); + } + return window.location.href; + }; + + this.getText = function () { + if (this.button.data('share-description')) { + return this.button.data('share-description'); + } + if ($('head meta[property="og:description"]').length) { + return $('head meta[property="og:description"]').first().attr('content'); + } + }; + + this.getImage = async function () { + var dataUrl, filename, imagename = this.button.data('share-image-name'); + + if (this.button.data('share-image-id')) { + var image = document.getElementById(this.button.data('share-image-id')); + switch (image.tagName.toLowerCase()) { + case 'canvas': + dataUrl = image.toDataURL(); + filename = imagename ?? image.id; + if (!filename.endsWith('.png')) { + filename += '.png'; + } + break; + case 'img': + dataUrl = image.src; + filename = dataUrl.substring(dataUrl.lastIndexOf('/') + 1); + break; + default: + console.error('data-share-image-id unsupported tag type: ' + image.tagName); + } + } else if (this.button.data('share-image-url')) { + dataUrl = this.button.data('share-image-url'); + filename = dataUrl.substring(dataUrl.lastIndexOf('/') + 1); + } + if (dataUrl) { + var data = await fetch(dataUrl); + var blob = await data.blob(); + return [ + new File( + [blob], + filename, + { + type: blob.type, + lastModified: new Date().getTime() + } + ) + ]; + } + + return []; + }; + + this.modalWidth = function () { + return Math.min($(window).width() - 16, 550); + } + + + this.shareModal = function (close) { + //create share modal html + //social media icons + var overlayID = this.modalID + '-overlay'; + $('#' + this.modalID).remove(); + $('body').removeClass(this.modalID + '-open'); + $('#' + overlayID).remove(); + + if (typeof close == 'undefined') { + if (!that.buttonsHtml) { + $.each(this.buttons, function (index, data) { + for (key in data) { + if (data.hasOwnProperty(key)) { + var value = data[key]; + that.buttonsHtml += ''; + } + } + }); + + } + + var div = '
'; + $('body').addClass(this.modalID + '-open'); + + $('body').append(div); + } + } + + this.openFaux = function () { + this.shareModal(); + }; + + this.close = function () { + this.shareModal(1); + }; + + this.telegram = function () { + window.open("https://t.me/share/url?url=" + this.getUrl(), 'share-telegram', 'width=' + this.modalWidth() + ',height=296'); + }; + + this.whatsapp = function () { + window.open("https://api.whatsapp.com/send?text=" + this.getUrl(), 'share-whatsapp', 'width=' + this.modalWidth() + ',height=296'); + }; + + this.facebook = function () { + window.open("https://www.facebook.com/sharer/sharer.php?u=" + this.getUrl(), 'share-facebook', 'width=' + this.modalWidth() + ',height=296'); + }; + + this.twitter = function () { + var params = this.getTitle(); + if (this.getText()) { + params += ' / ' + this.getText(); + } + params += "&url=" + this.getUrl(); + console.log(params); + window.open( + "https://twitter.com/intent/tweet?text=" + params, 'share-twitter', 'width=' + this.modalWidth() + ',height=235' + ); + }; + + this.email = function () { + //check if share text exists + var params = this.getUrl() + "&subject=" + this.getTitle(); + if (this.getText()) { + params = this.getText() + '%0D%0A%0D%0A' + params; + } + + window.open( + "mailto:?&body=" + params, 'share-email' + ); + }; + + + this.share = async function () { + if (navigator.share && navigator.userAgent.match(/SamsungBrowser/i) === null) { + //web share API is supported + navigator.share({ + title: this.getTitle(), + text: this.getText(), + url: this.getUrl(), + files: await this.getImage() + }).then(() => { + console.log('Thanks for sharing!'); + }).catch(console.error); + + } else { + this.openFaux(); + var overlayID = this.modalID + '-overlay'; + $('#' + this.modalID + ' button').on('click', function () { + var action = $(this).data('for'); + if (action) + that[action](); + + }); + + $("#" + overlayID).click(function () { + if (!$(this).closest('#' + this.modalID).length) { + that.close(); + } + }); + + } + }; + this._init = function () { + + $(this.btnSelector).on('click', function () { + that.button = $(this); + that.share(); + }); + }; + this._init(); } -$(function() { - betterShare(); +$(function () { + betterShare(); }); \ No newline at end of file