=r;r++){if(e.x=r,e.y=a,s=this.intersection(e,t),!s)return t.push(e),e.show(),!0;r=s.x+s.width-1}i.width+=e.width,i.height+=e.height}return!1}}),n}),define("manager/layout",["wrap/jquery","layout/compact","layout/vertical","layout/horizontal"],function(e,t,i,s){var n={compact:t,vertical:i,horizontal:s};return{set:function(e){var t=n[e]||n.compact;this.manager=new t},getDimensions:function(e,t){return this.manager.getDimensions(e,t)},placeSprites:function(t,i,s,n){var r=this;n(0,"info"),e.map(t,function(e){e.placed||(e.placed=r.manager.placeSprite(e,i,s)),n(i.length/t.length)}),t=e.map(t,function(e){return e.placed?null:e})},trim:function(t,i){var s=0,n=0;e.map(t,function(e){s=s>e.x+e.width?s:e.x+e.width,n=n>e.y+e.height?n:e.y+e.height}),i.width=s||i.width,i.height=n||i.height},getSpritesheet:function(t){var i,s,n,r=t.sprites,a=t.dimensions;i=document.createElement("canvas"),i.width=a.width,i.height=a.height;try{s=i.getContext("2d"),e.map(r,function(e){var t=e.left(),i=e.top();s.drawImage(e.image,t,i)}),n=i.toDataURL("image/png")}catch(o){this.$element.trigger("error",[o])}return n}}}),define("stylesheet/base",["wrap/jquery"],function(e){var t={filename:"spritesheet.png"},i=function(i){this.settings=e.extend({},t,i)};return i.prototype={constructor:i,template:null,get:function(){},markup:function(e,t,i){return this.template({prefix:t,sprites:e,tooltip:i})}},i}),define("stylesheet/css",["wrap/jquery","util/util","util/templates","stylesheet/base"],function(e,t,i,s){var n={filename:"spritesheet.png"},r=function(t){this.settings=e.extend({},n,t)};return t.inherit(r,s,{template:i.cssMarkup,get:function(e,t,s,n,r,a,o){var l=n?t:this.settings.filename;return i.css({prefix:s,backgroundImage:l,sprites:e,canvasWidth:r,canvasHeight:a,units:o})}}),r}),define("stylesheet/less",["wrap/jquery","util/util","util/templates","stylesheet/base"],function(e,t,i,s){var n={filename:"spritesheet.png"},r=function(t){this.settings=e.extend({},n,t)};return t.inherit(r,s,{template:i.lessMarkup,get:function(e,t,s,n,r,a,o){var l=n?t:this.settings.filename;return i.less({prefix:s,backgroundImage:l,sprites:e,canvasWidth:r,canvasHeight:a,units:o})}}),r}),define("stylesheet/sass",["wrap/jquery","util/util","util/templates","stylesheet/base"],function(e,t,i,s){var n={filename:"spritesheet.png"},r=function(t){this.settings=e.extend({},n,t)};return t.inherit(r,s,{template:i.sassMarkup,get:function(e,t,s,n,r,a,o){var l=n?t:this.settings.filename;return i.sass({prefix:s,backgroundImage:l,sprites:e,canvasWidth:r,canvasHeight:a,units:o})}}),r}),define("manager/stylesheet",["wrap/jquery","stylesheet/css","stylesheet/less","stylesheet/sass"],function(e,t,i,s){var n={css:t,less:i,sass:s};return{set:function(e){var t;this.type=e||"css",t=n[this.type],this.manager=new t},getStylesheet:function(e){var t=e.sprites,i=e.spritesheet,s=e.prefix,n=e.uri,r=e.width,a=e.height,o=e.units,l=this.manager.get(t,i,s,n,r,a,o);return l=l.replace(/\\n/g,"\n")},getMarkup:function(e){var t=e.sprites,i=e.prefix,s=e.tooltip||!1,n=this.manager.markup(t,i,s);return n=n.replace(/\\n/g,"\n")}}}),define("module/drop-box",["wrap/jquery","util/util"],function(e,t){var i={},s=function(t,s){this.$element=e(t),this.$overlay=this.$element.find(".stitches-overlay"),this.settings=e.extend({},i,s),this.init()};return s.classname=".stitches-drop-box",s.prototype={constructor:s,init:function(){this.bind()},bind:function(){var i=this.$element.get(0),s=this.$overlay.get(0);i.addEventListener("dragenter",e.proxy(this.dragStart,this),!1),s.addEventListener("dragleave",e.proxy(this.dragStop,this),!1),s.addEventListener("dragexit",e.proxy(this.dragStop,this),!1),s.addEventListener("dragover",t.noop,!1),s.addEventListener("drop",e.proxy(this.drop,this),!1)},dragStart:function(){this.$element.trigger("close-palettes"),this.$element.trigger("show-overlay")},dragStop:function(t){e.contains(this.$element,t.target)&&this.$element.trigger("hide-overlay")},drop:function(e){var t=e.files||e.dataTransfer.files;e.stopPropagation(),e.preventDefault(),t.length?this.$element.trigger("process-files",[t]):this.$element.trigger("hide-overlay")}},s}),define("util/array",["wrap/jquery"],function(e){return{remove:function(t,i){return e(t).filter(function(){return this!==i})}}}),define("module/sprite",["wrap/jquery","util/util","util/templates"],function(e,t,i){var s={name:"",src:"",padding:0},n=function(i,n){this.settings=e.extend({},s,i),this.$element=null,this.name=this.cleanName(this.settings.name),this.src=this.settings.src,this.padding=parseInt(this.settings.padding,10),this.active=!1,this.placed=!1,this.onload=n.onload||t.noop,this.init()};return n.classname=".stitches-sprite",n.prototype={constructor:n,init:function(){this.load()},load:function(){var e=this;this.image=new Image,this.image.onload=function(){e.x=0,e.y=0,e.width=e.image.width+2*e.padding,e.height=e.image.height+2*e.padding,e.area=e.width*e.height,e.render(),e.bind(),e.toDataURL(),e.onload(e)},this.image.src=this.src},render:function(){var t=i.sprite(this);this.$element=e(t),this.$element.data("sprite",this)},bind:function(){this.$element.on("click",e.proxy(this.click,this))},toDataURL:function(){var e,t,i;e=document.createElement("canvas"),e.width=this.image.width,e.height=this.image.height;try{t=e.getContext("2d"),t.drawImage(this.image,0,0),i=e.toDataURL("image/png")}catch(s){this.$element.trigger("error",[s])}this.src=i},reset:function(){this.x=0,this.y=0,this.placed=!1,this.$element.removeClass("placed")},show:function(){this.$element.css({left:this.x+"px",top:this.y+"px",padding:this.padding+"px"}).addClass("placed")},click:function(){var e=!this.active;e?(this.$element.trigger("clear-active",[this]),this.$element.trigger("open-properties",[this])):this.$element.trigger("close-properties"),this.active=e,this.$element.toggleClass("active",e)},configure:function(e){e.padding&&(this.padding=parseInt(e.padding,10),this.width=this.image.width+2*this.padding,this.height=this.image.height+2*this.padding,this.area=this.width*this.height)},cleanName:function(e){return e=e.replace(/\.\w+$/i,""),e=e.replace(/[\s.]+/gi,"-"),e=e.replace(/[^a-z0-9\-]/gi,"_")},left:function(){return this.x+this.padding},top:function(){return this.y+this.padding},toJSON:function(){return{name:this.name,src:this.src}}},n}),define("module/canvas",["wrap/jquery","util/util","util/array","manager/layout","module/sprite"],function(e,t,i,s,n){var r={images:null,dimensions:{width:400,height:400}},a=function(i,s,n){this.$element=e(i),this.settings=e.extend({},r,s),this.images=this.settings.images,this.dimensions=this.settings.dimensions,this.sprites=[],this.names=[],this.onprogress=n.onprogress||t.noop};return a.classname=".stitches-canvas",a.prototype={constructor:a,init:function(){this.reset=t.debounce(this.reset,500),this.bind(),this.setup(),this.reset()},bind:function(){this.$element.on("clear-active",e.proxy(this.clearActive,this))},setup:function(){var t=this;e(this.images).each(function(){var i=e(this),s=i.data("name"),n=i.attr("src");t.createSprite(s,n)}).remove()},reset:function(){this.$element.trigger("show-overlay"),this.measure(this.sprites),this.place(this.sprites),this.cut(this.sprites),this.$element.trigger("generate-sheets"),this.$element.trigger("hide-overlay")},measure:function(e){this.dimensions=s.getDimensions(e,this.settings.dimensions)},place:function(t){var i=[];e.map(t,function(e){e.reset()}),t=t.sort(function(e,t){return e.name===t.name?0:e.name>t.name?1:-1}),s.placeSprites(t,i,this.dimensions,this.onprogress)},cut:function(e){s.trim(e,this.dimensions),this.$element.css({width:this.dimensions.width+"px",height:this.dimensions.height+"px"})},add:function(e){this.sprites.push(e),this.names.push(e.name),this.$element.trigger("show-overlay"),e.$element.appendTo(this.$element),this.$element.trigger("update-toolbar"),this.reset()},remove:function(e){this.sprites=i.remove(this.sprites,e),this.names=i.remove(this.names,e.name),this.$element.trigger("show-overlay"),e.$element.fadeOut("fast").remove(),this.$element.trigger("update-toolbar"),this.$element.trigger("close-properties"),this.reset()},clear:function(){this.empty(),this.$element.trigger("show-overlay"),this.$element.trigger("update-toolbar"),this.$element.trigger("close-properties"),this.$element.trigger("open-settings"),this.reset()},empty:function(){this.sprites=[],this.names=[],this.$element.empty()},createSprite:function(e,t){var i=this;new n({name:e,src:t,padding:this.settings.padding},{onload:function(e){i.add(e)}})},clearActive:function(t,i){this.$element.find(".active").each(function(){var t=e(this),s=t.data("sprite");i&&s!==i&&(t.removeClass("active"),s.active=!1)})},toJSON:function(){return{sprites:this.sprites}}},a}),define("module/toolbar",["wrap/jquery"],function(e){var t={name:"",actions:{}},i=function(i,s){this.$element=e(i),this.settings=e.extend({},t,s),this.name=this.settings.name,this.actions=this.settings.actions,this.init()};return i.classname=".stitches-toolbar",i.prototype={constructor:i,init:function(){this.bind()},bind:function(){var t=this;e.each(this.actions,function(i,s){e.each(s,function(e,s){var n="[data-action="+i+"]",r=t.getHandler(t,s);"instance"===i?t.$element.on(e,t.getHandler(t,r)):t.$element.on(e,n,r)})})},getHandler:function(t,i){return function(s){var n=e(s.currentTarget);n.is(".disabled")?(s.stopPropagation(),s.preventDefault()):i.apply(t,arguments)}},toggleActions:function(t,i){var s=this;"string"==typeof t&&(t=t.split(" ")),e.map(t,function(e){var t=s.$element.find("[data-action="+e+"]");t.toggleClass("disabled",i)})},enable:function(e){this.toggleActions(e,!1)},disable:function(e){this.toggleActions(e,!0)}},i}),define("module/palette",["wrap/jquery","util/util","module/toolbar"],function(e,t,i){var s={name:"",visible:!1,actions:{},fields:{}},n=function(t,i){this.$element=e(t),this.settings=e.extend({},s,i),this.name=this.settings.name,this.visible=this.settings.visible,this.actions=this.settings.actions,this.fields=this.settings.fields,this.source=null,this.init()};return n.classname=".stitches-palette",t.inherit(n,i,{init:function(){this._super("init",this,arguments),this.$element.toggleClass("in",this.visible)},bind:function(){var t=this;this._super("bind",this,arguments),e.each(this.fields,function(i,s){e.each(s,function(e,s){var n="[name="+i+"]",r=t.getHandler(t,s);t.$element.on(e,n,r)})})},open:function(){this.$element.addClass("in"),this.visible=!0},close:function(){this.$element.removeClass("in"),this.visible=!1},configure:function(t){var i=this;this.source=t.source,e.each(t.inputs,function(e,t){var s="[name="+e+"]",n=i.$element.find(s),r=n.attr("type");switch(r){case"radio":case"checkbox":n=n.removeAttr("checked").filter("[value="+t+"]"),n.attr("checked","checked");break;default:n.val(t)}})}}),n}),define("module/stitches",["wrap/jquery","wrap/modernizr","../../../libs/store/store","util/util","util/templates","manager/file","manager/layout","manager/stylesheet","module/drop-box","module/canvas","module/toolbar","module/palette"],function(e,t,i,s,n,r,a,o,l,c,p,h){var u="pixel",d={layout:"compact",prefix:"sprite",padding:5,uri:!1,stylesheet:"css",units:u},f=function(t,i){this.$element=e(t),this.settings=e.extend({},d,i),this.init()};return f.prototype={constructor:f,init:function(){this.configure(),this.render(),this.test(),this.bind(),this.setDropBox(),this.setToolbar(),this.setImages(),this.setCanvas(),this.setManagers(),this.setPalettes(),this.canvas.init()},configure:function(){var t;i&&!i.disabled&&(t=i.get("stitches-settings"),console.log("configure value:"+t.units),t.units||(t.units=u)),t&&(this.settings=e.extend(this.settings,t)),console.log("configure after value:"+t.units)},render:function(){var e=n.stitches({});this.$element.append(e),this.$overlay=this.$element.find(".stitches-overlay"),this.$dropBox=this.$element.find(".stitches-drop-box"),this.$toolbar=this.$element.find(".stitches-toolbar"),this.$canvas=this.$element.find(".stitches-canvas"),this.$progress=this.$element.find(".stitches-progress .progress"),this.$progressBar=this.$element.find(".stitches-progress .bar"),this.$about=this.$element.find(".stitches-about"),this.$downloads=this.$element.find(".stitches-downloads"),this.$settings=this.$element.find(".stitches-settings"),this.$properties=this.$element.find(".stitches-properties")},test:function(){this.hasFileInput=this.$element.find("input.file").length},bind:function(){this.$element.on("show-overlay",e.proxy(this.showOverlay,this)),this.$element.on("hide-overlay",e.proxy(this.hideOverlay,this)),this.$element.on("open-about",e.proxy(this.openAbout,this)),this.$element.on("close-about",e.proxy(this.closeAbout,this)),this.$element.on("open-downloads",e.proxy(this.openDownloads,this)),this.$element.on("close-downloads",e.proxy(this.closeDownloads,this)),this.$element.on("open-settings",e.proxy(this.openSettings,this)),this.$element.on("close-settings",e.proxy(this.closeSettings,this)),this.$element.on("open-properties",e.proxy(this.openProperties,this)),this.$element.on("close-properties",e.proxy(this.closeProperties,this)),this.$element.on("close-palettes",e.proxy(this.closePalettes,this)),this.$element.on("process-files",e.proxy(this.processFiles,this)),this.$element.on("update-toolbar",e.proxy(this.updateToolbar,this)),this.$element.on("update-settings",e.proxy(this.updateSettingsPalette,this)),this.$element.on("update-downloads",e.proxy(this.updateDownloadsPalette,this)),this.$element.on("generate-sheets",e.proxy(this.generateSheets,this)),this.$element.on("error",e.proxy(this.errorHandler,this))},setDropBox:function(){this.dropBox=new l(this.$dropBox)},setManagers:function(){r.set({onload:e.proxy(this.canvas.createSprite,this.canvas),onprogress:e.proxy(this.updateProgress,this)}),a.set(this.settings.layout),o.set(this.settings.stylesheet)},setImages:function(){this.images=this.$element.find("> img").get()},setCanvas:function(){this.canvas=new c(this.$canvas,{images:this.images,padding:this.settings.padding},{onprogress:e.proxy(this.updateProgress,this)})},setToolbar:function(){var e=this;this.toolbar=new p(this.$toolbar,{name:"toolbar",actions:{open:{change:function(t){var i=e.$toolbar.find("input[type=file]"),s=i.clone(!0).val(""),n=t.target.files;e.$element.trigger("process-files",[n]),i.replaceWith(s)}},settings:{click:function(){e.$element.trigger("open-settings")}},reset:{click:function(){e.canvas.reset()}},clear:{click:function(){e.canvas.clear()}},downloads:{click:function(){e.$element.trigger("open-downloads")}},about:{click:function(){e.$element.trigger("open-about")}}}})},setPalettes:function(){var t=this,i=new h(this.$about,{name:"about",visible:!0,actions:{close:{click:function(){this.close()}}}}),s=new h(this.$downloads,{name:"downloads",visible:!1,actions:{close:{click:function(){this.close()}}}}),n=new h(this.$settings,{name:"settings",visible:!1,actions:{close:{click:function(){t.$element.trigger("close-settings")}}},fields:{layout:{change:function(){var e=this.$element.find("input[name=layout]:checked"),i=e.val();this.source.layout=i,a.set(i),t.updateSettings()}},stylesheet:{change:function(){var e=this.$element.find("input[name=stylesheet]:checked"),i=e.val();t.settings.stylesheet=i,o.set(i),t.updateSettings()}},units:{change:function(){var e=this.$element.find("input[name=units]:checked"),i=e.val();console.log("units change, value:"+i),t.settings.units=i,t.updateSettings()}},prefix:{"input blur":function(i){var s=e(i.currentTarget).val();this.source.prefix=s,t.updateSettings()}},padding:{"input blur":function(i){var s=e(i.currentTarget).val();this.source.padding=s,t.canvas.padding=s,e.map(t.canvas.sprites,function(e){e.configure({padding:s})}),t.updateSettings()}},uri:{change:function(i){var s=e(i.currentTarget).is(":checked");this.source.uri=s,t.updateSettings()}},"import":{blur:function(i){var s,n=e(i.currentTarget),r=n.parents(".control-group"),a=n.val();if(r.removeClass("error"),a)try{s=JSON.parse(a),t.importData(s)}catch(o){r.addClass("error"),t.$element.trigger("error",[o])}else t.updateProgress(1,"success")}}}}),r=new h(this.$properties,{name:"properties",visible:!1,actions:{close:{click:function(){t.$element.trigger("close-properties")}},remove:{click:function(){var e=this.source;t.canvas.remove(e)}}},fields:{name:{"input blur":function(t){var i=e(t.currentTarget),s=this.source,n=i.val(),r=s.cleanName(n);this.source.name=r,n!==r&&i.val(r)}}}});this.palettes={about:i,downloads:s,settings:n,properties:r}},updateSettings:function(){this.showOverlay(),this.canvas.reset(),i&&!i.disabled&&i.set("stitches-settings",this.settings)},showOverlay:function(){this.$overlay.fadeTo("fast",.4)},hideOverlay:function(){this.$overlay.fadeOut("fast")},openAbout:function(){this.closePalettes(),this.palettes.about.open()},closeAbout:function(){this.palettes.about.visible&&this.palettes.about.close()},openDownloads:function(){this.closePalettes(),this.palettes.downloads.open()},closeDownloads:function(){this.palettes.downloads.visible&&this.palettes.downloads.close()},openSettings:function(){this.closePalettes(),console.log("openSettings value:"+this.settings.units),this.palettes.settings.configure({source:this.settings,inputs:{layout:this.settings.layout,stylesheet:this.settings.stylesheet,prefix:this.settings.prefix,padding:this.settings.padding,uri:this.settings.uri,units:this.settings.units}}),this.palettes.settings.open()},closeSettings:function(){var e=this.$settings.find("ul.nav-tabs"),t=e.find("li:first-child a"),i=this.$settings.find(":input[name=import]"),s=i.parents(".control-group");t.click(),i.val(""),s.removeClass("error"),this.palettes.settings.visible&&this.palettes.settings.close()},openProperties:function(e,t){this.closePalettes(),this.palettes.properties.configure({source:t,inputs:{name:t.name,x:t.left(),y:t.top()}}),this.palettes.properties.open()},closeProperties:function(){this.palettes.properties.visible&&(this.palettes.properties.close(),this.canvas.$element.trigger("clear-active",[!0]))},closePalettes:function(){this.closeAbout(),this.closeDownloads(),this.closeSettings(),this.closeProperties()},processFiles:function(e,t){r.processFiles(t)},updateToolbar:function(){var e=this.toolbar,t=this.canvas;t.sprites.length?e.enable("reset clear downloads"):e.disable("reset clear downloads"),this.hasFileInput?e.enable("open"):e.disable("open")},updateSettingsPalette:function(){var e=this.$settings.find(".downloads-export");e.attr({href:"data:text/plain,"+encodeURIComponent(JSON.stringify(this)),target:"_blank"})},updateDownloadsPalette:function(){var t=this.$downloads.find("section"),i=this.$downloads.find(".downloads-spritesheet"),s=this.$downloads.find(".downloads-stylesheet"),r=n.downloads({prefix:this.settings.prefix,spritesheet:this.spritesheet,stylesheet:this.stylesheet,units:this.units,stylesheetWithUri:this.stylesheetWithUri,stylesheetType:o.type,stylesheetLines:this.stylesheet.split("\n").length,markup:this.markup,markupLines:this.markup.split("\n").length,markupTooltip:this.markupTooltip});t.html(r),i.attr({href:this.spritesheet,target:"_blank"}),s.attr({href:"data:text/plain,"+encodeURIComponent(this.stylesheet),target:"_blank"}),e.fn.tooltip&&t.find("[data-toggle=tooltip]").tooltip()},updateProgress:function(e,t){var i=Math.ceil(100*e);100===i&&"danger"!==t&&"warning"!==t&&(t="success"),t&&this.$progress.attr({"class":"progress progress-"+t}),this.$progressBar.css({width:i+"%"})},generateSheets:function(){this.spritesheet=a.getSpritesheet({sprites:this.canvas.sprites,dimensions:this.canvas.dimensions}),console.log("generateSheets, units="+this.settings.units),this.stylesheetWithUri=o.getStylesheet({sprites:this.canvas.sprites,spritesheet:this.spritesheet,prefix:this.settings.prefix,uri:!0,width:this.canvas.dimensions.width,height:this.canvas.dimensions.height,units:this.settings.units}),this.markup=o.getMarkup({sprites:this.canvas.sprites,prefix:this.settings.prefix}),this.markupTooltip=o.getMarkup({sprites:this.canvas.sprites,prefix:this.settings.prefix,tooltip:!0}),console.log("generateSheets 2, units="+this.settings.units),this.stylesheet=this.settings.uri?this.stylesheetWithUri:o.getStylesheet({sprites:this.canvas.sprites,spritesheet:this.spritesheet,prefix:this.settings.prefix,uri:this.settings.uri,width:this.canvas.dimensions.width,height:this.canvas.dimensions.height,units:this.settings.units}),this.$element.trigger("update-toolbar"),this.$element.trigger("update-settings"),this.$element.trigger("update-downloads"),this.updateProgress(1,"success")},errorHandler:function(e,t,i){this.updateProgress(1,i||"warning")},toJSON:function(){return{settings:this.settings,canvas:this.canvas.toJSON()}},importData:function(t){var i=this,s=t.settings||{},n=t.canvas||{},r=n.sprites||[];this.settings=e.extend({},d,s),a.set(this.settings.layout),o.set(this.settings.stylesheet),this.updateSettings(),this.canvas.clear(),this.canvas.settings.padding=this.settings.padding,e.map(r,function(e){i.canvas.createSprite(e.name,e.src)}),this.updateProgress(1,"success")}},f}),require({paths:{tpl:"../tpl"}},["wrap/jquery","module/stitches"],function(e,t){e(document).ready(function(){var i=".stitches";e(i).each(function(){new t(this)})})}),define("stitches",function(){});
\ No newline at end of file
diff --git a/src/js/layout/base.js b/src/js/layout/base.js
index be256e46..8756fb57 100644
--- a/src/js/layout/base.js
+++ b/src/js/layout/base.js
@@ -66,12 +66,12 @@ function ($) {
*
* @param {Sprite} sprite The sprite to compare against others
* @param {array} obstacles An array of sprites already placed
+ * @param {boolean} placeX the intersection must place the sprite horizontaly or verticaly
* @return undefined|Sprite
*/
- intersection: function (sprite, obstacles) {
+ intersection: function (sprite, obstacles, placeX) {
var x1, x2, y1, y2;
- var intersections = [];
- var intersection;
+ var intersection = null;
$.map(obstacles, function (obstacle) {
x1 = (obstacle.x < (sprite.x + sprite.width));
@@ -80,14 +80,22 @@ function ($) {
y2 = ((obstacle.y + obstacle.height) > sprite.y);
if (x1 && x2 && y1 && y2) {
- intersections.push(obstacle);
+ if (intersection == null) {
+ intersection = obstacle;
+ } else {
+ if (placeX) {
+ if ((intersection.x + intersection.width) > (obstacle.x + obstacle.width)) {
+ intersection = obstacle;
+ }
+ } else {
+ if ((intersection.y + intersection.height) > (obstacle.y + obstacle.height)) {
+ intersection = obstacle;
+ }
+ }
+ }
}
});
- if (intersections.length) {
- intersection = intersections.pop();
- }
-
return intersection;
}
};
diff --git a/src/js/layout/compact.js b/src/js/layout/compact.js
index 40c8c1af..6742d33d 100644
--- a/src/js/layout/compact.js
+++ b/src/js/layout/compact.js
@@ -81,16 +81,14 @@ function ($, util, BaseLayout) {
placeSprite: function (sprite, placed, dimensions) {
var intersection;
var pass = 0;
- var x = 0;
- var y = 0;
while (pass++ < this.settings.maxPass) {
- for (y = 0; y <= (dimensions.height - sprite.height); y++) {
- for (x = 0; x <= (dimensions.width - sprite.width); x++) {
+ for (var y = 0; y <= (dimensions.height - sprite.height); y++) {
+ for (var x = 0; x <= (dimensions.width - sprite.width); x++) {
sprite.x = x;
sprite.y = y;
- intersection = this.intersection(sprite, placed);
+ intersection = this.intersection(sprite, placed, true);
if (!intersection) {
placed.push(sprite);
@@ -100,12 +98,33 @@ function ($, util, BaseLayout) {
x = intersection.x + intersection.width - 1;
}
-
+ sprite.x = 0;
+ intersection = this.intersection(sprite, placed, false);
+ for (var x = 0; x <= (dimensions.width - sprite.width); x++) {
+ sprite.x = x;
+ var intersectionTmp = this.intersection(sprite, placed, false);
+ if (intersectionTmp) {
+ if (!intersection) {
+ intersection = intersectionTmp;
+ } else {
+ if (intersectionTmp.y + intersectionTmp.height < intersection.y + intersection.height) {
+ intersection = intersectionTmp;
+ }
+ }
+ x += intersectionTmp.width;
+ }
+
+ }
y = intersection.y + intersection.height - 1;
}
- dimensions.width += sprite.width;
- dimensions.height += sprite.height;
+ sprite.x = 0;
+ sprite.y = 0;
+ if (sprite.width * dimensions.width <= sprite.height * dimensions.height) {
+ dimensions.width += sprite.width;
+ } else {
+ dimensions.height += sprite.height;
+ }
}
}
});
diff --git a/src/js/manager/layout.js b/src/js/manager/layout.js
index 5913c9b3..a39a3189 100644
--- a/src/js/manager/layout.js
+++ b/src/js/manager/layout.js
@@ -65,8 +65,30 @@ function ($, CompactLayout, VerticalLayout, HorizontalLayout) {
var self = this;
progress(0, "info");
-
- $.map(sprites, function (sprite) {
+
+ var sizes = [];
+ $.map(sprites, function(sprite) {
+ sizes.push(sprite.width * sprite.height);
+ });
+ sizes.sort(function(a, b){return b-a});
+ var spritesSorted = [];
+ var indexSize = 0;
+ $.map(sprites, function(sprite) {
+ sprite.computed = false;
+ });
+ for (var i = 0; i < sprites.length; i++) {
+ $.map(sprites, function(sprite) {
+ if (!sprite.computed) {
+ if (sprite.width * sprite.height == sizes[indexSize]) {
+ sprite.computed = true;
+ spritesSorted.push(sprite);
+ indexSize++;
+ }
+ }
+ });
+ }
+
+ $.map(spritesSorted, function (sprite) {
if (!sprite.placed) {
sprite.placed = self.manager.placeSprite(sprite, placed, dimensions);
}
diff --git a/src/js/manager/stylesheet.js b/src/js/manager/stylesheet.js
index edc6e42f..301760d9 100644
--- a/src/js/manager/stylesheet.js
+++ b/src/js/manager/stylesheet.js
@@ -11,16 +11,18 @@
define([
"wrap/jquery",
"stylesheet/css",
- "stylesheet/less"
+ "stylesheet/less",
+ "stylesheet/sass"
],
-function ($, CssStylesheet, LessStylesheet) {
+function ($, CssStylesheet, LessStylesheet, SassStylesheet) {
"use strict";
// **Canvas stylesheet managers**
var managers = {
css: CssStylesheet,
- less: LessStylesheet
+ less: LessStylesheet,
+ sass: SassStylesheet
};
// **Module definition**
@@ -54,8 +56,13 @@ function ($, CssStylesheet, LessStylesheet) {
var spritesheet = options.spritesheet;
var prefix = options.prefix;
var uri = options.uri;
+ var width = options.width;
+ var height = options.height;
+ var units = options.units;
+ var exportNormalSize = options.exportNormalSize;
+ var exportPercentageSize = options.exportPercentageSize;
- var styles = this.manager.get(sprites, spritesheet, prefix, uri);
+ var styles = this.manager.get(sprites, spritesheet, prefix, uri, width, height, units, exportNormalSize, exportPercentageSize);
styles = styles.replace(/\\n/g, "\n");
return styles;
diff --git a/src/js/module/canvas.js b/src/js/module/canvas.js
index 72e20533..8349893b 100644
--- a/src/js/module/canvas.js
+++ b/src/js/module/canvas.js
@@ -105,6 +105,17 @@ function($, util, array, layoutManager, Sprite) {
this.$element.trigger("generate-sheets");
this.$element.trigger("hide-overlay");
},
+
+ /**
+ * ### @resetWithoutPosition
+ * Reset the spritesheet generation without recompute the dimensions and position.
+ * Used after a change to sprite's name or settings
+ */
+ resetWithoutPosition: function() {
+ this.$element.trigger("show-overlay");
+ this.$element.trigger("generate-sheets");
+ this.$element.trigger("hide-overlay");
+ },
/**
* ### @measure
@@ -163,7 +174,6 @@ function($, util, array, layoutManager, Sprite) {
this.sprites.push(sprite);
this.names.push(sprite.name);
- this.$element.trigger("show-overlay");
sprite.$element.appendTo(this.$element);
this.$element.trigger("update-toolbar");
@@ -178,7 +188,13 @@ function($, util, array, layoutManager, Sprite) {
* @param {Sprite} sprite The sprite instance to remove
*/
remove: function (sprite) {
- this.sprites = array.remove(this.sprites, sprite);
+ var sprites = array.remove(this.sprites, sprite);
+ this.sprites = [];
+ var globalSprites = this.sprites;
+ $.map(sprites, function (sprite) {
+ globalSprites.push(sprite);
+ });
+
this.names = array.remove(this.names, sprite.name);
this.$element.trigger("show-overlay");
@@ -222,12 +238,14 @@ function($, util, array, layoutManager, Sprite) {
* @param {string} name The sprite name (usually from a file name)
* @param {string} src The image src (usually from a FileReader)
*/
- createSprite: function (name, src) {
+ createSprite: function (name, src, parentWidth, parentHeight) {
var self = this;
var sprite = new Sprite({
name: name,
src: src,
- padding: this.settings.padding
+ padding: this.settings.padding,
+ parentWidth: (parentWidth ? parentWidth : 0),
+ parentHeight: (parentHeight ? parentHeight : 0),
}, {
onload: function (sprite) {
self.add(sprite);
diff --git a/src/js/module/sprite.js b/src/js/module/sprite.js
index 8d37b629..a4a19d58 100644
--- a/src/js/module/sprite.js
+++ b/src/js/module/sprite.js
@@ -22,7 +22,9 @@ function($, util, templates) {
var defaults = {
name: "", // no special chars, no spaces
src: "", // image src (usually from a FileReader)
- padding: 0 // defined in stitches settings
+ padding: 0, // defined in stitches settings
+ parentWidth: 0, //parent div width
+ parentHeight: 0 //parent div height
};
/**
@@ -40,6 +42,8 @@ function($, util, templates) {
this.name = this.cleanName(this.settings.name);
this.src = this.settings.src;
this.padding = parseInt(this.settings.padding, 10);
+ this.parentWidth = parseInt(this.settings.parentWidth);
+ this.parentHeight = parseInt(this.settings.parentHeight);
this.active = false;
this.placed = false;
@@ -72,7 +76,7 @@ function($, util, templates) {
this.image.onload = function () {
self.x = 0;
self.y = 0;
- self.width = self.image.width + self.padding * 2;
+ self.width = self.image.width + self.padding * 2;
self.height = self.image.height + self.padding * 2;
self.area = self.width * self.height;
self.render();
@@ -210,38 +214,32 @@ function($, util, templates) {
* ### @left
* Returns the x position of the sprite accounting for padding
*
- * @param {boolean} isPx Method returns px value
* @return number || string
*/
- left: function (isPx) {
- var left = this.x + this.padding;
-
- // left style position is always negative
- return isPx ? util.toPx(-left) : left;
+ left: function () {
+ return (this.x + this.padding);
},
/**
* ### @top
* Returns the y position of the sprite accounting for padding
*
- * @param {boolean} isPx Method returns px value
* @return number || string
*/
- top: function (isPx) {
- var top = this.y + this.padding;
-
- // top style postion is always negative
- return isPx ? util.toPx(-top) : top;
+ top: function (unit, canvasHeight) {
+ return (this.y + this.padding);
},
- /**
+ /**
* ### @toJSON
* Returns object for sprite export
*/
toJSON: function () {
return {
name: this.name,
- src: this.src
+ src: this.src,
+ parentWidth: this.parentWidth,
+ parentHeight: this.parentHeight
};
}
};
diff --git a/src/js/module/stitches.js b/src/js/module/stitches.js
index 4dbe1166..8bbccb83 100644
--- a/src/js/module/stitches.js
+++ b/src/js/module/stitches.js
@@ -29,12 +29,16 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
"use strict";
+ var UNIT_PIXELS = "pixel";
+ var UNIT_PERCENT = "percent";
+
var defaults = {
layout: "compact", // default canvas sprite placement layout
prefix: "sprite", // default stylesheet class prefix
padding: 5, // default padding around sprites in pixels
uri: false, // whether or not to include the data-uri image (quite large)
- stylesheet: "css" // either css or less at the moment
+ stylesheet: "css", // either css, less or sass at the moment
+ units: UNIT_PIXELS // Units of the spritesheet
};
/**
@@ -87,6 +91,9 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
}
if (settings) {
+ if (!settings.units) {
+ settings.units = UNIT_PIXELS;
+ }
this.settings = $.extend(this.settings, settings);
}
},
@@ -304,6 +311,15 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
self.updateSettings();
}
},
+ units: {
+ "change": function (e) {
+ var $checked = this.$element.find("input[name=units]:checked");
+ var value = $checked.val();
+ self.settings.units = value;
+
+ self.updateSettings();
+ }
+ },
prefix: {
"input blur": function (e) {
var value = $(e.currentTarget).val();
@@ -395,7 +411,21 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
$input.val(clean);
}
}
- }
+ },
+ parentWidth: {
+ "input blur": function (e) {
+ var $input = $(e.currentTarget);
+ var parentWidth = $input.val();
+ this.source.parentWidth = parentWidth;
+ }
+ },
+ parentHeight: {
+ "input blur": function (e) {
+ var $input = $(e.currentTarget);
+ var parentHeight = $input.val();
+ this.source.parentHeight = parentHeight;
+ }
+ }
}
});
@@ -500,7 +530,6 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
*/
openSettings: function (e) {
this.closePalettes();
-
this.palettes.settings.configure({
source: this.settings,
inputs: {
@@ -508,7 +537,8 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
stylesheet: this.settings.stylesheet,
prefix: this.settings.prefix,
padding: this.settings.padding,
- uri: this.settings.uri
+ uri: this.settings.uri,
+ units: this.settings.units
}
});
@@ -555,7 +585,9 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
inputs: {
name: sprite.name,
x: sprite.left(),
- y: sprite.top()
+ y: sprite.top(),
+ parentWidth: sprite.parentWidth,
+ parentHeight: sprite.parentHeight
}
});
@@ -573,6 +605,7 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
if (this.palettes.properties.visible) {
this.palettes.properties.close();
this.canvas.$element.trigger("clear-active", [true]);
+ this.canvas.resetWithoutPosition();
}
},
@@ -646,25 +679,57 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
*
* @param {event} e The event object
*/
- updateDownloadsPalette: function (e) {
+ updateDownloadsPalette: function (e, refreshCss) {
var $section = this.$downloads.find("section");
var $spritesheet = this.$downloads.find(".downloads-spritesheet");
var $stylesheet = this.$downloads.find(".downloads-stylesheet");
- var html = templates.downloads({
+ if (refreshCss) {
+ this.generateSheets(e);
+ }
+
+ var html = templates.downloads({
prefix: this.settings.prefix,
spritesheet: this.spritesheet,
stylesheet: this.stylesheet,
+ units: this.settings.units,
+ responsive: (this.settings.units == UNIT_PERCENT),
stylesheetWithUri: this.stylesheetWithUri,
stylesheetType: stylesheetManager.type,
stylesheetLines: this.stylesheet.split("\n").length,
markup: this.markup,
markupLines: this.markup.split("\n").length,
- markupTooltip: this.markupTooltip
+ markupTooltip: this.markupTooltip,
+ exportNormalSize: this.$settings.exportNormalSizeClick,
+ exportPercentageSize: this.$settings.exportPercentageSizeClick
});
-
+
$section.html(html);
-
+ this.$exportNormalSize = this.$downloads.find(":input[name=exportNormalSize]");
+ this.$exportPercentageSize = this.$downloads.find(":input[name=exportPercentageSize]");
+ this.$exportNormalSize.on("click", $.proxy(this.exportNormalSizeClick, this));
+ this.$exportPercentageSize.on("click", $.proxy(this.exportPercentageSizeClick, this));
+
+ // refresh the css tab with the export option and open the css tab active
+ if (refreshCss) {
+ var tabSpritesheet = this.$downloads.find("#spritesheet");
+ tabSpritesheet.removeClass("active");
+ tabSpritesheet = this.$downloads.find("#tabSpritesheet");
+ tabSpritesheet.removeClass("active");
+
+ var tabStylesheet = this.$downloads.find("#stylesheet");
+ tabStylesheet.addClass("active");
+ tabStylesheet = this.$downloads.find("#tabStylesheet");
+ tabStylesheet.addClass("active");
+
+ if (this.$settings.exportPercentageSizeClick) {
+ this.$exportPercentageSize[0].checked = true;
+ }
+ if (this.$settings.exportNormalSizeClick) {
+ this.$exportNormalSize[0].checked = true;
+ }
+ }
+
// buttons
$spritesheet.attr({
"href": this.spritesheet,
@@ -681,6 +746,16 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
}
},
+ exportNormalSizeClick: function (event) {
+ this.$settings.exportNormalSizeClick = this.$exportNormalSize[0].checked;
+ this.updateDownloadsPalette(event, true);
+ },
+
+ exportPercentageSizeClick: function (event) {
+ this.$settings.exportPercentageSizeClick = this.$exportPercentageSize[0].checked;
+ this.updateDownloadsPalette(event, true);
+ },
+
/**
* ### @updateProgress
* Update the progress bar at the top of the UI, right below the toolbar
@@ -718,12 +793,17 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
sprites: this.canvas.sprites,
dimensions: this.canvas.dimensions
});
-
+
this.stylesheetWithUri = stylesheetManager.getStylesheet({
sprites: this.canvas.sprites,
spritesheet: this.spritesheet,
prefix: this.settings.prefix,
- uri: true
+ uri: true,
+ width: this.canvas.dimensions.width,
+ height: this.canvas.dimensions.height,
+ units: this.settings.units,
+ exportNormalSize: true,
+ exportPercentageSize: this.$settings.exportPercentageSizeClick
});
this.markup = stylesheetManager.getMarkup({
@@ -740,16 +820,22 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
// if uri is not checked, we need to generate another
// stylesheet with the data uri included for the
// download example rendering
- if (this.settings.uri) {
+
+ if (this.settings.uri) {
this.stylesheet = this.stylesheetWithUri;
} else {
- this.stylesheet = stylesheetManager.getStylesheet({
- sprites: this.canvas.sprites,
- spritesheet: this.spritesheet,
- prefix: this.settings.prefix,
- uri: this.settings.uri
- });
- }
+ this.stylesheet = stylesheetManager.getStylesheet({
+ sprites: this.canvas.sprites,
+ spritesheet: this.spritesheet,
+ prefix: this.settings.prefix,
+ uri: this.settings.uri,
+ width: this.canvas.dimensions.width,
+ height: this.canvas.dimensions.height,
+ units: this.settings.units,
+ exportNormalSize: this.$settings.exportNormalSizeClick,
+ exportPercentageSize: this.$settings.exportPercentageSizeClick
+ });
+ }
this.$element.trigger("update-toolbar");
this.$element.trigger("update-settings");
@@ -800,7 +886,7 @@ function($, Modernizr, store, util, templates, fileManager, layoutManager, style
this.canvas.clear();
this.canvas.settings.padding = this.settings.padding;
$.map(sprites, function (sprite) {
- self.canvas.createSprite(sprite.name, sprite.src);
+ self.canvas.createSprite(sprite.name, sprite.src, sprite.parentWidth, sprite.parentHeight);
});
// ok
diff --git a/src/js/stylesheet/base.js b/src/js/stylesheet/base.js
index 2c548b5e..b0c6ae2e 100644
--- a/src/js/stylesheet/base.js
+++ b/src/js/stylesheet/base.js
@@ -45,7 +45,7 @@ function ($) {
* @param {boolean} uri Switch including image as data URI
* @return string
*/
- get: function (sprites, spritesheet, prefix, uri) {},
+ get: function (sprites, spritesheet, prefix, uri, width, height, units, exportNormalSize, exportPercentageSize) {},
/**
* ### @markup
diff --git a/src/js/stylesheet/css.js b/src/js/stylesheet/css.js
index 8e41b475..34744f0f 100644
--- a/src/js/stylesheet/css.js
+++ b/src/js/stylesheet/css.js
@@ -46,13 +46,18 @@ function ($, util, templates, BaseStylesheet) {
* @param {boolean} uri Switch including image as data URI
* @return string
*/
- get: function (sprites, spritesheet, prefix, uri) {
+ get: function (sprites, spritesheet, prefix, uri, width, height, units, exportNormalSize, exportPercentageSize) {
var backgroundImage = uri ? spritesheet : this.settings.filename;
return templates.css({
prefix: prefix,
backgroundImage: backgroundImage,
- sprites: sprites
+ sprites: sprites,
+ canvasWidth: width,
+ canvasHeight: height,
+ units: units,
+ exportNormalSize: exportNormalSize,
+ exportPercentageSize: exportPercentageSize
});
}
});
diff --git a/src/js/stylesheet/less.js b/src/js/stylesheet/less.js
index 062cf168..9161b696 100644
--- a/src/js/stylesheet/less.js
+++ b/src/js/stylesheet/less.js
@@ -46,13 +46,18 @@ function ($, util, templates, BaseStylesheet) {
* @param {boolean} uri Switch including image as data URI
* @return string
*/
- get: function (sprites, spritesheet, prefix, uri) {
+ get: function (sprites, spritesheet, prefix, uri, width, height, units, exportNormalSize, exportPercentageSize) {
var backgroundImage = uri ? spritesheet : this.settings.filename;
return templates.less({
prefix: prefix,
backgroundImage: backgroundImage,
- sprites: sprites
+ sprites: sprites,
+ canvasWidth: width,
+ canvasHeight: height,
+ units: units,
+ exportNormalSize: exportNormalSize,
+ exportPercentageSize: exportPercentageSize
});
}
});
diff --git a/src/js/stylesheet/sass.js b/src/js/stylesheet/sass.js
new file mode 100644
index 00000000..fd9fe2ca
--- /dev/null
+++ b/src/js/stylesheet/sass.js
@@ -0,0 +1,67 @@
+/**
+ * # stylesheet/sass
+ *
+ * Base constructor for the SASS stylesheet manager
+ *
+ * > http://draeton.github.io/stitches
+ * > Copyright 2013 Matthew Cobbs
+ * > Licensed under the MIT license.
+ */
+
+define([
+ "wrap/jquery",
+ "util/util",
+ "util/templates",
+ "stylesheet/base"
+],
+function ($, util, templates, BaseStylesheet) {
+
+ "use strict";
+
+ var defaults = {
+ filename: "spritesheet.png"
+ };
+
+ /**
+ * ## SassStylesheet
+ * Create a new `SassStylesheet` instance
+ *
+ * @constructor
+ * @param {object} options
+ */
+ var SassStylesheet = function (options) {
+ this.settings = $.extend({}, defaults, options);
+ };
+
+ util.inherit(SassStylesheet, BaseStylesheet, {
+ template: templates.sassMarkup,
+
+ /**
+ * ### @get
+ * Returns a stylesheet to place images with spritesheet
+ *
+ * @param {array} sprites A list of sprites
+ * @param {string} spritesheet The data URL of the spritesheet
+ * @param {string} prefix Used to create CSS classes
+ * @param {boolean} uri Switch including image as data URI
+ * @return string
+ */
+ get: function (sprites, spritesheet, prefix, uri, width, height, units, exportNormalSize, exportPercentageSize) {
+ var backgroundImage = uri ? spritesheet : this.settings.filename;
+
+ return templates.sass({
+ prefix: prefix,
+ backgroundImage: backgroundImage,
+ sprites: sprites,
+ canvasWidth: width,
+ canvasHeight: height,
+ units: units,
+ exportNormalSize: exportNormalSize,
+ exportPercentageSize: exportPercentageSize
+ });
+ }
+ });
+
+ return SassStylesheet;
+
+});
\ No newline at end of file
diff --git a/src/js/util/templates.js b/src/js/util/templates.js
index cf21ccae..3a03015f 100644
--- a/src/js/util/templates.js
+++ b/src/js/util/templates.js
@@ -15,9 +15,11 @@ define([
"tpl!../../templates/css.tpl",
"tpl!../../templates/css-markup.tpl",
"tpl!../../templates/less.tpl",
- "tpl!../../templates/less-markup.tpl"
+ "tpl!../../templates/less-markup.tpl",
+ "tpl!../../templates/sass.tpl",
+ "tpl!../../templates/sass-markup.tpl"
],
-function (stitchesTemplate, downloadsTemplate, spriteTemplate, cssTemplate, cssMarkupTemplate, lessTemplate, lessMarkupTemplate) {
+function (stitchesTemplate, downloadsTemplate, spriteTemplate, cssTemplate, cssMarkupTemplate, lessTemplate, lessMarkupTemplate, sassTemplate, sassMarkupTemplate) {
"use strict";
@@ -91,6 +93,26 @@ function (stitchesTemplate, downloadsTemplate, spriteTemplate, cssTemplate, cssM
*/
lessMarkup: function () {
return lessMarkupTemplate.apply(this, arguments);
+ },
+
+ /**
+ * ### @sass
+ * Returns the sass template
+ *
+ * @return string
+ */
+ sass: function () {
+ return sassTemplate.apply(this, arguments);
+ },
+
+ /**
+ * ### @sassMarkup
+ * Returns the sass markup template
+ *
+ * @return string
+ */
+ sassMarkup: function () {
+ return sassMarkupTemplate.apply(this, arguments);
}
};
diff --git a/src/js/util/util.js b/src/js/util/util.js
index ecda87ee..9d8d004b 100644
--- a/src/js/util/util.js
+++ b/src/js/util/util.js
@@ -86,17 +86,6 @@ function ($) {
e.preventDefault();
e.stopPropagation();
}
- },
-
- /**
- * ### @toPx
- * Convet a number to px for stylesheets
- *
- * @param {string} num Pixel value
- * @return string
- */
- toPx: function (num) {
- return num ? num + "px" : "0";
}
};
diff --git a/src/templates/css-markup.tpl b/src/templates/css-markup.tpl
index 0c36709c..efefa031 100644
--- a/src/templates/css-markup.tpl
+++ b/src/templates/css-markup.tpl
@@ -1,6 +1,6 @@
<% $.map(sprites, function (sprite) { %>
<% if (tooltip) { %>
-\n
+\n
<% } else { %>
\n
<% } %>
diff --git a/src/templates/css.tpl b/src/templates/css.tpl
index fc452767..73922669 100644
--- a/src/templates/css.tpl
+++ b/src/templates/css.tpl
@@ -1,14 +1,42 @@
+
.<%= prefix %> {\n
background-image: url(<%= backgroundImage %>);\n
+<% if (units == "pixel") { %>
background-repeat: no-repeat;\n
+<% } else {%>
+ max-width: 100%;\n
+<% } %>
display: block;\n
}\n
<% $.map(sprites, function (sprite) { %>
\n
+<% if (units == "percent") { %>
+<% if (exportNormalSize) { %>
+.<%= prefix %>-<%= sprite.name %>-sizeNormal {\n
+ width: <%= sprite.width %>px;\n
+ height: <%= sprite.height %>px;\n
+}\n
+\n
+<% } %>
+<% if (exportPercentageSize) { %>
+<% if (sprite.parentWidth != 0 || sprite.parentHeight != 0) { %>
+.<%= prefix %>-<%= sprite.name %>-sizePercentage {\n
+ width: <%= ((sprite.parentWidth / sprite.width) * 100) %>%;\n
+ height: <%= ((sprite.parentHeight / sprite.height) * 100) %>%;\n
+}\n
+<% } %>
+<% } %>
+<% } %>
+
.<%= prefix %>-<%= sprite.name %> {\n
- width: <%= sprite.image.width %>px;\n
- height: <%= sprite.image.height %>px;\n
- background-position: <%= sprite.left(true) %> <%= sprite.top(true) %>;\n
+<% if (units == "percent") { %>
+ background-size : <%= ((canvasWidth / sprite.width) * 100) %>% <%= ((canvasHeight / sprite.height) * 100) %>%;\n
+ background-position: <%= ((sprite.left() / (canvasWidth - sprite.width)) * 100) %>% <%= ((sprite.top() / (canvasHeight - sprite.height)) * 100) %>%;\n
+<% } else { %>
+ width: <%= sprite.width %>px;\n
+ height: <%= sprite.height %>px;\n
+ background-position: -<%= sprite.left() %>px -<%= sprite.top() %>px;\n
+<% } %>
}\n
<% }); %>
\ No newline at end of file
diff --git a/src/templates/downloads.tpl b/src/templates/downloads.tpl
index 05c7a89e..bf65b224 100644
--- a/src/templates/downloads.tpl
+++ b/src/templates/downloads.tpl
@@ -1,7 +1,7 @@
@@ -10,6 +10,14 @@

+<% if (responsive) { %>
+
+<% }%>
diff --git a/src/templates/less-markup.tpl b/src/templates/less-markup.tpl
index 96fd1b0f..0be3f5cd 100644
--- a/src/templates/less-markup.tpl
+++ b/src/templates/less-markup.tpl
@@ -1,6 +1,6 @@
<% $.map(sprites, function (sprite) { %>
<% if (tooltip) { %>
-
+
<% } else { %>
\n
<% } %>
diff --git a/src/templates/less.tpl b/src/templates/less.tpl
index b5f976e1..ba8657e1 100644
--- a/src/templates/less.tpl
+++ b/src/templates/less.tpl
@@ -1,17 +1,61 @@
+<% if (units == "pixel") { %>
.stitches-<%= prefix %>(@x: 0, @y: 0, @width: 0, @height: 0) {\n
background-position: @x @y;\n
width: @width;\n
height: @height;\n
}\n
+<% } else if (units == "percent") { %>
+.stitches-<%= prefix %>(@x: 0, @y: 0, @width: 0, @height: 0) {\n
+ background-position: percentage(@x / (<%= canvasWidth %> - @width)) percentage(@y / (<%= canvasHeight %> - @height));\n
+ background-size: percentage(<%= canvasWidth %> / @width) percentage(<%= canvasHeight %> / @height);\n
+}\n
+<% } %>
+\n
+<% if (units == "percent") { %>
+<% if (exportNormalSize) { %>
+.stitches-<%= prefix %>-sizeNormal(@width: 0, @height: 0) {\n
+ width: @width;\n
+ height: @height;\n
+}
+\n
+<% }%>
+<% if (exportPercentageSize) { %>
+.stitches-<%= prefix %>-sizePercentage(@width: 0, @height: 0, @parentWidth: 0, @parentHeight: 0) {\n
+ width: percentage((@parentWidth / @width) * 100);\n
+ height: percentage((@parentHeight / @height * 100);\n
+}
\n
+<% }%>
+<% }%>
.<%= prefix %> {\n
- background-image: url(<%= backgroundImage %>);
+ background-image: url(<%= backgroundImage %>);\n
+<% if (units == "pixel") { %>
background-repeat: no-repeat;\n
+<% } else if (units == "percent") { %>
+ max-width: 100%;\n
+<% } %>
display: block;\n
<% $.map(sprites, function (sprite) { %>
\n
+<% if (units == "percent") { %>
+<% if (exportNormalSize) { %>
+ &.<%= prefix %>-<%= sprite.name %>-sizeNormal {\n
+ .stitches-<%= prefix %>-sizeNormal(<%= sprite.width %>px, <%= sprite.height %>px);\n
+ }\n
+<% } %>
+<% if (exportPercentageSize) { %>
+ &.<%= prefix %>-<%= sprite.name %>-sizePercentage {\n
+ .stitches-<%= prefix %>-sizePercentage(<%= sprite.width %>, <%= sprite.height %>, <%= sprite.parentWidth %>, <%= sprite.parentHeight %>);\n
+ }\n
+<% } %>
+<% } %>
+
&.<%= prefix %>-<%= sprite.name %> {\n
- .stitches-<%= prefix %>(<%= sprite.left(true) %>, <%= sprite.top(true) %>, <%= sprite.image.width %>px, <%= sprite.image.height %>px);\n
+<% if (units == "pixel") { %>
+ .stitches-<%= prefix %>(-<%= sprite.left() %>px, -<%= sprite.top() %>px, <%= sprite.width %>px, <%= sprite.height %>px);\n
+<% } else if (units == "percent") { %>
+ .stitches-<%= prefix %>(<%= sprite.left() %>, <%= sprite.top() %>, <%= sprite.width %>, <%= sprite.height %>);\n
+<% } %>
}\n
<% }); %>
}\n
\ No newline at end of file
diff --git a/src/templates/sass-markup.tpl b/src/templates/sass-markup.tpl
new file mode 100644
index 00000000..0be3f5cd
--- /dev/null
+++ b/src/templates/sass-markup.tpl
@@ -0,0 +1,7 @@
+<% $.map(sprites, function (sprite) { %>
+<% if (tooltip) { %>
+
+<% } else { %>
+\n
+<% } %>
+<% }); %>
\ No newline at end of file
diff --git a/src/templates/sass.tpl b/src/templates/sass.tpl
new file mode 100644
index 00000000..ddb28a73
--- /dev/null
+++ b/src/templates/sass.tpl
@@ -0,0 +1,56 @@
+<% if (units == "pixel") { %>
+@mixin stitches-<%= prefix %>($x: 0, $y: 0, $width: 0, $height: 0)\n
+ background-position: $x $y\n
+ width: $width\n
+ height: $height\n
+\n
+<% } else if (units == "percent") { %>
+@mixin stitches-<%= prefix %>($x: 0, $y: 0, $width: 0, $height: 0)\n
+ background-position: percentage($x / (<%= canvasWidth %> - $width)) percentage($y / (<%= canvasHeight %> - $height))\n
+ background-size: percentage(<%= canvasWidth %> / $width) percentage(<%= canvasHeight %> / $height)\n
+\n
+<% } %>
+<% if (units == "percent") { %>
+<% if (exportNormalSize) { %>
+@mixin stitches-<%= prefix %>-sizeNormal($width: 0, $height: 0)\n
+ width: $width\n
+ height: $height\n
+\n
+<% }%>
+<% if (exportPercentageSize) { %>
+@mixin stitches-<%= prefix %>-sizePercentage($width: 0, $height: 0, $parentWidth: 0, $parentHeight: 0)\n
+ width: percentage(($parentWidth / $width) * 100);\n
+ height: percentage(($parentHeight / $height * 100);\n
+\n
+<% }%>
+<% }%>
+.<%= prefix %> \n
+ background-image: url(<%= backgroundImage %>)\n
+<% if (units == "pixel") { %>
+ background-repeat: no-repeat\n
+<% } else { %>
+ max-width: 100%\n
+<% } %>
+ display: block\n
+<% $.map(sprites, function (sprite) { %>
+<% if (units == "percent") { %>
+<% if (exportNormalSize) { %>
+ .<%= prefix %>-<%= sprite.name %>-sizeNormal\n
+ @include stitches-<%= prefix %>-sizeNormal(<%= sprite.width %>px, <%= sprite.height %>px)\n
+ \n
+<% } %>
+<% if (exportPercentageSize) { %>
+ .<%= prefix %>-<%= sprite.name %>-sizePercentage\n
+ @include stitches-<%= prefix %>-sizePercentage(<%= sprite.width %>, <%= sprite.height %>, <%= sprite.parentWidth %>, <%= sprite.parentHeight %>)\n
+ \n
+<% } %>
+<% } %>
+ .<%= prefix %>-<%= sprite.name %>\n
+<% if (units == "pixel") { %>
+ @include stitches-<%= prefix %>(<%= sprite.left() %>px, <%= sprite.top() %>px, <%= sprite.width %>px, <%= sprite.height %>px)\n
+<% } else if (units == "percent") { %>
+ @include stitches-<%= prefix %>(<%= sprite.left() %>, <%= sprite.top() %>, <%= sprite.width %>, <%= sprite.height %>)\n
+<% } %>
+ \n
+<% }); %>
+\n
\ No newline at end of file
diff --git a/src/templates/stitches.tpl b/src/templates/stitches.tpl
index db7c89ce..a60e72f5 100644
--- a/src/templates/stitches.tpl
+++ b/src/templates/stitches.tpl
@@ -90,7 +90,7 @@
+
+
@@ -154,34 +169,57 @@
-
+
+