Start implementing background gradients

This commit is contained in:
Niklas von Hertzen
2014-02-01 21:48:30 +02:00
parent 17731169e9
commit 9beae48cf0
9 changed files with 108 additions and 29 deletions

15
src/gradientcontainer.js Normal file
View File

@ -0,0 +1,15 @@
function GradientContainer(imageData) {
this.src = imageData.value;
this.colorStops = [];
this.type = null;
this.x0 = 0.5;
this.y0 = 0.5;
this.x1 = 0.5;
this.y1 = 0.5;
this.promise = Promise.resolve(true);
}
GradientContainer.prototype.TYPES = {
LINEAR: 1,
RADIAL: 2
};

View File

@ -12,7 +12,7 @@ ImageLoader.prototype.findImages = function(nodes) {
};
ImageLoader.prototype.findBackgroundImage = function(images, container) {
container.parseBackgroundImages().filter(this.isImageBackground).map(this.getBackgroundUrl).forEach(this.addImage(images, this.loadImage), this);
container.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(images, this.loadImage), this);
return images;
};
@ -20,30 +20,33 @@ ImageLoader.prototype.addImage = function(images, callback) {
return function(newImage) {
if (!this.imageExists(images, newImage)) {
images.splice(0, 0, callback.apply(this, arguments));
log('Added image #' + (images.length), newImage.substring(0, 100));
log('Added image #' + (images.length), newImage);
}
};
};
ImageLoader.prototype.getBackgroundUrl = function(imageData) {
return imageData.args[0];
ImageLoader.prototype.hasImageBackground = function(imageData) {
return imageData.method !== "none";
};
ImageLoader.prototype.isImageBackground = function(imageData) {
return imageData.method === "url";
};
ImageLoader.prototype.loadImage = function(src) {
if (src.match(/data:image\/.*;base64,/i)) {
return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
} else if (this.isSameOrigin(src) || this.options.allowTaint === true) {
return new ImageContainer(src, false);
} else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {
return new ImageContainer(src, true);
} else if (this.options.proxy) {
return new ProxyImageContainer(src);
} else {
return new DummyImageContainer(src);
ImageLoader.prototype.loadImage = function(imageData) {
if (imageData.method === "url") {
var src = imageData.args[0];
if (src.match(/data:image\/.*;base64,/i)) {
return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
} else if (this.isSameOrigin(src) || this.options.allowTaint === true) {
return new ImageContainer(src, false);
} else if (this.support.cors && !this.options.allowTaint && this.options.useCORS) {
return new ImageContainer(src, true);
} else if (this.options.proxy) {
return new ProxyImageContainer(src);
} else {
return new DummyImageContainer(src);
}
} else if (imageData.method === "linear-gradient") {
return new LinearGradientContainer(imageData);
} else if (imageData.method === "gradient") {
return new WebkitGradientContainer(imageData);
}
};

View File

@ -0,0 +1,33 @@
function LinearGradientContainer(imageData) {
GradientContainer.apply(this, arguments);
this.type = this.TYPES.LINEAR;
imageData.args[0].split(" ").forEach(function(position) {
switch(position) {
case "left":
this.x0 = 0;
this.x1 = 1;
break;
case "top":
this.y0 = 0;
this.y1 = 1;
break;
case "right":
this.x0 = 1;
this.x1 = 0;
break;
case "bottom":
this.y0 = 1;
this.y1 = 0;
break;
}
}, this);
imageData.args.slice(1).forEach(function(colorStop) {
// console.log(colorStop, colorStop.match(this.stepRegExp));
}, this);
}
LinearGradientContainer.prototype = Object.create(GradientContainer.prototype);
LinearGradientContainer.prototype.stepRegExp = /((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/;

View File

@ -73,11 +73,13 @@ NodeParser.prototype.getBounds = function(node) {
if (node.getBoundingClientRect) {
var clientRect = node.getBoundingClientRect();
var isBody = node.nodeName === "BODY";
var width = isBody ? node.scrollWidth : node.offsetWidth;
return {
top: clientRect.top,
bottom: clientRect.bottom || (clientRect.top + clientRect.height),
right: clientRect.left + width,
left: clientRect.left,
width: isBody ? node.scrollWidth : node.offsetWidth,
width: width,
height: isBody ? node.scrollHeight : node.offsetHeight
};
}

View File

@ -51,13 +51,26 @@ Renderer.prototype.renderBorder = function(data) {
Renderer.prototype.renderBackgroundImage = function(container, bounds) {
var backgroundImages = container.parseBackgroundImages();
backgroundImages.reverse().forEach(function(backgroundImage, index, arr) {
if (backgroundImage.method === "url") {
var image = this.images.get(backgroundImage.args[0]);
if (image) {
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1));
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
switch(backgroundImage.method) {
case "url":
var image = this.images.get(backgroundImage.args[0]);
if (image) {
this.renderBackgroundRepeating(container, bounds, image, arr.length - (index+1));
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
case "linear-gradient":
case "gradient":
var gradientImage = this.images.get(backgroundImage.value);
if (gradientImage) {
this.renderBackgroundGradient(gradientImage, bounds);
} else {
log("Error loading background-image", backgroundImage.args[0]);
}
break;
default:
log("Unknown background-image type", backgroundImage.args[0]);
}
}, this);
};

View File

@ -96,6 +96,13 @@ CanvasRenderer.prototype.renderBackgroundRepeat = function(imageContainer, backg
this.ctx.translate(-offsetX, -offsetY);
};
CanvasRenderer.prototype.renderBackgroundGradient = function(gradientImage, bounds) {
if (gradientImage instanceof LinearGradientContainer) {
var gradient = this.ctx.createLinearGradient(bounds.left, bounds.top, bounds.right, bounds.bottom);
//console.log(gradientImage, bounds, gradient);
}
};
CanvasRenderer.prototype.resizeImage = function(imageContainer, size) {
var image = imageContainer.image;
if(image.width === size.width && image.height === size.height) {

View File

@ -0,0 +1,6 @@
function WebkitGradientContainer(imageData) {
GradientContainer.apply(this, arguments);
this.type = (imageData.args[0] === "linear") ? this.TYPES.LINEAR : this.TYPES.RADIAL;
}
WebkitGradientContainer.prototype = Object.create(GradientContainer.prototype);