commit 5380048734733a88c0d1d8e12b384633c2d08418 Author: buttle Date: Sat Apr 17 22:18:36 2021 +0200 initial commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9bd6b00 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Neo-Inspiration + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Module.php b/Module.php new file mode 100644 index 0000000..9280d3e --- /dev/null +++ b/Module.php @@ -0,0 +1,16 @@ + + + + + Wheelzoom + + + Daisy! + + + + \ No newline at end of file diff --git a/asset/vendor/wheelzoom/package.json b/asset/vendor/wheelzoom/package.json new file mode 100644 index 0000000..8884190 --- /dev/null +++ b/asset/vendor/wheelzoom/package.json @@ -0,0 +1,23 @@ +{ + "name": "wheelzoom", + "description": "Zoom IMG elements on mousewheel or touchpad scroll.", + "version": "4.0.1", + "keywords": [ + "zoom", + "images", + "ui" + ], + "author": { + "name": "Jack Moore", + "url": "http://www.jacklmoore.com", + "email": "hello@jacklmoore.com" + }, + "main": "wheelzoom.js", + "license": "MIT", + "homepage": "http://www.jacklmoore.com/wheelzoom", + "demo": "http://www.jacklmoore.com/wheelzoom", + "repository": { + "type": "git", + "url": "http://github.com/jackmoore/wheelzoom.git" + } +} diff --git a/asset/vendor/wheelzoom/readme.md b/asset/vendor/wheelzoom/readme.md new file mode 100644 index 0000000..702b5f2 --- /dev/null +++ b/asset/vendor/wheelzoom/readme.md @@ -0,0 +1,77 @@ +# Wheelzoom + +A small script for zooming IMG elements with the mousewheel/trackpad. Wheelzoom works by replacing the img element's src with a transparent image, then using the original src as a background image, which can be sized and positioned. Wheelzoom is dependency free, doesn't add any extra elements to the DOM, or change the positioning of the IMG element. + +## Usage: +````javascript +wheelzoom(document.querySelectorAll('img')); +// or +wheelzoom(document.querySelectorAll('img'), {zoom:0.05}); +// zoom sets the zoom percent. +```` + +## License +[MIT License](http://opensource.org/licenses/MIT) + +## Supported Browsers: +Chrome, Safari, Opera, FireFox 17+, IE9+. + +## Changelog: + +##### v.4.0.1 - 2019/08/13 +* Added initialX and initialY for setting the initial zoomed coordinates + +##### v.4.0.0 - 2018/10/09 +* Replaced canvas data URI with base64 svg for creating placeholder +* Dropped IE9 support + +##### v.3.1.3 - 2018/01/31 +* Added 'initialZoom' option. Resolves #32 + +##### v.3.1.2 - 2017/04/20 +* Added package.json & added to NPM. + +##### v.3.1.0 - 2017/04/10 +* Added 'maxZoom' option for maximum zoom level. + +##### v.3.0.4 - 2015/12/15 +* Automatically account for changes to the img src, to avoid requiring manually calling destroy and reapply. + +##### v.3.0.3 - 2015/09/05 +* Fixed zoom positioning issue in Firefox. Fixes #17 +* Fixed error when calling destroy in Firefox. Fixes #16 +* Removed debugging statement. Fixes #15 + +##### v.3.0.2 - 2015/09/05 +* Fixed lint warnings and bug introduced in 3.0.1 + +##### v.3.0.1 - 2015/09/05 +* Fixed issue with src URLs that contain single quotes. Fixes #13. + +##### v.3.0.0 - 2014/10/14 +* Removed jQuery dependency +* Added 'wheelzoom.destroy' event for removing changes that wheelzoom has made to an element. + +##### v.2.0.1 - 2014/9/9 +* Merged bugfix to wrap background-image path in quotes. Ref #8. + +##### v.2.0.0 - 2014/4/17 +* Simplified by dropping support for having border and padding on the img element. Borders and/or padding should be applied to the parent element, rather than the img element. + +##### v.1.1.3 - 2014/4/13 +* Minor code improvement. + +##### v.1.1.2 - 2013/1/31 +* Fixed bug with unzoom trigger. + +##### v1.1.1 - 2013/1/29 +* Added trigger to unzoom image: +````javascript + $('#example').trigger('wheelzoom.reset') +```` + +##### v1.1.0 - 2012/11/28 +* Added dragging. + +##### v1.0 - 2012/11/26 +* Initial release. diff --git a/asset/vendor/wheelzoom/wheelzoom.js b/asset/vendor/wheelzoom/wheelzoom.js new file mode 100644 index 0000000..b19dd6c --- /dev/null +++ b/asset/vendor/wheelzoom/wheelzoom.js @@ -0,0 +1,206 @@ +/*! + Wheelzoom 4.0.1 + license: MIT + http://www.jacklmoore.com/wheelzoom +*/ +window.wheelzoom = (function(){ + var defaults = { + zoom: 0.10, + maxZoom: false, + initialZoom: 1, + initialX: 0.5, + initialY: 0.5, + }; + + var main = function(img, options){ + if (!img || !img.nodeName || img.nodeName !== 'IMG') { return; } + + var settings = {}; + var width; + var height; + var bgWidth; + var bgHeight; + var bgPosX; + var bgPosY; + var previousEvent; + var transparentSpaceFiller; + + function setSrcToBackground(img) { + img.style.backgroundRepeat = 'no-repeat'; + img.style.backgroundImage = 'url("'+img.src+'")'; + transparentSpaceFiller = 'data:image/svg+xml;base64,'+window.btoa(''); + img.src = transparentSpaceFiller; + } + + function updateBgStyle() { + if (bgPosX > 0) { + bgPosX = 0; + } else if (bgPosX < width - bgWidth) { + bgPosX = width - bgWidth; + } + + if (bgPosY > 0) { + bgPosY = 0; + } else if (bgPosY < height - bgHeight) { + bgPosY = height - bgHeight; + } + + img.style.backgroundSize = bgWidth+'px '+bgHeight+'px'; + img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px'; + } + + function reset() { + bgWidth = width; + bgHeight = height; + bgPosX = bgPosY = 0; + updateBgStyle(); + } + + function onwheel(e) { + var deltaY = 0; + + e.preventDefault(); + + if (e.deltaY) { // FireFox 17+ (IE9+, Chrome 31+?) + deltaY = e.deltaY; + } else if (e.wheelDelta) { + deltaY = -e.wheelDelta; + } + + // As far as I know, there is no good cross-browser way to get the cursor position relative to the event target. + // We have to calculate the target element's position relative to the document, and subtrack that from the + // cursor's position relative to the document. + var rect = img.getBoundingClientRect(); + var offsetX = e.pageX - rect.left - window.pageXOffset; + var offsetY = e.pageY - rect.top - window.pageYOffset; + + // Record the offset between the bg edge and cursor: + var bgCursorX = offsetX - bgPosX; + var bgCursorY = offsetY - bgPosY; + + // Use the previous offset to get the percent offset between the bg edge and cursor: + var bgRatioX = bgCursorX/bgWidth; + var bgRatioY = bgCursorY/bgHeight; + + // Update the bg size: + if (deltaY < 0) { + bgWidth += bgWidth*settings.zoom; + bgHeight += bgHeight*settings.zoom; + } else { + bgWidth -= bgWidth*settings.zoom; + bgHeight -= bgHeight*settings.zoom; + } + + if (settings.maxZoom) { + bgWidth = Math.min(width*settings.maxZoom, bgWidth); + bgHeight = Math.min(height*settings.maxZoom, bgHeight); + } + + // Take the percent offset and apply it to the new size: + bgPosX = offsetX - (bgWidth * bgRatioX); + bgPosY = offsetY - (bgHeight * bgRatioY); + + // Prevent zooming out beyond the starting size + if (bgWidth <= width || bgHeight <= height) { + reset(); + } else { + updateBgStyle(); + } + } + + function drag(e) { + e.preventDefault(); + bgPosX += (e.pageX - previousEvent.pageX); + bgPosY += (e.pageY - previousEvent.pageY); + previousEvent = e; + updateBgStyle(); + } + + function removeDrag() { + document.removeEventListener('mouseup', removeDrag); + document.removeEventListener('mousemove', drag); + } + + // Make the background draggable + function draggable(e) { + e.preventDefault(); + previousEvent = e; + document.addEventListener('mousemove', drag); + document.addEventListener('mouseup', removeDrag); + } + + function load() { + var initial = Math.max(settings.initialZoom, 1); + + if (img.src === transparentSpaceFiller) return; + + var computedStyle = window.getComputedStyle(img, null); + + width = parseInt(computedStyle.width, 10); + height = parseInt(computedStyle.height, 10); + bgWidth = width * initial; + bgHeight = height * initial; + bgPosX = -(bgWidth - width) * settings.initialX; + bgPosY = -(bgHeight - height) * settings.initialY; + + setSrcToBackground(img); + + img.style.backgroundSize = bgWidth+'px '+bgHeight+'px'; + img.style.backgroundPosition = bgPosX+'px '+bgPosY+'px'; + img.addEventListener('wheelzoom.reset', reset); + + img.addEventListener('wheel', onwheel); + img.addEventListener('mousedown', draggable); + } + + var destroy = function (originalProperties) { + img.removeEventListener('wheelzoom.destroy', destroy); + img.removeEventListener('wheelzoom.reset', reset); + img.removeEventListener('load', load); + img.removeEventListener('mouseup', removeDrag); + img.removeEventListener('mousemove', drag); + img.removeEventListener('mousedown', draggable); + img.removeEventListener('wheel', onwheel); + + img.style.backgroundImage = originalProperties.backgroundImage; + img.style.backgroundRepeat = originalProperties.backgroundRepeat; + img.src = originalProperties.src; + }.bind(null, { + backgroundImage: img.style.backgroundImage, + backgroundRepeat: img.style.backgroundRepeat, + src: img.src + }); + + img.addEventListener('wheelzoom.destroy', destroy); + + options = options || {}; + + Object.keys(defaults).forEach(function(key){ + settings[key] = options[key] !== undefined ? options[key] : defaults[key]; + }); + + if (img.complete) { + load(); + } + + img.addEventListener('load', load); + }; + + // Do nothing in IE9 or below + if (typeof window.btoa !== 'function') { + return function(elements) { + return elements; + }; + } else { + return function(elements, options) { + if (elements && elements.length) { + Array.prototype.forEach.call(elements, function (node) { + main(node, options); + }); + } else if (elements && elements.nodeName) { + main(elements, options); + } + return elements; + }; + } +}()); \ No newline at end of file diff --git a/config/module.config.php b/config/module.config.php new file mode 100644 index 0000000..853110f --- /dev/null +++ b/config/module.config.php @@ -0,0 +1,28 @@ + [ + 'template_path_stack' => [ + dirname(__DIR__) . '/view', + ] + ], + 'block_layouts' => [ + 'factories' => [ + 'imageViewer' => Service\BlockLayout\ImageViewerFactory::class, + ], + ], + 'form_elements' => [ + 'invokables' => [ + Form\ImageViewerBlockForm::class => Form\ImageViewerBlockForm::class, + ], + ], + 'DefaultSettings' => [ + 'ImageViewerBlockForm' => [ + 'title' => '', + 'width' => 600, + 'zoom' => false, + 'wrapStyle' => 'overflow-y: hidden;display: flex;flex-direction: column;justify-content: center;', + ] + ] +]; diff --git a/config/module.ini b/config/module.ini new file mode 100644 index 0000000..8eb3f0a --- /dev/null +++ b/config/module.ini @@ -0,0 +1,12 @@ +[info] +name = "Image viewer" +description = "View and optionally zoom images" +tags = "" +license = "MIT" +author = "Hangar.org" +author_link = "https://git.hangar.org/chris" +module_link = "https://git.hangar.org/arcHIVE-tech/ImageViewer" +support_link = "https://git.hangar.org/arcHIVE-tech/ImageViewer/issues" +configurable = false +version = "1.0.0" +omeka_version_constraint = "^3.0.1" diff --git a/src/Form/ImageViewerBlockForm.php b/src/Form/ImageViewerBlockForm.php new file mode 100644 index 0000000..4dddc64 --- /dev/null +++ b/src/Form/ImageViewerBlockForm.php @@ -0,0 +1,45 @@ +add([ + 'name' => 'o:block[__blockIndex__][o:data][title]', + 'type' => Element\Text::class, + 'options' => [ + 'label' => 'Title (option)', + ] + ]); + + + $this->add([ + 'name' => 'o:block[__blockIndex__][o:data][width]', + 'type' => Element\Number::class, + 'options' => [ + 'label' => 'Width in pixels', + ], + 'attributes' => [ + 'min' => '100', + ], + ]); + + $this->add([ + 'type' => Element\Checkbox::class, + 'name' => 'o:block[__blockIndex__][o:data][zoom]', + 'options' => [ + 'label' => 'Zoom', + //'use_hidden_element' => true, + 'checked_value' => true, + 'unchecked_value' => false, + ], + ]); + + } +} diff --git a/src/Service/BlockLayout/ImageViewerFactory.php b/src/Service/BlockLayout/ImageViewerFactory.php new file mode 100644 index 0000000..946eeb3 --- /dev/null +++ b/src/Service/BlockLayout/ImageViewerFactory.php @@ -0,0 +1,18 @@ +get('FormElementManager'), + $services->get('Config')['DefaultSettings']['ImageViewerBlockForm'] + ); + } +} +?> \ No newline at end of file diff --git a/src/Site/BlockLayout/ImageViewer.php b/src/Site/BlockLayout/ImageViewer.php new file mode 100644 index 0000000..4608ee2 --- /dev/null +++ b/src/Site/BlockLayout/ImageViewer.php @@ -0,0 +1,86 @@ +formElementManager = $formElementManager; + $this->defaultSettings = $defaultSettings; + } + + public function getLabel() { + return 'Image viewer'; + } + + public function form(PhpRenderer $view, + SiteRepresentation $site, + SitePageRepresentation $page = null, + SitePageBlockRepresentation $block = null + ) { + $form = $this->formElementManager->get(ImageViewerBlockForm::class); + $data = $block + ? $block->data() + $this->defaultSettings + : $this->defaultSettings; + $form->setData([ + 'o:block[__blockIndex__][o:data][title]' => $data['title'], + 'o:block[__blockIndex__][o:data][width]' => $data['width'], + 'o:block[__blockIndex__][o:data][zoom]' => $data['zoom'], + ]); + $form->prepare(); + + $html = ''; + $html .= $view->blockAttachmentsForm($block); + $html .= '

'; + $html .= $view->translate('Options'). '

'; + $html .= '
'; + $html .= $view->formCollection($form); + $html .= '
'; + return $html; + } + + public function render(PhpRenderer $view, SitePageBlockRepresentation $block) + { + $attachments = $block->attachments(); + if (!$attachments) { + return ''; + } + + $thumbnails = []; + static $id = 0; + + $media = $attachments[0]->item()->media()[0]; + $width = $block->dataValue('width'); + return $view->partial('common/block-layout/imageViewer', [ + 'zoom' => $block->dataValue('zoom'), + 'title' => $block->dataValue('title'), + 'width' => $width, + 'image' => $media->primaryMedia()->thumbnailUrl('large'), + 'id' => 'iv-' . ++$id, + ]); + } +} diff --git a/view/common/block-layout/imageViewer.phtml b/view/common/block-layout/imageViewer.phtml new file mode 100644 index 0000000..693a408 --- /dev/null +++ b/view/common/block-layout/imageViewer.phtml @@ -0,0 +1,36 @@ + + +headScript()->appendFile($this->assetUrl('vendor/wheelzoom/wheelzoom.js', + 'ImageViewer')); +} ?> + +
+ + %s

', $title); + } else { + $title = false; + } + ?> + + + + + + + + + +