mirror of https://gitee.com/antv-l7/antv-l7
refactor(text):升级文本渲染方法
This commit is contained in:
parent
691f2237d0
commit
33e0e56ef4
|
@ -1,246 +0,0 @@
|
|||
// const SDFCommonWordsKey = '_AMap_sdf_com_words';
|
||||
|
||||
// /**
|
||||
// * SDF 常用字获取/存储/check
|
||||
// *
|
||||
// */
|
||||
// const SDFCommonWords = {
|
||||
|
||||
// store() {
|
||||
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * 检查一个字符是否在常用字中
|
||||
// * @param {*} charcode 汉字
|
||||
// */
|
||||
// check(charcode) {
|
||||
// const range = this.range || [];
|
||||
// const info = this.info || {};
|
||||
|
||||
// if (typeof charcode !== 'number') {
|
||||
|
||||
// charcode = charcode.substr(0).charCodeAt(0);
|
||||
// }
|
||||
|
||||
// for (let i = 0; i < range.length; i++) {
|
||||
// const curRange = range[i];
|
||||
// const [ rangeStart, rangeEnd ] = curRange.split('-');
|
||||
|
||||
// if (charcode >= rangeStart && charcode <= rangeEnd) {
|
||||
|
||||
// const curInfo = info[curRange] && info[curRange].info || {};
|
||||
|
||||
// if (curInfo[charcode]) {
|
||||
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * 获取纹理和位置信息
|
||||
// * @param list
|
||||
// * @param cb
|
||||
// */
|
||||
// getImagesAndInfo(list, cb) {
|
||||
// const range = this.range;
|
||||
|
||||
|
||||
// },
|
||||
|
||||
// loadCanvas(url, range, done) {
|
||||
|
||||
// try {
|
||||
// const xhr = new XMLHttpRequest();
|
||||
// xhr.open('GET', url);
|
||||
|
||||
// // 直接用 blob 格式 load 图片文件,方便直接转换成 base64
|
||||
// // 转成 base64 便于存储
|
||||
// // 使用 canvas 转换 base64 容易有损
|
||||
// xhr.responseType = 'blob';
|
||||
// xhr.onerror = function() {
|
||||
// done({ code: 0 });
|
||||
// };
|
||||
|
||||
// xhr.onload = function() {
|
||||
|
||||
// if (xhr.status === 200) {
|
||||
// const reader = new FileReader();
|
||||
|
||||
// reader.onload = () => {
|
||||
|
||||
// done(reader.result, range);
|
||||
// };
|
||||
|
||||
// reader.readAsDataURL(xhr.response);
|
||||
// } else {
|
||||
// done({ code: 0 });
|
||||
// }
|
||||
// };
|
||||
|
||||
// xhr.send();
|
||||
// } catch (err) {
|
||||
|
||||
// done({ code: 0 });
|
||||
// }
|
||||
// },
|
||||
|
||||
// loadImages(urls = []) {
|
||||
// const deferred = $.Deferred();
|
||||
// const totalNumbers = urls.length;
|
||||
// const localInfo = this.info;
|
||||
// let loadPicNum = 0;
|
||||
|
||||
// for (let i = 0; i < urls.length; i++) {
|
||||
// const { url, range } = urls[i];
|
||||
|
||||
// this.loadCanvas(url, range, (base64, range) => {
|
||||
|
||||
// // image to base64
|
||||
// loadPicNum++;
|
||||
|
||||
// !localInfo[range] && (localInfo[range] = {});
|
||||
|
||||
// localInfo[range].pic = base64;
|
||||
|
||||
// this.info = localInfo;
|
||||
|
||||
// // todo: temp 暂时用 localstorage 存储,因为数据比较大,最好使用 indexDB
|
||||
// localStorage.setItem(SDFCommonWordsKey, JSON.stringify(localInfo));
|
||||
|
||||
// if (loadPicNum === totalNumbers) {
|
||||
|
||||
// deferred.resolve();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// return deferred;
|
||||
// },
|
||||
|
||||
// loadInfo(urls) {
|
||||
// const deferred = $.Deferred();
|
||||
// const totalNumbers = urls.length;
|
||||
// const localInfo = this.info;
|
||||
// let loadInfoNum = 0;
|
||||
|
||||
// for (let i = 0; i < urls.length; i++) {
|
||||
// const { url, range } = urls[i];
|
||||
|
||||
// $.ajax({
|
||||
// url,
|
||||
// dataType: 'json',
|
||||
// success: data => {
|
||||
// loadInfoNum++;
|
||||
|
||||
// !localInfo[range] && (localInfo[range] = {});
|
||||
|
||||
// localInfo[range].info = data;
|
||||
|
||||
// this.info = localInfo;
|
||||
|
||||
// localStorage.setItem(SDFCommonWordsKey, JSON.stringify(localInfo));
|
||||
|
||||
// if (loadInfoNum === totalNumbers) {
|
||||
|
||||
// deferred.resolve();
|
||||
// }
|
||||
// },
|
||||
// error: () => {
|
||||
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// return deferred;
|
||||
|
||||
// },
|
||||
|
||||
// getTotalAssets(info, cb) {
|
||||
// const { range = [], urlPrefix } = info;
|
||||
// const picUrls = [];
|
||||
// const infoUrls = [];
|
||||
|
||||
// this.range = range;
|
||||
|
||||
// for (let i = 0; i < range.length; i++) {
|
||||
// const curRange = range[i];
|
||||
// const baseUrl = urlPrefix + curRange;
|
||||
// const picUrl = baseUrl + '.png';
|
||||
// const infoUrl = baseUrl + '.json';
|
||||
|
||||
// picUrls.push({ range: curRange, url: picUrl });
|
||||
// infoUrls.push({ range: curRange, url: infoUrl });
|
||||
// }
|
||||
|
||||
// const imageDeferred = this.loadImages(picUrls);
|
||||
// const infoDeferred = this.loadInfo(infoUrls);
|
||||
|
||||
// $.when(imageDeferred, infoDeferred)
|
||||
// .then(() => {
|
||||
|
||||
// // all info load complete
|
||||
// // console.log("all info load complete", " -- ", 1);
|
||||
// cb && cb(this.info);
|
||||
// }, () => {
|
||||
|
||||
// // fail
|
||||
// });
|
||||
// },
|
||||
// // 获取数据
|
||||
// getData(cb) {
|
||||
|
||||
// if (!_.isEmpty(this.info)) {
|
||||
|
||||
// cb && cb(this.info);
|
||||
// } else {
|
||||
|
||||
// this.getRemoteData(cb);
|
||||
// }
|
||||
// },
|
||||
|
||||
// /**
|
||||
// * 从服务获取数据,什么时候强制去取一回数据?过期?
|
||||
// * @param cb
|
||||
// */
|
||||
// getRemoteData(cb) {
|
||||
// const self = this;
|
||||
|
||||
// $.ajax({
|
||||
// url: '/getcommonwords',
|
||||
// dataType: 'json',
|
||||
// success: data => {
|
||||
|
||||
// if (data.code == 1) {
|
||||
|
||||
// const info = data.data;
|
||||
|
||||
// self.getTotalAssets(info, cb);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
|
||||
// destroy() {
|
||||
|
||||
// },
|
||||
|
||||
// init() {
|
||||
// let info = localStorage.getItem(SDFCommonWordsKey);
|
||||
// this.range = [];
|
||||
// this.info = {};
|
||||
|
||||
// if (info) {
|
||||
// info = JSON.parse(info);
|
||||
// this.range = Object.keys(info);
|
||||
// this.info = info;
|
||||
// }
|
||||
|
||||
// this.info = info || {};
|
||||
// }
|
||||
// };
|
||||
// export default SDFCommonWords;
|
|
@ -1,4 +1,4 @@
|
|||
export default function TextBuffer2(layerData, fontAtlasManager) {
|
||||
export default function TextBuffer(layerData, fontAtlasManager) {
|
||||
const characterSet = [];
|
||||
layerData.forEach(element => {
|
||||
let text = element.shape || '';
|
||||
|
@ -12,35 +12,116 @@ export default function TextBuffer2(layerData, fontAtlasManager) {
|
|||
fontAtlasManager.setProps({
|
||||
characterSet
|
||||
});
|
||||
const attr = generateTextBuffer(layerData, fontAtlasManager);
|
||||
const attr = drawGlyph(layerData, fontAtlasManager);
|
||||
return attr;
|
||||
}
|
||||
function generateTextBuffer(layerData, fontAtlasManager) {
|
||||
function drawGlyph(layerData, fontAtlasManager) {
|
||||
const attributes = {
|
||||
vertices: [],
|
||||
pickingIds: [],
|
||||
textSizes: [], // 文字大小 // 长宽
|
||||
textOffsets: [], // 文字偏移量
|
||||
originPoints: [],
|
||||
textSizes: [],
|
||||
textOffsets: [],
|
||||
colors: [],
|
||||
textUv: [] // 纹理坐标
|
||||
textureElements: [],
|
||||
pickingIds: []
|
||||
};
|
||||
const { texture, fontAtlas, mapping } = fontAtlasManager;
|
||||
layerData.forEach(element => {
|
||||
const { texture, fontAtlas, mapping, scale } = fontAtlasManager;
|
||||
layerData.forEach(function(element) {
|
||||
const size = element.size;
|
||||
const pos = element.coordinates;
|
||||
let text = element.shape || '';
|
||||
const pen = { x: -text.length * size / 2 + size / 2, y: 0 };
|
||||
const pen = {
|
||||
x: (-text.length * size) / 2,
|
||||
y: 0
|
||||
};
|
||||
text = text.toString();
|
||||
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const metric = mapping[text[i]];
|
||||
const { x, y, width, height } = metric;
|
||||
const color = element.color;
|
||||
attributes.vertices.push(...pos);
|
||||
attributes.colors.push(...color);
|
||||
attributes.textUv.push(x, y, width, height);
|
||||
attributes.textOffsets.push(pen.x, pen.y);
|
||||
attributes.pickingIds.push(element.id);
|
||||
attributes.textSizes.push(size, size);
|
||||
const offsetX = pen.x;
|
||||
const offsetY = pen.y;
|
||||
attributes.pickingIds.push(
|
||||
element.id,
|
||||
element.id,
|
||||
element.id,
|
||||
element.id,
|
||||
element.id,
|
||||
element.id
|
||||
);
|
||||
attributes.textOffsets.push(
|
||||
// 文字在词语的偏移量
|
||||
offsetX,
|
||||
offsetY,
|
||||
offsetX,
|
||||
offsetY,
|
||||
offsetX,
|
||||
offsetY,
|
||||
offsetX,
|
||||
offsetY,
|
||||
offsetX,
|
||||
offsetY,
|
||||
offsetX,
|
||||
offsetY
|
||||
);
|
||||
attributes.originPoints.push(
|
||||
// 词语的经纬度坐标
|
||||
pos[0],
|
||||
pos[1],
|
||||
0,
|
||||
pos[0],
|
||||
pos[1],
|
||||
0,
|
||||
pos[0],
|
||||
pos[1],
|
||||
0,
|
||||
pos[0],
|
||||
pos[1],
|
||||
0,
|
||||
pos[0],
|
||||
pos[1],
|
||||
0,
|
||||
pos[0],
|
||||
pos[1],
|
||||
0
|
||||
);
|
||||
attributes.textSizes.push(
|
||||
size,
|
||||
size * scale,
|
||||
0,
|
||||
size * scale,
|
||||
0,
|
||||
0,
|
||||
size,
|
||||
size * scale,
|
||||
0,
|
||||
0,
|
||||
size,
|
||||
0
|
||||
);
|
||||
attributes.colors.push(
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color
|
||||
);
|
||||
attributes.textureElements.push(
|
||||
// 文字纹理坐标
|
||||
x + width,
|
||||
y,
|
||||
x,
|
||||
y,
|
||||
x,
|
||||
y + height,
|
||||
x + width,
|
||||
y,
|
||||
x,
|
||||
y + height,
|
||||
x + width,
|
||||
y + height
|
||||
);
|
||||
pen.x = pen.x + size;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import TinySDF from '@mapbox/tiny-sdf';
|
||||
import { buildMapping } from '../../../../util/font-util';
|
||||
import * as THREE from '../../../../core/three';
|
||||
import * as logImage from 'console-image';
|
||||
import LRUCache from './lru-cache';
|
||||
export const DEFAULT_CHAR_SET = getDefaultCharacterSet();
|
||||
export const DEFAULT_FONT_FAMILY = 'sans-serif';
|
||||
|
@ -147,8 +146,9 @@ export default class FontAtlasManager {
|
|||
|
||||
_updateTexture({ data: canvas }) {
|
||||
this._texture = new THREE.CanvasTexture(canvas);
|
||||
// this._texture.wrapS = THREE.ClampToEdgeWrapping;
|
||||
// this._texture.wrapT = THREE.ClampToEdgeWrapping;
|
||||
this._texture.wrapS = THREE.ClampToEdgeWrapping;
|
||||
this._texture.wrapT = THREE.ClampToEdgeWrapping;
|
||||
this._texture.minFilter = THREE.LinearFilter;
|
||||
this._texture.flipY = false;
|
||||
this._texture.needUpdate = true;
|
||||
}
|
||||
|
@ -207,7 +207,6 @@ export default class FontAtlasManager {
|
|||
ctx.fillText(char, mapping[char].x, mapping[char].y + fontSize * BASELINE_SCALE);
|
||||
}
|
||||
}
|
||||
logImage(canvas);
|
||||
return {
|
||||
xOffset,
|
||||
yOffset,
|
||||
|
|
|
@ -1,157 +0,0 @@
|
|||
|
||||
|
||||
import { getJSON } from '../../../util/ajax';
|
||||
import EventEmitter from 'wolfy87-eventemitter';
|
||||
import Global from '../../../global';
|
||||
// const Space = 1;
|
||||
const metrics = {
|
||||
buffer: 3,
|
||||
family: 'ios9',
|
||||
size: 24
|
||||
};
|
||||
export default function TextBuffer(layerData, style) {
|
||||
EventEmitter.call(this);
|
||||
const attributes = {
|
||||
originPoints: [],
|
||||
textSizes: [],
|
||||
textOffsets: [],
|
||||
colors: [],
|
||||
textureElements: []
|
||||
};
|
||||
const { textOffset = [ 0, 0 ] } = style;
|
||||
const chars = [];
|
||||
const textChars = {};
|
||||
layerData.forEach(element => {
|
||||
let text = element.shape || '';
|
||||
text = text.toString();
|
||||
for (let j = 0; j < text.length; j++) {
|
||||
const code = text.charCodeAt(j);
|
||||
textChars[text] = 0;
|
||||
if (chars.indexOf(code) === -1) {
|
||||
chars.push(text.charCodeAt(j));
|
||||
}
|
||||
}
|
||||
});
|
||||
loadTextInfo(chars, (chars, texture) => {
|
||||
layerData.forEach(element => {
|
||||
const size = element.size;
|
||||
const pos = layerData.coordinates;
|
||||
const pen = { x: textOffset[0], y: textOffset[1] };
|
||||
let text = element.shape || '';
|
||||
text = text.toString();
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const color = element.color;
|
||||
drawGlyph(chars, pos, text[i], pen, size, attributes.colors, attributes.textureElements, attributes.originPoints, attributes.textSizes, attributes.textOffsets, color);
|
||||
}
|
||||
this.emit('completed', { attributes, texture });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function loadTextInfo(chars, done) {
|
||||
getJSON({
|
||||
url: `${Global.sdfHomeUrl}/getsdfdata?chars=${chars.join('|')}`
|
||||
}, (e, info) => {
|
||||
loadTextTexture(info.url, texture => {
|
||||
done(info.info, texture);
|
||||
});
|
||||
});
|
||||
}
|
||||
function loadTextTexture(url, cb) {
|
||||
|
||||
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'anonymous';
|
||||
|
||||
img.onload = () => {
|
||||
const textTexture = this._creatTexture(img);
|
||||
cb(textTexture);
|
||||
};
|
||||
img.src = url;
|
||||
|
||||
}
|
||||
/**
|
||||
* 计算每个标注词语的位置
|
||||
* @param {*} chars 文本信息
|
||||
* @param {*} pos 文字三维空间坐标
|
||||
* @param {*} text 字符
|
||||
* @param {*} pen 字符在词语的偏移量
|
||||
* @param {*} size 字体大小
|
||||
* @param {*} colors 颜色
|
||||
* @param {*} textureElements 纹理坐标
|
||||
* @param {*} originPoints 初始位置数据
|
||||
* @param {*} textSizes 文字大小数组
|
||||
* @param {*} textOffsets 字体偏移量数据
|
||||
* @param {*} color 文字颜色
|
||||
*/
|
||||
function drawGlyph(chars, pos, text, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color) {
|
||||
const chr = text.charCodeAt(0);
|
||||
const metric = chars[chr];
|
||||
if (!metric) return;
|
||||
const scale = size / metrics.size;
|
||||
|
||||
let width = metric[0];
|
||||
let height = metric[1];
|
||||
const posX = metric[5];
|
||||
const posY = metric[6];
|
||||
const buffer = metrics.buffer;
|
||||
if (width > 0 && height > 0) {
|
||||
width += buffer * 2;
|
||||
height += buffer * 2;
|
||||
const originX = 0;
|
||||
const originY = 0;
|
||||
const offsetX = pen.x;
|
||||
const offsetY = pen.y;
|
||||
originPoints.push(
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
);
|
||||
const bx = 0;
|
||||
const by = metrics.size / 2 + buffer;
|
||||
textSizes.push(
|
||||
((bx - buffer + width) * scale), (height - by) * scale,
|
||||
((bx - buffer) * scale), (height - by) * scale,
|
||||
((bx - buffer) * scale), -by * scale,
|
||||
|
||||
((bx - buffer + width) * scale), (height - by) * scale,
|
||||
((bx - buffer) * scale), -by * scale,
|
||||
((bx - buffer + width) * scale), -by * scale,
|
||||
);
|
||||
|
||||
|
||||
textOffsets.push(
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
);
|
||||
|
||||
colors.push(
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
);
|
||||
textureElements.push(
|
||||
|
||||
posX + width, posY,
|
||||
posX, posY,
|
||||
posX, posY + height,
|
||||
|
||||
posX + width, posY,
|
||||
posX, posY + height,
|
||||
posX + width, posY + height
|
||||
);
|
||||
}
|
||||
pen.x = pen.x + size;
|
||||
|
||||
}
|
||||
|
|
@ -1,276 +0,0 @@
|
|||
import BufferBase from './bufferBase';
|
||||
import { getJSON } from '../../util/ajax';
|
||||
import * as THREE from '../../core/three';
|
||||
import TinySDF from '@mapbox/tiny-sdf';
|
||||
|
||||
import Global from '../../global';
|
||||
const Space = 1;
|
||||
export default class TextBuffer extends BufferBase {
|
||||
|
||||
geometryBuffer() {
|
||||
this.metrics = {
|
||||
buffer: 3,
|
||||
family: 'ios9',
|
||||
size: 24
|
||||
};
|
||||
const layerData = this.get('layerData');
|
||||
const { textOffset = [ 0, 0 ] } = this.get('style');
|
||||
const chars = [];
|
||||
const textChars = {};
|
||||
layerData.forEach(element => {
|
||||
let text = element.shape || '';
|
||||
text = text.toString();
|
||||
for (let j = 0; j < text.length; j++) {
|
||||
const code = text.charCodeAt(j);
|
||||
textChars[text] = 0;
|
||||
if (chars.indexOf(code) === -1) {
|
||||
chars.push(text.charCodeAt(j));
|
||||
}
|
||||
}
|
||||
});
|
||||
const sdfTexture = this._updateSdf(Object.keys(textChars).join(''));
|
||||
this.sdfTexture = sdfTexture;
|
||||
|
||||
this._loadTextInfo(chars);
|
||||
this.on('SourceLoaded', () => {
|
||||
const textureElements = [];
|
||||
const colors = [];
|
||||
const originPoints = [];
|
||||
const textSizes = [];
|
||||
const textOffsets = [];
|
||||
layerData.forEach(element => {
|
||||
const size = element.size;
|
||||
const pos = element.coordinates;
|
||||
// const pen = { x: pos[0] - dimensions.advance / 2, y: pos[1] };
|
||||
const pen = { x: textOffset[0], y: textOffset[1] };
|
||||
let text = element.shape || '';
|
||||
text = text.toString();
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
|
||||
|
||||
const color = element.color;
|
||||
this._drawGlyph(pos, text[i], pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color);
|
||||
}
|
||||
});
|
||||
this.bufferStruct.style = layerData;
|
||||
this.attributes = {
|
||||
originPoints,
|
||||
textSizes,
|
||||
textOffsets,
|
||||
colors,
|
||||
textureElements
|
||||
};
|
||||
this.emit('completed');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
_loadTextInfo(chars) {
|
||||
getJSON({
|
||||
url: `${Global.sdfHomeUrl}/getsdfdata?chars=${chars.join('|')}`
|
||||
}, (e, info) => {
|
||||
this.metrics.chars = info.info;
|
||||
|
||||
this._loadTextTexture(info.url);
|
||||
});
|
||||
}
|
||||
_loadTextTexture(url) {
|
||||
|
||||
|
||||
const img = new Image();
|
||||
img.crossOrigin = 'anonymous';
|
||||
|
||||
|
||||
img.onload = () => {
|
||||
this.bufferStruct.textTexture = this._creatTexture(this.sdfTexture.texure);
|
||||
this.emit('SourceLoaded');
|
||||
};
|
||||
img.src = url;
|
||||
|
||||
}
|
||||
/**
|
||||
* 计算每个标注词语的位置
|
||||
* @param {*} pos 文字三维空间坐标
|
||||
* @param {*} text 字符
|
||||
* @param {*} pen 字符在词语的偏移量
|
||||
* @param {*} size 字体大小
|
||||
* @param {*} colors 颜色
|
||||
* @param {*} textureElements 纹理坐标
|
||||
* @param {*} originPoints 初始位置数据
|
||||
* @param {*} textSizes 文字大小数组
|
||||
* @param {*} textOffsets 字体偏移量数据
|
||||
* @param {*} color 文字颜色
|
||||
*/
|
||||
_drawGlyph(pos, text, pen, size, colors, textureElements, originPoints, textSizes, textOffsets, color) {
|
||||
const metrics = this.metrics;
|
||||
const chr = text.charCodeAt(0);
|
||||
const metric = metrics.chars[chr];
|
||||
if (!metric) return;
|
||||
const info = this.sdfTexture.info;
|
||||
const { x, y } = info[text];
|
||||
const scale = size / metrics.size;
|
||||
|
||||
let width = 24; // metric[0];
|
||||
let height = 24;// metric[1];
|
||||
|
||||
// const horiBearingX = metric[2];
|
||||
// const horiBearingY = metric[3];
|
||||
|
||||
// const horiAdvance = metric[4];
|
||||
// const posX = metric[5];
|
||||
// const posY = metric[6];
|
||||
const posX = x;
|
||||
const posY = y;
|
||||
|
||||
const buffer = metrics.buffer;
|
||||
|
||||
if (width > 0 && height > 0) {
|
||||
width += buffer * 2;
|
||||
height += buffer * 2;
|
||||
|
||||
// Add a quad (= two triangles) per glyph.
|
||||
// const originX = (horiBearingX - buffer + width / 2) * scale;
|
||||
// const originY = -(height - horiBearingY) * scale;
|
||||
const originX = 0;
|
||||
const originY = 0;
|
||||
|
||||
// const offsetWidth = width / 2 * scale / (1.0 - horiBearingX * 1.5 / horiAdvance);
|
||||
// const offsetHeight = (horiAdvance / 2) * scale;
|
||||
|
||||
// const offsetWidth = width/2 * scale;
|
||||
// const offsetHeight = height / 2 * scale;
|
||||
// const offsetHeight = height * scale;
|
||||
|
||||
const offsetX = pen.x;
|
||||
const offsetY = pen.y;
|
||||
originPoints.push(
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
pos[0] + originX, pos[1] + originY, 0,
|
||||
);
|
||||
|
||||
// textSizes.push(
|
||||
// offsetWidth, offsetHeight,
|
||||
// -offsetWidth, offsetHeight,
|
||||
// -offsetWidth, -offsetHeight,
|
||||
// offsetWidth, offsetHeight,
|
||||
// -offsetWidth, -offsetHeight,
|
||||
// offsetWidth, -offsetHeight,
|
||||
// );
|
||||
const bx = 0;
|
||||
const by = metrics.size / 2 + buffer;
|
||||
textSizes.push(
|
||||
|
||||
|
||||
((bx - buffer + width) * scale), (height - by) * scale,
|
||||
((bx - buffer) * scale), (height - by) * scale,
|
||||
((bx - buffer) * scale), -by * scale,
|
||||
|
||||
((bx - buffer + width) * scale), (height - by) * scale,
|
||||
((bx - buffer) * scale), -by * scale,
|
||||
((bx - buffer + width) * scale), -by * scale,
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
||||
textOffsets.push(
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
offsetX, offsetY,
|
||||
);
|
||||
|
||||
colors.push(
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
...color,
|
||||
);
|
||||
textureElements.push(
|
||||
|
||||
posX + width, posY,
|
||||
posX, posY,
|
||||
posX, posY + height,
|
||||
|
||||
posX + width, posY,
|
||||
posX, posY + height,
|
||||
posX + width, posY + height
|
||||
);
|
||||
}
|
||||
|
||||
// pen.x = pen.x + (horiAdvance + Space) * scale;
|
||||
pen.x = pen.x + size * 1.8;
|
||||
|
||||
}
|
||||
|
||||
|
||||
_measureText(text, size) {
|
||||
const dimensions = {
|
||||
advance: 0
|
||||
};
|
||||
const metrics = this.metrics;
|
||||
const scale = size / metrics.size;
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const code = text.charCodeAt(i);
|
||||
const horiAdvance = metrics.chars[code][4];
|
||||
|
||||
dimensions.advance += (horiAdvance + Space) * scale;
|
||||
}
|
||||
|
||||
return dimensions;
|
||||
}
|
||||
_creatTexture(image) {
|
||||
this.bufferStruct.textSize = [ image.width, image.height ];
|
||||
const texture = new THREE.Texture(image);
|
||||
texture.minFilter = THREE.LinearFilter;
|
||||
texture.magFilter = THREE.ClampToEdgeWrapping;
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
}
|
||||
_updateSdf(chars) {
|
||||
const canvas = document.createElement('canvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
const sdfs = {};
|
||||
|
||||
|
||||
const fontSize = 24;
|
||||
const fontWeight = 100;
|
||||
const buffer = fontSize / 8;
|
||||
const radius = fontSize / 3;
|
||||
const canvasSize = Math.floor(Math.pow(chars.length, 0.5)) * (fontSize + buffer + radius);
|
||||
canvas.width = canvasSize;
|
||||
canvas.height = canvasSize;
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
const sdf = new TinySDF(fontSize, buffer, radius, null, null, fontWeight);
|
||||
for (let y = 0, i = 0; y + sdf.size <= canvas.height && i < chars.length; y += sdf.size) {
|
||||
for (let x = 0; x + sdf.size <= canvas.width && i < chars.length; x += sdf.size) {
|
||||
ctx.putImageData(this._makeRGBAImageData(ctx, sdf.draw(chars[i]), sdf.size), x, y);
|
||||
sdfs[chars[i]] = { x, y };
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return {
|
||||
info: sdfs,
|
||||
texure: canvas
|
||||
};
|
||||
}
|
||||
_makeRGBAImageData(ctx, alphaChannel, size) {
|
||||
const imageData = ctx.createImageData(size, size);
|
||||
const data = imageData.data;
|
||||
for (let i = 0; i < alphaChannel.length; i++) {
|
||||
data[4 * i + 0] = alphaChannel[i];
|
||||
data[4 * i + 1] = alphaChannel[i];
|
||||
data[4 * i + 2] = alphaChannel[i];
|
||||
data[4 * i + 3] = 255;
|
||||
}
|
||||
return imageData;
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
import { UniformSemantic, DataType, RenderState, BlendFunc } from '@ali/r3-base';
|
||||
import { Material, RenderTechnique } from '@ali/r3-material';
|
||||
import point_frag from '../shader/rainPass_frag.glsl';
|
||||
import point_vert from '../shader/rainPass_vert.glsl';
|
||||
export class RainPassMaterial extends Material {
|
||||
constructor(opt) {
|
||||
super(opt.name);
|
||||
|
||||
// this._generateTechnique();
|
||||
|
||||
for (const item in opt) {
|
||||
if (item.substr(0, 2) === 'u_') {
|
||||
this.setValue(item, opt[item]);
|
||||
}
|
||||
}
|
||||
}
|
||||
_generateTechnique() {
|
||||
|
||||
const VERT_SHADER = point_vert;
|
||||
// 片元着色器
|
||||
const FRAG_SHADER = point_frag;
|
||||
// Technique 配置信息
|
||||
const cfg = {
|
||||
attributes: {
|
||||
a_position: {
|
||||
name: 'a_position',
|
||||
semantic: 'POSITION',
|
||||
type: DataType.FLOAT_VEC3
|
||||
},
|
||||
a_uv: {
|
||||
name: 'a_uv',
|
||||
semantic: 'TEXCOORD_0',
|
||||
type: DataType.FLOAT_VEC2
|
||||
}
|
||||
},
|
||||
uniforms: {
|
||||
matModelViewProjection: {
|
||||
name: 'matModelViewProjection',
|
||||
semantic: UniformSemantic.MODELVIEWPROJECTION,
|
||||
type: DataType.FLOAT_MAT4
|
||||
},
|
||||
u_texture: {
|
||||
name: 'u_texture',
|
||||
type: DataType.SAMPLER_2D
|
||||
},
|
||||
u_colorTexture: {
|
||||
name: 'u_colorTexture',
|
||||
type: DataType.SAMPLER_2D
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// 创建 Technique
|
||||
const tech = new RenderTechnique('PointMaterial');
|
||||
tech.states = {
|
||||
disable: [ RenderState.CULL_FACE, RenderState.DEPTH_TEST ],
|
||||
enable: [ RenderState.BLEND ],
|
||||
functions: { blendFunc: [ BlendFunc.SRC_ALPHA, BlendFunc.ONE_MINUS_SRC_ALPHA ] }
|
||||
};
|
||||
tech.isValid = true;
|
||||
tech.uniforms = cfg.uniforms;
|
||||
tech.attributes = cfg.attributes;
|
||||
tech.vertexShader = VERT_SHADER;
|
||||
tech.fragmentShader = FRAG_SHADER;
|
||||
tech.customMacros = this._macros;
|
||||
this._technique = tech;
|
||||
}
|
||||
|
||||
prepareDrawing(camera, component, primitive) {
|
||||
|
||||
this.getAttributeDefines(camera, component, primitive);
|
||||
if (!this._technique) { this._generateTechnique(); }
|
||||
super.prepareDrawing(camera, component, primitive);
|
||||
|
||||
}
|
||||
getAttributeDefines(camera, component, primitive) {
|
||||
this._macros = [];
|
||||
if (!primitive) return this._macros;
|
||||
|
||||
const attribNames = Object.keys(primitive.vertexAttributes);
|
||||
if (attribNames.indexOf('SHAPE') !== -1) {
|
||||
this._macros.push('SHAPE');
|
||||
}
|
||||
if (attribNames.indexOf('TEXCOORD_0') !== -1) {
|
||||
this._macros.push('TEXCOORD_0');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -31,7 +31,7 @@ import heatmap_intensity_vert from '../shader/heatmap_intensity_vert.glsl';
|
|||
|
||||
// 文本
|
||||
import text_frag from '../shader/text_frag.glsl';
|
||||
import text_vert from '../shader/text_vert2.glsl';
|
||||
import text_vert from '../shader/text_vert.glsl';
|
||||
|
||||
// 图像
|
||||
import image_vert from '../shader/image_vert.glsl';
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
precision mediump float;
|
||||
uniform sampler2D u_texture;
|
||||
varying float v_time;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
|
||||
void main() {
|
||||
vec4 color = texture2D(u_texture, v_texCoord);
|
||||
if(color.w ==0.)
|
||||
discard;
|
||||
gl_FragColor = texture2D(u_texture, v_texCoord);
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
precision highp float;
|
||||
attribute vec3 a_position;
|
||||
attribute vec2 a_uv;
|
||||
uniform mat4 matModelViewProjection;
|
||||
uniform float u_time;
|
||||
// varying float v_time;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
varying vec4 v_color;
|
||||
float random (in float x) {
|
||||
return fract(sin(x)*1e4);
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_texCoord = a_uv;
|
||||
float z = a_position.z;
|
||||
z = z - mod(u_time * 1000000.0, 5000000.0);
|
||||
gl_Position = matModelViewProjection * vec4(vec2(a_position), z, 1.0);
|
||||
gl_PointSize = 3.0;
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
precision mediump float;
|
||||
uniform sampler2D u_texture;
|
||||
uniform sampler2D u_colorTexture;
|
||||
uniform vec2 u_wind_min;
|
||||
uniform vec2 u_wind_max;
|
||||
varying float v_time;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
void main() {
|
||||
vec2 velocity = mix(u_wind_min, u_wind_max, texture2D(u_texture, v_texCoord).rg);
|
||||
float speed_t = length(velocity) / length(u_wind_max);
|
||||
vec2 ramp_pos = vec2(
|
||||
fract(16.0 * speed_t),
|
||||
floor(16.0 * speed_t) / 16.0);
|
||||
gl_FragColor = texture2D(u_colorTexture, ramp_pos);
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
precision highp float;
|
||||
attribute vec3 a_position;
|
||||
attribute vec2 a_uv;
|
||||
uniform mat4 matModelViewProjection;
|
||||
uniform float u_time;
|
||||
// varying float v_time;
|
||||
|
||||
varying vec2 v_texCoord;
|
||||
varying vec4 v_color;
|
||||
float random (in float x) {
|
||||
return fract(sin(x)*1e4);
|
||||
}
|
||||
|
||||
void main() {
|
||||
v_texCoord = a_uv;
|
||||
gl_Position = matModelViewProjection * vec4(a_position, 1.0);
|
||||
gl_PointSize = 1.0;
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
precision mediump float;
|
||||
attribute vec2 a_txtsize;
|
||||
attribute vec2 a_txtOffsets;
|
||||
uniform float u_opacity;
|
||||
attribute vec4 a_color;
|
||||
uniform mat4 u_model;
|
||||
uniform mat4 u_view;
|
||||
uniform mat4 u_scale;
|
||||
uniform vec2 u_textSize;
|
||||
uniform vec2 u_textTextureSize;// 纹理大小
|
||||
uniform vec2 u_glSize;
|
||||
varying vec2 v_texcoord;
|
||||
varying vec4 v_color;
|
||||
|
@ -15,16 +13,12 @@ uniform vec4 u_activeColor;
|
|||
void main(){
|
||||
mat4 matModelViewProjection=projectionMatrix*modelViewMatrix;
|
||||
vec4 cur_position=matModelViewProjection*vec4(position.xy,0,1);
|
||||
gl_Position=cur_position/cur_position.w+vec4((a_txtOffsets/2.+a_txtsize)/u_glSize*2.,0.,0.);
|
||||
//+vec4(abs(a_txtsize.x)/u_glSize.x *2.0, -abs(a_txtsize.y)/u_glSize.y* 2.0, 0.0, 0.0);
|
||||
highp float camera_to_anchor_distance=gl_Position.w;
|
||||
// highp float perspective_ratio = clamp(
|
||||
// 0.5 + 0.5 * distance_ratio,
|
||||
// 0.0, // Prevents oversized near-field symbols in pitched/overzoomed tiles
|
||||
// 4.0);
|
||||
v_color=a_color;
|
||||
v_color.a=v_color.a*camera_to_anchor_distance;
|
||||
v_texcoord=uv/u_textSize;
|
||||
worldId = id_toPickColor(pickingId);
|
||||
gl_Position=cur_position/cur_position.w+vec4((a_txtOffsets+a_txtsize)/u_glSize*2.,0.,0.);
|
||||
v_color=vec4(a_color.rgb,a_color.a*u_opacity);
|
||||
if(pickingId==u_activeId){
|
||||
v_color=u_activeColor;
|
||||
}
|
||||
v_texcoord=uv/u_textTextureSize;
|
||||
worldId=id_toPickColor(pickingId);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
precision mediump float;
|
||||
attribute vec3 a_position;
|
||||
attribute vec4 textUv;
|
||||
attribute vec2 a_textSize;
|
||||
attribute vec2 a_textOffset;// 文本偏移
|
||||
attribute vec4 a_color;
|
||||
uniform mat4 u_model;
|
||||
uniform float u_opacity;
|
||||
uniform mat4 u_view;
|
||||
uniform mat4 u_scale;
|
||||
uniform vec2 u_textTextureSize;// 纹理大小
|
||||
uniform float u_activeId;
|
||||
uniform vec4 u_activeColor;
|
||||
uniform vec2 u_glSize;// 画布大小
|
||||
varying vec2 v_texcoord;
|
||||
varying vec4 v_color;
|
||||
|
||||
void main(){
|
||||
mat4 matModelViewProjection=projectionMatrix*modelViewMatrix;
|
||||
vec4 cur_position=matModelViewProjection*vec4(a_position.xy,0,1);
|
||||
gl_Position=cur_position / cur_position.w+ vec4(a_textSize*position.xy/u_glSize, 0., 0.)+vec4(a_textOffset/u_glSize * 2.0,0,0);
|
||||
// v_color=vec4(a_color.rgb,a_color.a*u_opacity);
|
||||
// if(pickingId == u_activeId) {
|
||||
// v_color = u_activeColor;
|
||||
// }
|
||||
v_color = a_color;
|
||||
v_texcoord=(textUv.xy + vec2(uv.x,1.-uv.y) * textUv.zw)/u_textTextureSize;
|
||||
worldId = id_toPickColor(pickingId);
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
attribute vec3 a_position;
|
||||
|
||||
varying vec2 v_tex_pos;
|
||||
|
||||
void main() {
|
||||
v_tex_pos = vec2(a_position);
|
||||
gl_Position = vec4(1.0 - 2.0 * vec2(a_position), 0, 1);
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
precision mediump float;
|
||||
|
||||
uniform sampler2D u_screen;
|
||||
uniform float u_opacity;
|
||||
|
||||
varying vec2 v_tex_pos;
|
||||
|
||||
void main() {
|
||||
vec4 color = texture2D(u_screen, 1.0 - v_tex_pos);
|
||||
// a hack to guarantee opacity fade out even with a value close to 1.0
|
||||
gl_FragColor = vec4(1.0,0.,0.,1.0);
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import Layer from '../core/layer';
|
||||
import * as drawPoint from '../layer/render/point';
|
||||
import TextBuffer2 from '../geom/buffer/point/text';
|
||||
import TextBuffer from '../geom/buffer/point/text';
|
||||
import DrawText from './render/point/drawText';
|
||||
import Global from '../global';
|
||||
// import PointBuffer from '../geom/buffer/point';
|
||||
|
@ -14,26 +14,22 @@ const { pointShape } = Global;
|
|||
*/
|
||||
|
||||
export default class PointLayer extends Layer {
|
||||
|
||||
render() {
|
||||
this.type = 'point';
|
||||
|
||||
this.init();
|
||||
if (!this._hasRender) {
|
||||
this._prepareRender(this.shapeType);
|
||||
this._hasRender = true;
|
||||
} else {
|
||||
this._initAttrs();
|
||||
(this._needUpdateFilter || this._needUpdateColor) ? this._updateFilter() : null;
|
||||
this._needUpdateFilter || this._needUpdateColor
|
||||
? this._updateFilter()
|
||||
: null;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
_prepareRender() {
|
||||
const { stroke, fill } = this.get('styleOptions');
|
||||
if (this.shapeType === 'text') { // 绘制文本图层
|
||||
this._textPoint();
|
||||
return;
|
||||
}
|
||||
const style = this.get('styleOptions');
|
||||
const activeOption = this.get('activedOptions');
|
||||
const config = {
|
||||
|
@ -41,36 +37,55 @@ export default class PointLayer extends Layer {
|
|||
activeColor: activeOption.fill
|
||||
};
|
||||
const pointShapeType = this._getShape();
|
||||
|
||||
switch (pointShapeType) {
|
||||
case 'fill' :// 填充图形
|
||||
{
|
||||
if (fill !== 'none') { // 是否填充
|
||||
case 'fill': { // 填充图形
|
||||
if (fill !== 'none') {
|
||||
// 是否填充
|
||||
const attributes = PointBuffer.FillBuffer(this.layerData, style);
|
||||
const meshfill = drawPoint.DrawFill(attributes, config);
|
||||
this.add(meshfill);
|
||||
}
|
||||
if (stroke !== 'none') { // 是否绘制边界
|
||||
if (stroke !== 'none') {
|
||||
// 是否绘制边界
|
||||
const lineAttribute = PointBuffer.StrokeBuffer(this.layerData, style);
|
||||
const meshStroke = drawPoint.DrawStroke(lineAttribute, config);
|
||||
this.add(meshStroke, 'line');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'image':// 绘制图片标注
|
||||
{
|
||||
const imageAttribute = PointBuffer.ImageBuffer(this.layerData, { imagePos: this.scene.image.imagePos });
|
||||
const imageMesh = drawPoint.DrawImage(imageAttribute, { ...style, texture: this.scene.image.texture });
|
||||
case 'image': { // 绘制图片标注
|
||||
const imageAttribute = PointBuffer.ImageBuffer(this.layerData, {
|
||||
imagePos: this.scene.image.imagePos
|
||||
});
|
||||
const imageMesh = drawPoint.DrawImage(imageAttribute, {
|
||||
...style,
|
||||
texture: this.scene.image.texture
|
||||
});
|
||||
this.add(imageMesh);
|
||||
break;
|
||||
}
|
||||
case 'normal' : // 原生点
|
||||
{
|
||||
case 'normal': { // 原生点
|
||||
const normalAttribute = PointBuffer.NormalBuffer(this.layerData, style);
|
||||
const normalPointMesh = drawPoint.DrawNormal(normalAttribute, config);
|
||||
this.add(normalPointMesh);
|
||||
break;
|
||||
}
|
||||
case 'text': { // 原生点
|
||||
const { width, height } = this.scene.getSize();
|
||||
const textCfg = {
|
||||
...style,
|
||||
width,
|
||||
height,
|
||||
activeColor: activeOption.fill
|
||||
};
|
||||
const buffer = new TextBuffer(
|
||||
this.layerData,
|
||||
this.scene.fontAtlasManager
|
||||
);
|
||||
const mesh = new DrawText(buffer, textCfg);
|
||||
this.add(mesh);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -87,32 +102,14 @@ export default class PointLayer extends Layer {
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (pointShape['2d'].indexOf(shape) !== -1 || pointShape['3d'].indexOf(shape) !== -1) {
|
||||
if (
|
||||
pointShape['2d'].indexOf(shape) !== -1 ||
|
||||
pointShape['3d'].indexOf(shape) !== -1
|
||||
) {
|
||||
return 'fill';
|
||||
} else if (shape === 'text') {
|
||||
return 'text';
|
||||
} else if (this.scene.image.imagesIds.indexOf(shape) !== -1) {
|
||||
return 'image';
|
||||
}
|
||||
return 'normal';
|
||||
|
||||
|
||||
return 'text';
|
||||
}
|
||||
_textPoint() {
|
||||
const styleOptions = this.get('styleOptions');
|
||||
const activeOption = this.get('activedOptions');
|
||||
const { width, height } = this.scene.getSize();
|
||||
const textCfg = {
|
||||
...styleOptions,
|
||||
width,
|
||||
height,
|
||||
activeColor: activeOption.fill
|
||||
};
|
||||
const buffer2 = new TextBuffer2(this.layerData, this.scene.fontAtlasManager);
|
||||
const testMesh = new DrawText(buffer2, textCfg);
|
||||
this.add(testMesh);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,48 @@
|
|||
import * as THREE from '../../../core/three';
|
||||
import TextMaterial from '../../../geom/material/textMaterial';
|
||||
|
||||
export default function DrawText(attributes, style) {
|
||||
const instancedGeometry = new THREE.InstancedBufferGeometry();
|
||||
// instancedGeometry.copy(new buildTextbufferGeometry());
|
||||
instancedGeometry.copy(new THREE.PlaneBufferGeometry(2, 2));
|
||||
const geometry = new THREE.BufferGeometry();
|
||||
geometry.addAttribute(
|
||||
'position',
|
||||
new THREE.Float32BufferAttribute(attributes.originPoints, 3)
|
||||
);
|
||||
geometry.addAttribute(
|
||||
'uv',
|
||||
new THREE.Float32BufferAttribute(attributes.textureElements, 2)
|
||||
);
|
||||
geometry.addAttribute(
|
||||
'a_txtsize',
|
||||
new THREE.Float32BufferAttribute(attributes.textSizes, 2)
|
||||
);
|
||||
geometry.addAttribute(
|
||||
'a_txtOffsets',
|
||||
new THREE.Float32BufferAttribute(attributes.textOffsets, 2)
|
||||
);
|
||||
geometry.addAttribute(
|
||||
'a_color',
|
||||
new THREE.Float32BufferAttribute(attributes.colors, 4)
|
||||
);
|
||||
geometry.addAttribute(
|
||||
'pickingId',
|
||||
new THREE.Float32BufferAttribute(attributes.pickingIds, 1)
|
||||
);
|
||||
const { strokeWidth, width, stroke, height, opacity, activeColor } = style;
|
||||
instancedGeometry.addAttribute('a_position', new THREE.InstancedBufferAttribute(new Float32Array(attributes.vertices), 3));
|
||||
instancedGeometry.addAttribute('a_textSize', new THREE.InstancedBufferAttribute(new Float32Array(attributes.textSizes), 2));
|
||||
instancedGeometry.addAttribute('a_textOffset', new THREE.InstancedBufferAttribute(new Float32Array(attributes.textOffsets), 2));
|
||||
instancedGeometry.addAttribute('a_color', new THREE.InstancedBufferAttribute(new Float32Array(attributes.colors), 4));
|
||||
instancedGeometry.addAttribute('a_size', new THREE.InstancedBufferAttribute(new Float32Array(attributes.textSizes), 1));
|
||||
instancedGeometry.addAttribute('pickingId', new THREE.InstancedBufferAttribute(new Float32Array(attributes.pickingIds), 1));
|
||||
instancedGeometry.addAttribute('textUv', new THREE.InstancedBufferAttribute(new Float32Array(attributes.textUv), 4));
|
||||
const material = new TextMaterial({
|
||||
name: this.layerId,
|
||||
u_texture: attributes.texture,
|
||||
u_strokeWidth: strokeWidth,
|
||||
u_stroke: stroke,
|
||||
u_textTextureSize: [ attributes.fontAtlas.width, attributes.fontAtlas.height ],
|
||||
u_gamma: 0.1,
|
||||
u_buffer: 0.68,
|
||||
u_textTextureSize: [
|
||||
attributes.fontAtlas.width,
|
||||
attributes.fontAtlas.height
|
||||
],
|
||||
u_gamma: 0.2,
|
||||
u_buffer: 0.75,
|
||||
u_opacity: opacity,
|
||||
u_glSize: [ width, height ],
|
||||
u_activeColor: activeColor
|
||||
});
|
||||
const textMesh = new THREE.Mesh(instancedGeometry, material);
|
||||
return textMesh;
|
||||
const mesh = new THREE.Mesh(geometry, material);
|
||||
return mesh;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue