Commit c1655e6c authored by Ivan Malopinsky's avatar Ivan Malopinsky
Browse files

upgrade holder to 2.0, update thumbnail examples in docs to fit inside containers

parent ac3521fe
Showing with 147 additions and 129 deletions
+147 -129
/*
Holder - 1.9 - client side image placeholders
Holder - 2.0 - client side image placeholders
(c) 2012-2013 Ivan Malopinsky / http://imsky.co
Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
......@@ -41,19 +41,22 @@ if (!Object.prototype.hasOwnProperty)
}
function text_size(width, height, template) {
var dimension_arr = [height, width].sort();
var maxFactor = Math.round(dimension_arr[1] / 16),
minFactor = Math.round(dimension_arr[0] / 16);
var text_height = Math.max(template.size, maxFactor);
height = parseInt(height,10);
width = parseInt(width,10);
var bigSide = Math.max(height, width)
var smallSide = Math.min(height, width)
var scale = 1 / 12;
var newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale);
return {
height: text_height
height: Math.round(Math.max(template.size, newHeight))
}
}
function draw(ctx, dimensions, template, ratio) {
var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height;
var width = dimensions.width * ratio, height = dimensions.height * ratio;
var width = dimensions.width * ratio,
height = dimensions.height * ratio;
var font = template.font ? template.font : "sans-serif";
canvas.width = width;
canvas.height = height;
......@@ -62,13 +65,14 @@ function draw(ctx, dimensions, template, ratio) {
ctx.fillStyle = template.background;
ctx.fillRect(0, 0, width, height);
ctx.fillStyle = template.foreground;
ctx.font = "bold " + text_height + "px "+font;
var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height);
if (ctx.measureText(text).width / width > 1) {
text_height = template.size / (ctx.measureText(text).width / width);
ctx.font = "bold " + text_height + "px " + font;
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
var text_width = ctx.measureText(text).width;
if (text_width / width >= 0.75) {
text_height = Math.floor(text_height * 0.75 * (width/text_width));
}
//Resetting font size if necessary
ctx.font = "bold " + (text_height * ratio) + "px "+font;
ctx.font = "bold " + (text_height * ratio) + "px " + font;
ctx.fillText(text, (width / 2), (height / 2), width);
return canvas.toDataURL("image/png");
}
......@@ -78,89 +82,71 @@ function render(mode, el, holder, src) {
theme = holder.theme,
text = holder.text ? decodeURIComponent(holder.text) : holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, { text: text }) : theme);
theme = (holder.font ? extend(theme, {font: holder.font}) : theme);
var ratio = 1;
if(window.devicePixelRatio && window.devicePixelRatio > 1){
ratio = window.devicePixelRatio;
}
theme = (text ? extend(theme, {
text: text
}) : theme);
theme = (holder.font ? extend(theme, {
font: holder.font
}) : theme);
if (mode == "image") {
el.setAttribute("data-src", src);
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if(fallback || !holder.auto){
el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px";
if (fallback || !holder.auto) {
el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px";
}
if (fallback) {
el.style.backgroundColor = theme.background;
}
else{
} else {
el.setAttribute("src", draw(ctx, dimensions, theme, ratio));
}
} else {
} else if (mode == "background") {
if (!fallback) {
el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")";
el.style.backgroundSize = dimensions.width+"px "+dimensions.height+"px";
el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px";
}
} else if (mode == "fluid") {
el.setAttribute("data-src", src);
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (dimensions.height.substr(-1) == "%") {
el.style.height = dimensions.height
} else {
el.style.height = dimensions.height + "px"
}
if (dimensions.width.substr(-1) == "%") {
el.style.width = dimensions.width
} else {
el.style.width = dimensions.width + "px"
}
if (el.style.display == "inline" || el.style.display == "") {
el.style.display = "block";
}
if (fallback) {
el.style.backgroundColor = theme.background;
} else {
el.holderData = holder;
fluid_images.push(el);
fluid_update(el);
}
}
};
function fluid(el, holder, src) {
var dimensions = holder.dimensions,
theme = holder.theme,
text = holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, {
text: text
}) : theme);
var fluid = document.createElement("div");
fluid.style.backgroundColor = theme.background;
fluid.style.color = theme.foreground;
fluid.className = el.className + " holderjs-fluid";
fluid.style.width = holder.dimensions.width + (holder.dimensions.width.indexOf("%")>0?"":"px");
fluid.style.height = holder.dimensions.height + (holder.dimensions.height.indexOf("%")>0?"":"px");
fluid.id = el.id;
el.style.width=0;
el.style.height=0;
if (theme.text) {
fluid.appendChild(document.createTextNode(theme.text))
function fluid_update(element) {
var images;
if (element.nodeType == null) {
images = fluid_images;
} else {
fluid.appendChild(document.createTextNode(dimensions_caption))
fluid_images.push(fluid);
setTimeout(fluid_update, 0);
images = [element]
}
el.parentNode.insertBefore(fluid, el.nextSibling)
if(window.jQuery){
jQuery(function($){
$(el).on("load", function(){
el.style.width = fluid.style.width;
el.style.height = fluid.style.height;
$(el).show();
$(fluid).remove();
});
})
}
}
function fluid_update() {
for (i in fluid_images) {
if(!fluid_images.hasOwnProperty(i)) continue;
var el = fluid_images[i],
label = el.firstChild;
el.style.lineHeight = el.offsetHeight+"px";
label.data = el.offsetWidth + "x" + el.offsetHeight;
for (i in images) {
var el = images[i]
if (el.holderData) {
var holder = el.holderData;
el.setAttribute("src", draw(ctx, {
height: el.clientHeight,
width: el.clientWidth
}, holder.theme, ratio));
}
}
}
......@@ -186,10 +172,9 @@ function parse_flags(flags, options) {
ret.theme = options.themes[flag];
} else if (app.flags.text.match(flag)) {
ret.text = app.flags.text.output(flag);
} else if(app.flags.font.match(flag)){
} else if (app.flags.font.match(flag)) {
ret.font = app.flags.font.output(flag);
}
else if(app.flags.auto.match(flag)){
} else if (app.flags.auto.match(flag)) {
ret.auto = true;
}
}
......@@ -198,6 +183,8 @@ function parse_flags(flags, options) {
};
if (!canvas.getContext) {
fallback = true;
} else {
......@@ -210,6 +197,15 @@ if (!canvas.getContext) {
}
}
var dpr = 1, bsr = 1;
if(!fallback){
dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
}
var ratio = dpr / bsr;
var fluid_images = [];
var settings = {
......@@ -222,12 +218,12 @@ var settings = {
foreground: "#aaa",
size: 12
},
"social": {
"social": {
background: "#3a5a97",
foreground: "#fff",
size: 12
},
"industrial": {
"industrial": {
background: "#434A52",
foreground: "#C2F200",
size: 12
......@@ -276,18 +272,18 @@ app.flags = {
}
},
font: {
regex: /font\:(.*)/,
output: function(val){
return this.regex.exec(val)[1];
}
regex: /font\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
auto: {
regex: /^auto$/
regex: /^auto$/
}
}
for (var flag in app.flags) {
if(!app.flags.hasOwnProperty(flag)) continue;
if (!app.flags.hasOwnProperty(flag)) continue;
app.flags[flag].match = function (val) {
return val.match(this.regex)
}
......@@ -311,26 +307,24 @@ app.add_image = function (src, el) {
};
app.run = function (o) {
var options = extend(settings, o), images = [];
if(options.images instanceof window.NodeList){
imageNodes = options.images;
}
else if(options.images instanceof window.Node){
imageNodes = [options.images];
}
else{
var options = extend(settings, o),
images = [], imageNodes = [], bgnodes = [];
if(typeof(options.images) == "string"){
imageNodes = selector(options.images);
}
if(options.elements instanceof window.NodeList){
bgnodes = options.bgnodes;
}
else if(options.bgnodes instanceof window.Node){
bgnodes = [options.bgnodes];
else if (window.NodeList && options.images instanceof window.NodeList) {
imageNodes = options.images;
} else if (window.Node && options.images instanceof window.Node) {
imageNodes = [options.images];
}
else{
if(typeof(options.bgnodes) == "string"){
bgnodes = selector(options.bgnodes);
} else if (window.NodeList && options.elements instanceof window.NodeList) {
bgnodes = options.bgnodes;
} else if (window.Node && options.bgnodes instanceof window.Node) {
bgnodes = [options.bgnodes];
}
preempted = true;
......@@ -338,19 +332,19 @@ app.run = function (o) {
for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
var holdercss = document.getElementById("holderjs-style");
if(!holdercss){
holdercss = document.createElement("style");
holdercss.setAttribute("id", "holderjs-style");
holdercss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(holdercss);
if (!holdercss) {
holdercss = document.createElement("style");
holdercss.setAttribute("id", "holderjs-style");
holdercss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(holdercss);
}
if(holdercss.styleSheet){
holdercss.styleSheet += options.stylesheet;
}
else{
holdercss.textContent+= options.stylesheet;
if (!options.nocss) {
if (holdercss.styleSheet) {
holdercss.styleSheet.cssText += options.stylesheet;
} else {
holdercss.appendChild(document.createTextNode(options.stylesheet));
}
}
var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
......@@ -359,22 +353,44 @@ app.run = function (o) {
var src = window.getComputedStyle(bgnodes[i], null)
.getPropertyValue("background-image");
var flags = src.match(cssregex);
var bgsrc = bgnodes[i].getAttribute("data-background-src");
if (flags) {
var holder = parse_flags(flags[1].split("/"), options);
if (holder) {
render("background", bgnodes[i], holder, src);
}
}
else if(bgsrc != null){
var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if(holder){
render("background", bgnodes[i], holder, src);
}
}
}
for (var l = images.length, i = 0; i < l; i++) {
var src = images[i].getAttribute("src") || images[i].getAttribute("data-src");
if (src != null && src.indexOf(options.domain) >= 0) {
for (l = images.length, i = 0; i < l; i++) {
var attr_src = attr_data_src = src = null;
try{
attr_src = images[i].getAttribute("src");
attr_datasrc = images[i].getAttribute("data-src");
}catch(e){}
if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) {
src = attr_src;
} else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) {
src = attr_datasrc;
}
if (src) {
var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if (holder) {
if (holder.fluid) {
fluid(images[i], holder, src);
render("fluid", images[i], holder, src)
} else {
render("image", images[i], holder, src);
}
......@@ -394,8 +410,10 @@ contentLoaded(win, function () {
preempted || app.run();
});
if ( typeof define === "function" && define.amd ) {
define( "Holder", [], function () { return app; } );
if (typeof define === "function" && define.amd) {
define("Holder", [], function () {
return app;
});
}
})(Holder, window);
......@@ -1759,22 +1759,22 @@ body { padding-bottom: 70px; }
<div class="row">
<div class="col-lg-3">
<a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt="">
<img data-src="holder.js/100%x180" alt="">
</a>
</div>
<div class="col-lg-3">
<a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt="">
<img data-src="holder.js/100%x180" alt="">
</a>
</div>
<div class="col-lg-3">
<a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt="">
<img data-src="holder.js/100%x180" alt="">
</a>
</div>
<div class="col-lg-3">
<a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt="">
<img data-src="holder.js/100%x180" alt="">
</a>
</div>
</div>
......@@ -1783,7 +1783,7 @@ body { padding-bottom: 70px; }
<div class="row">
<div class="col-lg-3">
<a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt="">
<img data-src="holder.js/100%x180" alt="">
</a>
</div>
...
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment