UNPKG

pip-webui

Version:

HTML5 UI for LOB applications

319 lines (255 loc) 12.5 kB
/** * @file Collage control * @copyright Digital Living Software Corp. 2014-2015 * @todo * - Improve samples in sampler app * - Replace placeholder with default image generated on server * - Fix resizing problem */ /* global angular */ (function () { 'use strict'; var thisModule = angular.module("pipCollage", ['pipCore', 'pipRest']); thisModule.directive('pipCollage', function () { return { restrict: 'EA', scope: false, controller: 'pipCollageController' } } ); thisModule.controller('pipCollageController', function ($scope, $element, $attrs, $parse, $rootScope, pipUtils, pipStrings, pipRest, pipImageUtils) { var pictureIdsGetter = $attrs.pipPictureIds ? $parse($attrs.pipPictureIds) : null, srcsGetter = $attrs.pipSrcs ? $parse($attrs.pipSrcs) : null, uniqueCodeGetter = $attrs.pipUniqueCode ? $parse($attrs.pipUniqueCode) : null, multipleGetter = $attrs.pipMultiple ? $parse($attrs.pipMultiple) : null, allowOpen = pipUtils.toBoolean($attrs.pipOpen), collageSchemes = pipImageUtils.getCollageSchemes(), resized = 0, $svgData = '<?xml version="1.0" encoding="utf-8"?>'+ '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'+ '<svg version="1.1"'+ 'xmlns="http://www.w3.org/2000/svg"'+ 'xmlns:xlink="http://www.w3.org/1999/xlink"'+ 'x="0px" y="0px"'+ 'viewBox="0 0 510 510"'+ 'style="enable-background:new 0 0 515 515;"'+ 'xml:space="preserve">'+ '<defs>'+ '<style type="text/css"><![CDATA['+ '#symbol-picture-no-border {'+ ' transform-origin: 50% 50%;'+ ' transform: scale(0.6, -0.6);'+ ' }'+ ' ]]></style>'+ ' </defs>'+ '<rect x="0" width="515" height="515"/>'+ '<path id="symbol-picture-no-border" d="M120 325l136-102 69 33 136-82 0-54-410 0 0 136z m341 15c0-28-23-51-51-51-29 0-52 23-52 51 0 29 23 52 52 52 28 0 51-23 51-52z" />'+ '</svg>'; // Add class $element.addClass('pip-collage'); // Also optimization to avoid watch if it is unnecessary if (pipUtils.toBoolean($attrs.pipRebind)) { if (srcsGetter) { $scope.$watch(srcsGetter, function (newValue) { //getImageUrls(); generateContent(); }); $scope.$watchCollection(srcsGetter, function (newValue) { //getImageUrls(); generateContent(); }); } else if (pictureIdsGetter) { $scope.$watch(pictureIdsGetter, function (newValue) { //getImageUrls(); generateContent(); }); } } $scope.getElementDimensions = getElementDimensions; var update = _.debounce(calculateResize, 50); function calculateResize() { var ims = $element.find('img'); var i = 0; for ( i; i < ims.length; i++ ) { var container = angular.element(ims[i].parentElement), image = angular.element(ims[i]); if (image.css('display') != 'none') pipImageUtils.setImageMarginCSS(container, image); } var icns = $element.find('md-icon'); var i = 0; for ( i; i < icns.length; i++ ) { var container = angular.element(icns[i].parentElement), icn = angular.element(icns[i]); if (container.css('display') != 'none') { pipImageUtils.setIconMarginCSS(container[0], icn); } } }; $scope.$watch($scope.getElementDimensions, function (newValue, oldValue) { if (newValue && oldValue && oldValue.h == newValue.h && oldValue.w == newValue.w) return; calculateResize(); }, true); generateContent(); //getImageUrls(); return; function getElementDimensions() { var dimension = { 'h': $element.height(), 'w': $element.width() }; return dimension; }; // Clean up url to remove broken icon function onImageError(event) { var image = $(event.target), container = image.parent(), defaultBlock = container.children('div'), defaultIcon = image.parent().find('md-icon'); defaultBlock.css('display', 'block'); image.css('display', 'none'); pipImageUtils.setIconMarginCSS(container[0], defaultIcon); defaultIcon.empty().append($svgData); }; // When image is loaded resize/reposition it function onImageLoad($event) { var image = $($event.target), container = image.parent(), defaultBlock = container.children('div'); pipImageUtils.setImageMarginCSS(container, image); defaultBlock.css('display', 'none'); }; function getScheme(count) { var schemes = collageSchemes[count - 1]; // If nothing to choose from then return if (schemes.length == 1) return schemes[0]; // Calculate unique had code var uniqueCode = uniqueCodeGetter ? '' + uniqueCodeGetter($scope) : ''; var hash = pipStrings.hashCode(uniqueCode); // Return reproducable scheme by hashcode return schemes[hash % schemes.length]; }; function getImageUrls() { // Simply return sources if (srcsGetter) { var srcs = srcsGetter($scope); //generateContent(); return _.clone(srcs); } // Calculate urls if picture ids are specified if (pictureIdsGetter) { var ids = pictureIdsGetter($scope) || [], serverUrl = pipRest.serverUrl(), userId = ($rootScope.$user || {}).id, partyId = ($rootScope.$party || {}).id || userId, result = []; for (var i = 0; i < ids.length; i++) { result.push( serverUrl + '/api/parties/' + partyId + '/files/' + ids[i] + '/content' ); } return result; } // Return an empty array otherwise return []; }; function generatePicture(urls, scheme) { var url = urls[0], containerClasses = '', pictureClasses = ''; urls.splice(0, 1); containerClasses += scheme.fullWidth ? ' pip-full-width' : ''; containerClasses += scheme.fullHeight ? ' pip-full-height' : ''; containerClasses += ' flex-' + scheme.flex; pictureClasses += scheme.leftPadding ? ' pip-left' : ''; pictureClasses += scheme.rightPadding ? ' pip-right' : ''; pictureClasses += scheme.topPadding ? ' pip-top' : ''; pictureClasses += scheme.bottomPadding ? ' pip-bottom' : ''; if (allowOpen) { return '<a class="pip-picture-container' + containerClasses + '" flex="' + scheme.flex + '" ' + 'href="' + url + '" target="_blank">' + '<div class="pip-picture' + pictureClasses + '"><img src="' + url + '"/>' + '<div><md-icon></md-icon></div></div></a>'; } return '<div class="pip-picture-container' + containerClasses + '" flex="' + scheme.flex + '">' + '<div class="pip-picture' + pictureClasses + '"><img src="' + url + '"/>' + '<div><md-icon></md-icon></div></div></div>'; }; function generatePictureGroup(urls, scheme) { var classes = '', result; classes += scheme.fullWidth ? ' pip-full-width' : ''; classes += scheme.fullHeight ? ' pip-full-height' : ''; classes += ' flex-' + scheme.flex; classes += ' layout-' + scheme.layout; result = '<div class="pip-picture-group layout' + classes + '" flex="' + scheme.flex + '" layout="' + scheme.layout + '">'; // Generate content for children recursively for (var i = 0; i < scheme.children.length; i++) { result += generate(urls, scheme.children[i]); } result += '</div>'; return result; }; function generate(urls, scheme) { if (scheme.group) return generatePictureGroup(urls, scheme); return generatePicture(urls, scheme); }; function generateContent(urls) { // Unbind previously defined actions handlers $element.find('img') .unbind('error') .unbind('load'); // Clean up content $element.empty(); // Calculate list of image urls var urls = getImageUrls(); // And exit if nothing to show if (urls.length == 0) { $element.hide(); return; } // Limit collage only to one element if not specified otherwise if (urls.length > 8) { var multiple = multipleGetter ? multipleGetter($scope) : false; if (!multiple) { urls.length = 8; } } if (urls.length <= 8) { // Get scheme for visualization var scheme = getScheme(urls.length); // Generate and add content var html = '<div class="pip-collage-section">' + generate(urls, scheme) + '</div>'; html += '<div class="clearfix"></div>'; $element.html(html); } else { var html = ''; while (urls.length > 0) { var partialUrls = urls.splice(0, 8); // Get scheme for visualization var scheme = getScheme(partialUrls.length); // Generate and add content html += '<div class="pip-collage-section">' + generate(partialUrls, scheme) + '</div>'; } html += '<div class="clearfix"></div>'; $element.html(html); } // Bind events to images... $element.find('img') .bind('error', onImageError) .bind('load', onImageLoad); // Show the new element $element.show(); }; } ); })();