0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-11-29 11:24:18 +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
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){
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();
});
})
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));
}
}
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];
} 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 = {
@ -277,7 +273,7 @@ app.flags = {
},
font: {
regex: /font\:(.*)/,
output: function(val){
output: function (val) {
return this.regex.exec(val)[1];
}
},
@ -287,7 +283,7 @@ 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) {
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 = [];
var options = extend(settings, o),
images = [], imageNodes = [], bgnodes = [];
if(options.images instanceof window.NodeList){
imageNodes = options.images;
}
else if(options.images instanceof window.Node){
imageNodes = [options.images];
}
else{
if(typeof(options.images) == "string"){
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){
bgnodes = options.bgnodes;
}
else if(options.bgnodes instanceof window.Node){
bgnodes = [options.bgnodes];
}
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){
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;
if (!options.nocss) {
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 + "\/(.*?)\"?\\)");
@ -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);

View File

@ -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>
...