feat: Crop tiles.
Allow tiles to be cropped from their source in the canvas and webgl
renderers.
This can be used to subset a larger image efficiently on multiple tiles
(sprites).
MODIFY
examples/quads/main.js
examples/quads/main.js
-/* globals $, geo, utils */
+/* globals utils */
var quadDebug = {};
@@ -85,6 +85,11 @@ $(function () {
ur: {x: -138, y: 39},
opacity: 0.25,
color: '#0000FF'
+ }, {
+ ll: {x: -88, y: 49},
+ ur: {x: -58, y: 63},
+ image: 'flower1.jpg',
+ crop: {left: 10, right: 240, top: 20, bottom: 260}
}];
if (query.canvas === 'true') {
// You can render a canvas on a quad, but only on the canvas and webgl

MODIFY
src/canvas/quadFeature.js
src/canvas/quadFeature.js
@@ -174,10 +174,17 @@ var canvas_quadFeature = function (arg) {
if (!quad.crop) {
context2d.drawImage(src, 0, 0);
} else {
- var cropx = Math.min(w, quad.crop.x),
- cropy = Math.min(h, quad.crop.y);
- if (cropx > 0 && cropy > 0) {
- context2d.drawImage(src, 0, 0, cropx, cropy, 0, 0, cropx, cropy);
+ const cropw = Math.min(w, quad.crop.x || w),
+ croph = Math.min(h, quad.crop.y || h),
+ cropx0 = Math.max(0, quad.crop.left || 0),
+ cropy0 = Math.max(0, quad.crop.top || 0),
+ cropx1 = Math.min(w, quad.crop.right || w),
+ cropy1 = Math.min(h, quad.crop.bottom || h);
+ if (w && h && cropw > 0 && croph > 0 && cropx1 > cropx0 && cropy1 > cropy0) {
+ context2d.drawImage(
+ src,
+ cropx0, cropy0, Math.floor((cropx1 - cropx0) * cropw / w), Math.floor((cropy1 - cropy0) * croph / h),
+ 0, 0, cropw, croph);
}
}
});

MODIFY
src/quadFeature.js
src/quadFeature.js
@@ -10,6 +10,17 @@ var feature = require('./feature');
* @property {geo.geoPosition} [ur] Upper right coordinate.
* @property {geo.geoPosition} [ll] Lower left coordinate.
* @property {geo.geoPosition} [lr] Lower right coordinate.
+ * @property {object} [crop] Image tile crop size in image pixels. Areas
+ * beyond the width ``x`` and height ``y`` are transparent. ``left``,
+ * ``top``, ``right``, ``bottom`` extract a specific part of the image tile
+ * as the source and expand it to fill the conceptual space before any crop
+ * width and height are applied.
+ * @property {number} [crop.x] Width of image after crop.
+ * @property {number} [crop.y] Height of image after crop.
+ * @property {number} [crop.left] Left coordinate of image source.
+ * @property {number} [crop.top] Top coordinate of image source.
+ * @property {number} [crop.right] Right coordinate of image source.
+ * @property {number} [crop.bottom] Bottom coordinate of image source.
*/
/**

MODIFY
src/webgl/quadFeature.js
src/webgl/quadFeature.js
@@ -158,7 +158,7 @@ var webgl_quadFeature = function (arg) {
* Build this feature.
*/
this._build = function () {
- var mapper, mat, prog, srctex, unicrop, geom, context;
+ var mapper, mat, prog, srctex, unicrop, unicropsource, geom, context;
if (!m_this.position()) {
return;
@@ -187,6 +187,9 @@ var webgl_quadFeature = function (arg) {
unicrop = new vgl.uniform(context.FLOAT_VEC2, 'crop');
unicrop.set([1.0, 1.0]);
prog.addUniform(unicrop);
+ unicropsource = new vgl.uniform(context.FLOAT_VEC4, 'cropsource');
+ unicropsource.set([0.0, 0.0, 0.0, 0.0]);
+ prog.addUniform(unicropsource);
prog.addShader(vgl.getCachedShader(
context.VERTEX_SHADER, context, vertexShaderImage));
prog.addShader(vgl.getCachedShader(
@@ -348,7 +351,9 @@ var webgl_quadFeature = function (arg) {
var context = renderState.m_context,
opacity, zOffset,
- crop = {x: 1, y: 1}, quadcrop;
+ crop = {x: 1, y: 1}, quadcrop,
+ cropsrc = {x0: 0, y0: 0, x1: 1, y1: 1}, quadcropsrc,
+ w, h, quadw, quadh;
context.bindBuffer(context.ARRAY_BUFFER, m_glBuffers.imgQuadsPosition);
$.each(m_quads.imgQuads, function (idx, quad) {
@@ -371,7 +376,18 @@ var webgl_quadFeature = function (arg) {
if (!crop || quadcrop.x !== crop.x || quadcrop.y !== crop.y) {
crop = quadcrop;
context.uniform2fv(renderState.m_material.shaderProgram()
- .uniformLocation('crop'), new Float32Array([crop.x, crop.y]));
+ .uniformLocation('crop'), new Float32Array([crop.x || 1, crop.y || 1]));
+ }
+ w = quad.image.width;
+ h = quad.image.height;
+ quadcropsrc = quad.crop || {left: 0, top: 0, right: w, bottom: h};
+ if (!cropsrc || quadcropsrc.left !== cropsrc.left || quadcropsrc.top !== cropsrc.top || quadcropsrc.right !== cropsrc.right || quadcropsrc.bottom !== cropsrc.bottom || quadw !== w || quadh !== h) {
+ cropsrc = quadcropsrc;
+ quadw = w;
+ quadh = h;
+ context.uniform4fv(renderState.m_material.shaderProgram()
+ .uniformLocation('cropsource'), new Float32Array([
+ cropsrc.left / w, cropsrc.top / h, cropsrc.right / w, cropsrc.bottom / h]));
}
context.bindBuffer(context.ARRAY_BUFFER, m_glBuffers.imgQuadsPosition);
context.vertexAttribPointer(vgl.vertexAttributeKeys.Position, 3,

MODIFY
src/webgl/quadFeatureImage.frag
src/webgl/quadFeatureImage.frag
@@ -13,4 +13,3 @@ void main(void) {
color.w *= opacity;
gl_FragColor = color;
}
-

MODIFY
src/webgl/quadFeatureImage.vert
src/webgl/quadFeatureImage.vert
@@ -6,10 +6,15 @@ uniform float zOffset;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
varying highp vec2 iTextureCoord;
+uniform highp vec4 cropsource;
void main(void) {
gl_Position = projectionMatrix * modelViewMatrix * vec4(vertexPosition, 1.0);
gl_Position.z += zOffset;
+ if (cropsource.p > cropsource.s && cropsource.q > cropsource.t && (cropsource.p < 1.0 || cropsource.s > 0.0 || cropsource.q < 1.0 || cropsource.t > 0.0)) {
+ iTextureCoord.s = textureCoord.s * (cropsource.p - cropsource.s) + cropsource.s;
+ iTextureCoord.t = textureCoord.t * (cropsource.q - cropsource.t) + cropsource.t;
+ } else {
iTextureCoord = textureCoord;
}
-
+}

feat: Crop tiles.

Allow tiles to be cropped from their source in the canvas and webgl
renderers.

This can be used to subset a larger image efficiently on multiple tiles
(sprites).