webkit 根据background-repeat 来实现背景图片缩放
磨机一下..
background-repeat
可分为repeat-X,repeat-Y,no-repeat,repeat 即按横向平铺,纵向平铺,非平铺和X&Y平铺
background-repeat 默认为repeat
分析这个样式的起因是需要在背景图片w*h < 目标区域的 w*h 为防止图片被剪切 实现图片缩放来将图片显示完整
从开源的WebKit中找到了这段处理的代码
****处理类 :RenderBoxModelObject.cpp
****方法原型:
void RenderBoxModelObject::calculateBackgroundImageGeometry(const FillLayer* fillLayer, int tx, int ty, int w, int h,
IntRect& destRect, IntPoint& phase, IntSize& tileSize)
关键参数注解:
w-->目标显示区域width
h -->目标显示区域height
destRect 含 width,height倆属性 分别为图片需显示的宽度、高度
tileSize 亦含width,height倆属性 分别为图片的元素宽度、高度
我们看一下,WebKit是如何处理的
EFillRepeat backgroundRepeatX = fillLayer->repeatX();
EFillRepeat backgroundRepeatY = fillLayer->repeatY();
int xPosition = fillLayer->xPosition().calcMinValue(positioningAreaSize.width() - tileSize.width(), true);
if (backgroundRepeatX == RepeatFill) // 样式中 横向需平铺时 时执行分支(repeat || repeat-x)
phase.setX(tileSize.width() ? tileSize.width() - (xPosition + left) % tileSize.width() : 0);
else {
/*
此处即可对用户未设置平铺 但图片又小于显示区域是 对图片实行缩小
*/
destRect.move(max(xPosition + left, 0), 0);
phase.setX(-min(xPosition + left, 0));
//destRect.setWidth(tileSize.width() + min(xPosition + left, 0));
/**更新 */
if(w<(tileSize.width() + min(xPosition + left, 0))){
destRect.setWidth(w);
tileSize.setWidth(w);
//注:必须将 图片原始大小和图片目标显示大小同时设置为目标显示区域大小 才能达到缩放的效果
}
}
int yPosition = fillLayer->yPosition().calcMinValue(positioningAreaSize.height() - tileSize.height(), true);
if (backgroundRepeatY == RepeatFill)
phase.setY(tileSize.height() ? tileSize.height() - (yPosition + top) % tileSize.height() : 0);
else {
destRect.move(0, max(yPosition + top, 0));
phase.setY(-min(yPosition + top, 0));
destRect.setHeight(tileSize.height() + min(yPosition + top, 0));
//就不重复上述操作了 若在纵向亦有所需求 可按照上述横向缩放的方式更改此处代码 以达到整张图片的缩放效果
}
if (fixedAttachment)
phase.move(max(tx - destRect.x(), 0), max(ty - destRect.y(), 0));
destRect.intersect(IntRect(tx, ty, w, h));