Skip to content

Commit

Permalink
Final
Browse files Browse the repository at this point in the history
  • Loading branch information
ftoromanoff committed Jul 13, 2023
1 parent 688b844 commit a7b9c74
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 71 deletions.
29 changes: 3 additions & 26 deletions src/Converter/Feature2Texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as THREE from 'three';
import { FEATURE_TYPES } from 'Core/Feature';
import Extent from 'Core/Geographic/Extent';
import Coordinates from 'Core/Geographic/Coordinates';
import Style from 'Core/Style';

const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const matrix = svg.createSVGMatrix();
Expand Down Expand Up @@ -36,41 +37,17 @@ function _drawPolygon(ctx, vertices, indices, style, size, extent, invCtxScale,

// draw line or edge of polygon
if (style.stroke) {
// TO DO move to Style
strokeStyle(style, ctx, invCtxScale);
ctx.stroke();
}

// fill polygon only
if (canBeFilled && style.fill) {
// fillStyle(style, ctx, invCtxScale);
// ctx.fill();
style.fillPolygon(ctx, matrix.scale(invCtxScale));
new Style(style).fillPolygon(ctx, matrix.scale(invCtxScale));
}
}

// async function fillStyle(style, ctx, invCtxScale) {
// if (style.fill.pattern) {
// if (typeof style.fill.pattern === 'string') {
// let fillPatternImg = cacheTxt.get(style.fill.pattern);
// if (!fillPatternImg) {
// fillPatternImg = (await Fetcher.texture(style.fill.pattern)).image;
// cacheTxt.set(fillPatternImg, style.fill.pattern);
// }
// ctx.fillStyle = ctx.createPattern(fillPatternImg, 'repeat');
// if (ctx.fillStyle.setTransform) {
// ctx.fillStyle.setTransform(matrix.scale(invCtxScale));
// } else {
// console.warn('Raster pattern isn\'t completely supported on Ie and edge');
// }
// }
// } else if (ctx.fillStyle !== style.fill.color) {
// ctx.fillStyle = style.fill.color;
// }
// if (style.fill.opacity !== ctx.globalAlpha) {
// ctx.globalAlpha = style.fill.opacity;
// }
// }

