0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-12-01 13:24:25 +01:00

Merge pull request #8187 from imsky/3.0.0-wip

upgrade holder to 2.0, update thumbnail examples in docs to fit inside containers
This commit is contained in:
Mark Otto 2013-06-16 20:39:11 -07:00
commit 1555992e35
2 changed files with 147 additions and 129 deletions

View File

@ -1,6 +1,6 @@
/* /*
Holder - 1.9 - client side image placeholders Holder - 2.0 - client side image placeholders
(c) 2012-2013 Ivan Malopinsky / http://imsky.co (c) 2012-2013 Ivan Malopinsky / http://imsky.co
Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0 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) { function text_size(width, height, template) {
var dimension_arr = [height, width].sort(); height = parseInt(height,10);
var maxFactor = Math.round(dimension_arr[1] / 16), width = parseInt(width,10);
minFactor = Math.round(dimension_arr[0] / 16); var bigSide = Math.max(height, width)
var text_height = Math.max(template.size, maxFactor); var smallSide = Math.min(height, width)
var scale = 1 / 12;
var newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale);
return { return {
height: text_height height: Math.round(Math.max(template.size, newHeight))
} }
} }
function draw(ctx, dimensions, template, ratio) { function draw(ctx, dimensions, template, ratio) {
var ts = text_size(dimensions.width, dimensions.height, template); var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height; 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"; var font = template.font ? template.font : "sans-serif";
canvas.width = width; canvas.width = width;
canvas.height = height; canvas.height = height;
@ -62,13 +65,14 @@ function draw(ctx, dimensions, template, ratio) {
ctx.fillStyle = template.background; ctx.fillStyle = template.background;
ctx.fillRect(0, 0, width, height); ctx.fillRect(0, 0, width, height);
ctx.fillStyle = template.foreground; ctx.fillStyle = template.foreground;
ctx.font = "bold " + text_height + "px "+font; ctx.font = "bold " + text_height + "px " + font;
var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height); var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (ctx.measureText(text).width / width > 1) { var text_width = ctx.measureText(text).width;
text_height = template.size / (ctx.measureText(text).width / width); if (text_width / width >= 0.75) {
text_height = Math.floor(text_height * 0.75 * (width/text_width));
} }
//Resetting font size if necessary //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); ctx.fillText(text, (width / 2), (height / 2), width);
return canvas.toDataURL("image/png"); return canvas.toDataURL("image/png");
} }
@ -78,89 +82,71 @@ function render(mode, el, holder, src) {
theme = holder.theme, theme = holder.theme,
text = holder.text ? decodeURIComponent(holder.text) : holder.text; text = holder.text ? decodeURIComponent(holder.text) : holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height; var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, { text: text }) : theme); theme = (text ? extend(theme, {
theme = (holder.font ? extend(theme, {font: holder.font}) : theme); text: text
}) : theme);
var ratio = 1; theme = (holder.font ? extend(theme, {
if(window.devicePixelRatio && window.devicePixelRatio > 1){ font: holder.font
ratio = window.devicePixelRatio; }) : theme);
}
if (mode == "image") { if (mode == "image") {
el.setAttribute("data-src", src); el.setAttribute("data-src", src);
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (fallback || !holder.auto) {
if(fallback || !holder.auto){
el.style.width = dimensions.width + "px"; el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px"; el.style.height = dimensions.height + "px";
} }
if (fallback) { if (fallback) {
el.style.backgroundColor = theme.background; el.style.backgroundColor = theme.background;
} else {
}
else{
el.setAttribute("src", draw(ctx, dimensions, theme, ratio)); el.setAttribute("src", draw(ctx, dimensions, theme, ratio));
} }
} else { } else if (mode == "background") {
if (!fallback) { if (!fallback) {
el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")"; 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) { function fluid_update(element) {
var dimensions = holder.dimensions, var images;
theme = holder.theme, if (element.nodeType == null) {
text = holder.text; images = fluid_images;
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))
} else { } else {
fluid.appendChild(document.createTextNode(dimensions_caption)) images = [element]
fluid_images.push(fluid);
setTimeout(fluid_update, 0);
} }
for (i in images) {
el.parentNode.insertBefore(fluid, el.nextSibling) var el = images[i]
if (el.holderData) {
if(window.jQuery){ var holder = el.holderData;
jQuery(function($){ el.setAttribute("src", draw(ctx, {
$(el).on("load", function(){ height: el.clientHeight,
el.style.width = fluid.style.width; width: el.clientWidth
el.style.height = fluid.style.height; }, holder.theme, ratio));
$(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;
} }
} }
@ -186,10 +172,9 @@ function parse_flags(flags, options) {
ret.theme = options.themes[flag]; ret.theme = options.themes[flag];
} else if (app.flags.text.match(flag)) { } else if (app.flags.text.match(flag)) {
ret.text = app.flags.text.output(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); ret.font = app.flags.font.output(flag);
} } else if (app.flags.auto.match(flag)) {
else if(app.flags.auto.match(flag)){
ret.auto = true; ret.auto = true;
} }
} }
@ -198,6 +183,8 @@ function parse_flags(flags, options) {
}; };
if (!canvas.getContext) { if (!canvas.getContext) {
fallback = true; fallback = true;
} else { } 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 fluid_images = [];
var settings = { var settings = {
@ -277,7 +273,7 @@ app.flags = {
}, },
font: { font: {
regex: /font\:(.*)/, regex: /font\:(.*)/,
output: function(val){ output: function (val) {
return this.regex.exec(val)[1]; return this.regex.exec(val)[1];
} }
}, },
@ -287,7 +283,7 @@ app.flags = {
} }
for (var flag in app.flags) { for (var flag in app.flags) {
if(!app.flags.hasOwnProperty(flag)) continue; if (!app.flags.hasOwnProperty(flag)) continue;
app.flags[flag].match = function (val) { app.flags[flag].match = function (val) {
return val.match(this.regex) return val.match(this.regex)
} }
@ -311,26 +307,24 @@ app.add_image = function (src, el) {
}; };
app.run = function (o) { app.run = function (o) {
var options = extend(settings, o), images = []; var options = extend(settings, o),
images = [], imageNodes = [], bgnodes = [];
if(options.images instanceof window.NodeList){ if(typeof(options.images) == "string"){
imageNodes = options.images;
}
else if(options.images instanceof window.Node){
imageNodes = [options.images];
}
else{
imageNodes = selector(options.images); imageNodes = selector(options.images);
} }
else if (window.NodeList && options.images instanceof window.NodeList) {
imageNodes = options.images;
} else if (window.Node && options.images instanceof window.Node) {
imageNodes = [options.images];
}
if(options.elements instanceof window.NodeList){ if(typeof(options.bgnodes) == "string"){
bgnodes = options.bgnodes;
}
else if(options.bgnodes instanceof window.Node){
bgnodes = [options.bgnodes];
}
else{
bgnodes = selector(options.bgnodes); 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; preempted = true;
@ -338,19 +332,19 @@ app.run = function (o) {
for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]); for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
var holdercss = document.getElementById("holderjs-style"); var holdercss = document.getElementById("holderjs-style");
if (!holdercss) {
if(!holdercss){
holdercss = document.createElement("style"); holdercss = document.createElement("style");
holdercss.setAttribute("id", "holderjs-style"); holdercss.setAttribute("id", "holderjs-style");
holdercss.type = "text/css"; holdercss.type = "text/css";
document.getElementsByTagName("head")[0].appendChild(holdercss); document.getElementsByTagName("head")[0].appendChild(holdercss);
} }
if(holdercss.styleSheet){ if (!options.nocss) {
holdercss.styleSheet += options.stylesheet; if (holdercss.styleSheet) {
holdercss.styleSheet.cssText += options.stylesheet;
} else {
holdercss.appendChild(document.createTextNode(options.stylesheet));
} }
else{
holdercss.textContent+= options.stylesheet;
} }
var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)"); var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
@ -359,22 +353,44 @@ app.run = function (o) {
var src = window.getComputedStyle(bgnodes[i], null) var src = window.getComputedStyle(bgnodes[i], null)
.getPropertyValue("background-image"); .getPropertyValue("background-image");
var flags = src.match(cssregex); var flags = src.match(cssregex);
var bgsrc = bgnodes[i].getAttribute("data-background-src");
if (flags) { if (flags) {
var holder = parse_flags(flags[1].split("/"), options); var holder = parse_flags(flags[1].split("/"), options);
if (holder) { if (holder) {
render("background", bgnodes[i], holder, src); 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++) { for (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) { 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) var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options); .split("/"), options);
if (holder) { if (holder) {
if (holder.fluid) { if (holder.fluid) {
fluid(images[i], holder, src); render("fluid", images[i], holder, src)
} else { } else {
render("image", images[i], holder, src); render("image", images[i], holder, src);
} }
@ -394,8 +410,10 @@ contentLoaded(win, function () {
preempted || app.run(); preempted || app.run();
}); });
if ( typeof define === "function" && define.amd ) { if (typeof define === "function" && define.amd) {
define( "Holder", [], function () { return app; } ); define("Holder", [], function () {
return app;
});
} }
})(Holder, window); })(Holder, window);

View File

@ -1759,22 +1759,22 @@ body { padding-bottom: 70px; }
<div class="row"> <div class="row">
<div class="col-lg-3"> <div class="col-lg-3">
<a href="#" class="thumbnail"> <a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt=""> <img data-src="holder.js/100%x180" alt="">
</a> </a>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<a href="#" class="thumbnail"> <a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt=""> <img data-src="holder.js/100%x180" alt="">
</a> </a>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<a href="#" class="thumbnail"> <a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt=""> <img data-src="holder.js/100%x180" alt="">
</a> </a>
</div> </div>
<div class="col-lg-3"> <div class="col-lg-3">
<a href="#" class="thumbnail"> <a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt=""> <img data-src="holder.js/100%x180" alt="">
</a> </a>
</div> </div>
</div> </div>
@ -1783,7 +1783,7 @@ body { padding-bottom: 70px; }
<div class="row"> <div class="row">
<div class="col-lg-3"> <div class="col-lg-3">
<a href="#" class="thumbnail"> <a href="#" class="thumbnail">
<img data-src="holder.js/260x180" alt=""> <img data-src="holder.js/100%x180" alt="">
</a> </a>
</div> </div>
... ...