| | |
| | | |
| | | 1. Create the SVG master file that includes all icons: |
| | | |
| | | The master SVG icon-containing file is an SVG file that contains |
| | | The master SVG icon-containing file is an SVG file that contains |
| | | <g> elements. Each <g> element should contain the markup of an SVG |
| | | icon. The <g> element has an ID that should |
| | | correspond with the ID of the HTML element used on the page that should contain |
| | | icon. The <g> element has an ID that should |
| | | correspond with the ID of the HTML element used on the page that should contain |
| | | or optionally be replaced by the icon. Additionally, one empty element should be |
| | | added at the end with id "svg_eof". |
| | | |
| | |
| | | |
| | | - 'fallback (object literal)': List of raster images with each |
| | | key being the SVG icon ID to replace, and the value the image file name. |
| | | |
| | | |
| | | - 'fallback_path (string)': The path to use for all images |
| | | listed under "fallback" |
| | | |
| | | |
| | | - 'replace (boolean)': If set to true, HTML elements will be replaced by, |
| | | rather than include the SVG icon. |
| | | |
| | |
| | | |
| | | - 'resize (object literal)': List with selectors for keys and numbers |
| | | as values. This allows an easy way to resize specific icons. |
| | | |
| | | - 'callback (function)': A function to call when all icons have been loaded. |
| | | Includes an object literal as its argument with as keys all icon IDs and the |
| | | |
| | | - 'callback (function)': A function to call when all icons have been loaded. |
| | | Includes an object literal as its argument with as keys all icon IDs and the |
| | | icon as a jQuery object as its value. |
| | | |
| | | - 'id_match (boolean)': Automatically attempt to match SVG icon ids with |
| | | corresponding HTML id (default: true) |
| | | |
| | | |
| | | - 'no_img (boolean)': Prevent attempting to convert the icon into an <img> |
| | | element (may be faster, help for browser consistency) |
| | | |
| | |
| | | $.getSvgIcon(id (string)); |
| | | |
| | | This will return the icon (as jQuery object) with a given ID. |
| | | |
| | | |
| | | 6. To resize icons at a later point without using the callback, use this: |
| | | $.resizeSvgIcons(resizeOptions) (use the same way as the "resize" parameter) |
| | | |
| | |
| | | |
| | | $(function() { |
| | | $.svgIcons('my_icon_set.svg'); // The SVG file that contains all icons |
| | | // No options have been set, so all icons will automatically be inserted |
| | | // into HTML elements that match the same IDs. |
| | | // No options have been set, so all icons will automatically be inserted |
| | | // into HTML elements that match the same IDs. |
| | | }); |
| | | |
| | | Example usage #2: |
| | |
| | | resize: function() { |
| | | '#save_icon .svg_icon': 64 // The "save" icon will be resized to 64 x 64px |
| | | }, |
| | | |
| | | callback: function(icons) { // Sets background color for "close" icon |
| | | |
| | | callback: function(icons) { // Sets background color for "close" icon |
| | | icons['close'].css('background','red'); |
| | | }, |
| | | |
| | | |
| | | svgz: true // Indicates that an SVGZ file is being used |
| | | |
| | | |
| | | }) |
| | | }); |
| | | |
| | |
| | | icons_made = false, data_loaded = false, load_attempts = 0, |
| | | ua = navigator.userAgent, isOpera = !!window.opera, isSafari = (ua.indexOf('Safari/') > -1 && ua.indexOf('Chrome/')==-1), |
| | | data_pre = 'data:image/svg+xml;charset=utf-8;base64,'; |
| | | |
| | | |
| | | if(opts.svgz) { |
| | | var data_el = $('<object data="' + file + '" type=image/svg+xml>').appendTo('body').hide(); |
| | | try { |
| | |
| | | if(err.responseText) { |
| | | svgdoc = parser.parseFromString(err.responseText, "text/xml"); |
| | | if(!svgdoc.childNodes.length) { |
| | | $(useFallback); |
| | | $(useFallback); |
| | | } |
| | | $(function() { |
| | | getIcons('ajax'); |
| | | }); |
| | | }); |
| | | } else { |
| | | $(useFallback); |
| | | } |
| | |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | function getIcons(evt, no_wait) { |
| | | if(evt !== 'ajax') { |
| | | if(data_loaded) return; |
| | | // Webkit sometimes says svgdoc is undefined, other times |
| | | // it fails to load all nodes. Thus we must make sure the "eof" |
| | | // it fails to load all nodes. Thus we must make sure the "eof" |
| | | // element is loaded. |
| | | svgdoc = data_el[0].contentDocument; // Needed again for Webkit |
| | | var isReady = (svgdoc && svgdoc.getElementById('svg_eof')); |
| | |
| | | } |
| | | data_loaded = true; |
| | | } |
| | | |
| | | |
| | | elems = $(svgdoc.firstChild).children(); //.getElementsByTagName('foreignContent'); |
| | | |
| | | |
| | | if(!opts.no_img) { |
| | | var testSrc = data_pre + 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNzUiIGhlaWdodD0iMjc1Ij48L3N2Zz4%3D'; |
| | | |
| | | |
| | | testImg = $(new Image()).attr({ |
| | | src: testSrc, |
| | | width: 0, |
| | |
| | | },500); |
| | | } |
| | | } |
| | | |
| | | |
| | | var setIcon = function(target, icon, id, setID) { |
| | | if(isOpera) icon.css('visibility','hidden'); |
| | | if(opts.replace) { |
| | |
| | | if(cl) icon.attr('class','svg_icon '+cl); |
| | | target.replaceWith(icon); |
| | | } else { |
| | | |
| | | |
| | | target.append(icon); |
| | | } |
| | | if(isOpera) { |
| | |
| | | },1); |
| | | } |
| | | } |
| | | |
| | | |
| | | var addIcon = function(icon, id) { |
| | | if(opts.id_match === undefined || opts.id_match !== false) { |
| | | setIcon(holder, icon, id, true); |
| | | } |
| | | svg_icons[id] = icon; |
| | | } |
| | | |
| | | |
| | | function makeIcons(toImage, fallback) { |
| | | if(icons_made) return; |
| | | if(opts.no_img) toImage = false; |
| | | var holder; |
| | | |
| | | |
| | | if(toImage) { |
| | | var temp_holder = $(document.createElement('div')); |
| | | temp_holder.hide().appendTo('body'); |
| | | } |
| | | } |
| | | if(fallback) { |
| | | var path = opts.fallback_path?opts.fallback_path:''; |
| | | $.each(fallback, function(id, imgsrc) { |
| | |
| | | 'height': icon_h, |
| | | 'alt': 'icon' |
| | | }); |
| | | |
| | | |
| | | addIcon(icon, id); |
| | | }); |
| | | } else { |
| | |
| | | var h = svg.getAttribute('height'); |
| | | svg.removeAttribute('width'); |
| | | svg.removeAttribute('height'); |
| | | |
| | | |
| | | var vb = svg.getAttribute('viewBox'); |
| | | if(!vb) { |
| | | svg.setAttribute('viewBox', [0,0,w,h].join(' ')); |
| | | } |
| | | |
| | | |
| | | // Not using jQuery to be a bit faster |
| | | svgroot.setAttribute('xmlns', svgns); |
| | | svgroot.setAttribute('width', icon_w); |
| | |
| | | // Without cloning, Firefox will make another GET request. |
| | | // With cloning, causes issue in Opera/Win/Non-EN |
| | | if(!isOpera) svg = svg.cloneNode(true); |
| | | |
| | | |
| | | svgroot.appendChild(svg); |
| | | |
| | | |
| | | if(toImage) { |
| | | // Without cloning, Safari will crash |
| | | // With cloning, causes issue in Opera/Win/Non-EN |
| | |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | if(opts.placement) { |
| | | $.each(opts.placement, function(sel, id) { |
| | | if(!svg_icons[id]) return; |
| | |
| | | |
| | | if(opts.callback) opts.callback(svg_icons); |
| | | } |
| | | |
| | | |
| | | fixIDs = function(svg_el, svg_num, force) { |
| | | var defs = svg_el.find('defs'); |
| | | if(!defs.length) return svg_el; |
| | | |
| | | |
| | | if(isOpera) { |
| | | var id_elems = defs.find('*').filter(function() { |
| | | return !!this.id; |
| | |
| | | } else { |
| | | var id_elems = defs.find('[id]'); |
| | | } |
| | | |
| | | |
| | | var all_elems = svg_el[0].getElementsByTagName('*'), len = all_elems.length; |
| | | |
| | | |
| | | id_elems.each(function(i) { |
| | | var id = this.id; |
| | | var no_dupes = ($(svgdoc).find('#' + id).length <= 1); |
| | |
| | | // if(!force && no_dupes) return; |
| | | var new_id = 'x' + id + svg_num + i; |
| | | this.id = new_id; |
| | | |
| | | |
| | | var old_val = 'url(#' + id + ')'; |
| | | var new_val = 'url(#' + new_id + ')'; |
| | | |
| | |
| | | }); |
| | | return svg_el; |
| | | } |
| | | |
| | | |
| | | function useFallback() { |
| | | if(file.indexOf('.svgz') != -1) { |
| | | var reg_file = file.replace('.svgz','.svg'); |
| | |
| | | makeIcons(false, opts.fallback); |
| | | } |
| | | } |
| | | |
| | | |
| | | function encode64(input) { |
| | | // base64 strings are 4/3 larger than the original string |
| | | if(window.btoa) return window.btoa(input); |
| | |
| | | var chr1, chr2, chr3; |
| | | var enc1, enc2, enc3, enc4; |
| | | var i = 0, p = 0; |
| | | |
| | | |
| | | do { |
| | | chr1 = input.charCodeAt(i++); |
| | | chr2 = input.charCodeAt(i++); |
| | | chr3 = input.charCodeAt(i++); |
| | | |
| | | |
| | | enc1 = chr1 >> 2; |
| | | enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); |
| | | enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); |
| | | enc4 = chr3 & 63; |
| | | |
| | | |
| | | if (isNaN(chr2)) { |
| | | enc3 = enc4 = 64; |
| | | } else if (isNaN(chr3)) { |
| | | enc4 = 64; |
| | | } |
| | | |
| | | |
| | | output[p++] = _keyStr.charAt(enc1); |
| | | output[p++] = _keyStr.charAt(enc2); |
| | | output[p++] = _keyStr.charAt(enc3); |
| | | output[p++] = _keyStr.charAt(enc4); |
| | | } while (i < input.length); |
| | | |
| | | |
| | | return output.join(''); |
| | | } |
| | | } |
| | | |
| | | $.getSvgIcon = function(id, uniqueClone) { |
| | | |
| | | $.getSvgIcon = function(id, uniqueClone) { |
| | | var icon = svg_icons[id]; |
| | | if(uniqueClone && icon) { |
| | | icon = fixIDs(icon, 0, true).clone(true); |
| | | } |
| | | return icon; |
| | | return icon; |
| | | } |
| | | |
| | | |
| | | $.resizeSvgIcons = function(obj) { |
| | | // FF2 and older don't detect .svg_icon, so we change it detect svg elems instead |
| | | var change_sel = !$('.svg_icon:first').length; |
| | |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | })(jQuery); |
| | | |
| | | })(jQuery); |