function strokeStyle(style, ctx, invCtxScale) {
if (ctx.strokeStyle !== style.stroke.color) {
ctx.strokeStyle = style.stroke.color;
Expand Down
104 changes: 59 additions & 45 deletions src/Core/Style.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,44 +79,60 @@ function readVectorProperty(property, options) {
}
}

function getImage(source, value) {
const target = document.createElement('img');

if (typeof source == 'string') {
if (value) {
const color = new Color(value);
Fetcher.texture(source, { crossOrigin: 'anonymous' })
.then((texture) => {
const img = texture.image;
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
async function loadImage(source) {
let promise = cacheStyle.get(source, 'null');
if (!promise) {
promise = Fetcher.texture(source, { crossOrigin: 'anonymous' });
cacheStyle.set(promise, source, 'null');
}
return (await promise).image;
}

async function loadImageData(source, value) {
let promise = cacheStyle.get(source, value);
if (!promise) {
promise = new Promise((resolve) => {
loadImage(source)
.then((img2) => {
canvas.width = img2.naturalWidth;
canvas.height = img2.naturalHeight;
const ctx = canvas.getContext('2d', { willReadFrequently: true });
ctx.drawImage(img, 0, 0);
const imgd = ctx.getImageData(0, 0, img.naturalWidth, img.naturalHeight);
ctx.drawImage(img2, 0, 0);
const imgd = ctx.getImageData(0, 0, img2.naturalWidth, img2.naturalHeight);
const pix = imgd.data;

const color = new Color(value);
const colorToChange = new Color('white');
for (let i = 0, n = pix.length; i < n; i += 4) {
const d = deltaE(pix.slice(i, i + 3), colorToChange) / 100;
pix[i] = (pix[i] * d + color.r * 255 * (1 - d));
pix[i + 1] = (pix[i + 1] * d + color.g * 255 * (1 - d));
pix[i + 2] = (pix[i + 2] * d + color.b * 255 * (1 - d));
}
ctx.putImageData(imgd, 0, 0);
target.src = canvas.toDataURL('image/png');
resolve(imgd);
});
} else {
target.src = source;
}
} else if (source && source[value]) {
const sprite = source[value];
});
cacheStyle.set(promise, source, value);
}
return promise;
}

async function getImage(source, value) {
if (value.sprites) {
// TO DO change VectorTileSource.sprites to use loadImage instead of loading at start.
const img = value.sprites.img || await loadImage(source);
const sprite = value.sprites[source];
canvas.width = sprite.width;
canvas.height = sprite.height;
canvas.getContext('2d').drawImage(source.img, sprite.x, sprite.y, sprite.width, sprite.height, 0, 0, sprite.width, sprite.height);
target.src = canvas.toDataURL('image/png');
canvas.getContext('2d').drawImage(img,
sprite.x, sprite.y, sprite.width, sprite.height,
0, 0, sprite.width, sprite.height);
} else if (value.color) {
const imgd = await loadImageData(source, value.color);
canvas.width = imgd.width;
canvas.height = imgd.height;
canvas.getContext('2d').putImageData(imgd, 0, 0);
}

return target;
return canvas.toDataURL('image/png');
}

const textAnchorPosition = {
Expand Down Expand Up @@ -674,7 +690,8 @@ class Style {
this.fill.color = color;
this.fill.opacity = readVectorProperty(layer.paint['fill-opacity']) || opacity;
if (layer.paint['fill-pattern'] && sprites) {
this.fill.pattern = getImage(sprites, layer.paint['fill-pattern']);
// TO DO homogenize with other
this.fill.pattern = getImage(layer.paint['fill-pattern'], { sprites });
}

if (layer.paint['fill-outline-color']) {
Expand Down Expand Up @@ -757,11 +774,7 @@ class Style {
async fillPolygon(canevasCtx, scaledMatrix) {
if (this.fill.pattern) {
if (typeof this.fill.pattern === 'string') {
let fillPatternImg = cacheStyle.get(this.fill.pattern);
if (!fillPatternImg) {
fillPatternImg = (await Fetcher.texture(this.fill.pattern)).image;
cacheStyle.set(fillPatternImg, this.fill.pattern);
}
const fillPatternImg = await loadImage(this.fill.pattern);
canevasCtx.fillStyle = canevasCtx.createPattern(fillPatternImg, 'repeat');
if (canevasCtx.fillStyle.setTransform) {
canevasCtx.fillStyle.setTransform(scaledMatrix);
Expand All @@ -785,7 +798,7 @@ class Style {
* @param {Element} domElement - The element to set the style to.
* @param {Object} sprites - the sprites.
*/
applyToHTML(domElement, sprites) {
async applyToHTML(domElement, sprites) {
domElement.style.padding = `${this.text.padding}px`;
domElement.style.maxWidth = `${this.text.wrap}em`;

Expand All @@ -811,19 +824,20 @@ class Style {
return;
}

const image = this.icon.source;
const size = this.icon.size;
const key = this.icon.key;
const color = this.icon.color;

let icon = cacheStyle.get(image || key, size, color);
if (!icon) {
if (key && sprites) {
icon = getImage(sprites, key);
} else {
icon = getImage(image, color);
}
cacheStyle.set(icon, image || key, size, color);
const icon = document.createElement('img');
const options = {
sprites,
color: this.icon.color,
};
// TO DO homogenize th VectorTileSource.icon: change key and source
if (sprites) {
const url = await getImage(this.icon.key, options);
icon.src = url;
} else if (this.icon.color) {
const url = await getImage(this.icon.source, options);
icon.src = url;
} else {
icon.src = this.icon.source;
}

const addIcon = () => {
Expand Down

0 comments on commit a7b9c74

Please sign in to comment.