fix: 图标比例设置

This commit is contained in:
thinkinggis 2020-12-15 01:24:46 +08:00
parent 6448f71b4c
commit 8c79b8731e
8 changed files with 68 additions and 69 deletions

View File

@ -5,13 +5,16 @@ export type Listener = (...args: any[]) => void;
export interface IIconValue {
x: number;
y: number;
height?: number;
width?: number;
image?: HTMLImageElement;
}
export interface IIcon {
id: string;
image?: HTMLImageElement;
height: number;
width: number;
size: number;
height?: number;
width?: number;
}
export interface IICONMap {
[key: string]: IIconValue;

View File

@ -15,12 +15,17 @@ const MAX_CANVAS_WIDTH = 1024;
const imageSize = 64;
@injectable()
export default class IconService extends EventEmitter implements IIconService {
public canvasHeight: number;
public canvasHeight: number = 128;
private texture: ITexture2D;
private canvas: HTMLCanvasElement;
private iconData: IIcon[];
private iconMap: IICONMap;
private ctx: CanvasRenderingContext2D;
private loadingImageCount = 0;
public isLoading() {
return this.loadingImageCount === 0;
}
public init() {
this.iconData = [];
this.iconMap = {};
@ -30,13 +35,13 @@ export default class IconService extends EventEmitter implements IIconService {
public addImage(id: string, image: IImage) {
let imagedata = new Image();
this.loadingImageCount++;
if (this.hasImage(id)) {
throw new Error('Image Id already exists');
}
this.iconData.push({
id,
width: imageSize,
height: imageSize,
size: imageSize,
});
this.updateIconMap();
this.loadImage(image).then((img) => {
@ -46,13 +51,9 @@ export default class IconService extends EventEmitter implements IIconService {
});
if (iconImage) {
iconImage.image = imagedata;
iconImage.width = imagedata.width;
iconImage.height = imagedata.height;
}
// this.iconData.push({
// id,
// image: imagedata,
// width: imageSize,
// height: imageSize,
// });
this.update();
});
}
@ -89,16 +90,29 @@ export default class IconService extends EventEmitter implements IIconService {
private update() {
this.updateIconMap();
this.updateIconAtlas();
this.emit('imageUpdate');
this.loadingImageCount--;
if (this.loadingImageCount === 0) {
this.emit('imageUpdate');
}
}
private updateIconAtlas() {
this.canvas.width = MAX_CANVAS_WIDTH;
this.canvas.height = this.canvasHeight;
Object.keys(this.iconMap).forEach((item: string) => {
const { x, y, image } = this.iconMap[item];
const { x, y, image, width = 64, height = 64 } = this.iconMap[item];
const max = Math.max(width as number, height as number);
const ratio = max / imageSize;
const drawHeight = height / ratio;
const drawWidth = width / ratio;
if (image) {
this.ctx.drawImage(image, x, y, imageSize, imageSize);
this.ctx.drawImage(
image,
x + (imageSize - drawWidth) / 2,
y + (imageSize - drawHeight) / 2,
drawWidth,
drawHeight,
);
}
});
}

View File

@ -56,10 +56,10 @@ export function buildIconMaping(
const mapping: IICONMap = {};
for (const icon of icons) {
if (!mapping[icon.id]) {
const { height, width } = icon;
const { size } = icon;
// fill one row
if (xOffset + width + buffer > maxCanvasWidth) {
if (xOffset + size + buffer > maxCanvasWidth) {
buildRowMapping(mapping, columns, yOffset);
xOffset = 0;
@ -73,8 +73,8 @@ export function buildIconMaping(
xOffset,
});
xOffset = xOffset + width + buffer;
rowHeight = Math.max(rowHeight, height);
xOffset = xOffset + size + buffer;
rowHeight = Math.max(rowHeight, size);
}
}
@ -99,7 +99,14 @@ function buildRowMapping(
) {
for (const column of columns) {
const { icon, xOffset } = column;
mapping[icon.id] = { ...icon, x: xOffset, y: yOffset, image: icon.image };
mapping[icon.id] = {
...icon,
x: xOffset,
y: yOffset,
image: icon.image,
width: icon.width,
height: icon.height,
};
}
}
export function nextPowOfTwo(num: number) {

View File

@ -11,6 +11,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
public buildModels() {
const modelType = this.getModelType();
this.layerModel = new PointModels[modelType](this);
this.models = this.layerModel.initModels();
}
public rebuildModels() {

View File

@ -128,8 +128,9 @@ export default class ImageModel extends BaseModel {
}
this.texture = createTexture2D({
data: this.iconService.getCanvas(),
mag: gl.LINEAR,
min: gl.LINEAR,
mag: gl.NEAREST,
min: gl.NEAREST,
premultiplyAlpha: false,
width: 1024,
height: this.iconService.canvasHeight || 128,
});

View File

@ -12,19 +12,12 @@ varying float v_size;
#pragma include "picking"
void main(){
vec2 pos= v_uv / u_textSize + gl_PointCoord / u_textSize * 64.;
vec2 fragmentPosition = 2.0*gl_PointCoord - 1.0;
float distance = length(fragmentPosition);
float distanceSqrd = distance * distance;
float radius = 1.;
float r = 1.0 - smoothstep(radius-(radius*0.01),
radius+(radius*0.01),
distanceSqrd);
vec4 textureColor=texture2D(u_texture,pos);
if(all(lessThan(v_color, vec4(1.0+0.00001))) && all(greaterThan(v_color, vec4(1.0-0.00001))) || v_color==vec4(1.0)){
gl_FragColor= vec4(textureColor.xyz, textureColor.w);
}else {
gl_FragColor= step(0.01, textureColor.z) * v_color;
}
gl_FragColor.a =gl_FragColor.a * u_opacity;
gl_FragColor = filterColor(gl_FragColor);
vec4 textureColor=texture2D(u_texture,pos);
if(all(lessThan(v_color, vec4(1.0+0.00001))) && all(greaterThan(v_color, vec4(1.0-0.00001))) || v_color==vec4(1.0)){
gl_FragColor= textureColor;
}else {
gl_FragColor= step(0.01, textureColor.z) * v_color;
}
gl_FragColor.a =gl_FragColor.a * u_opacity;
gl_FragColor = filterColor(gl_FragColor);
}

View File

@ -15,25 +15,25 @@ export default class PointImage extends React.Component {
);
const scene = new Scene({
id: 'map',
map: new Mapbox({
map: new GaodeMap({
center: [121.4, 31.258134],
zoom: 15,
zoom: 5,
pitch: 0,
style: 'dark',
style: 'normal',
}),
});
this.scene = scene;
scene.addImage(
'00',
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Rq6tQ5b4_JMAAAAAAAAAAABkARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*g8cUQ7pPT9YAAAAAAAAAAAAAARQnAQ',
);
scene.addImage(
'01',
'https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*0D0SQ6AgkRMAAAAAAAAAAABkARQnAQ',
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*LTcXTLBM7kYAAAAAAAAAAAAAARQnAQ',
);
scene.addImage(
'02',
'https://gw.alipayobjects.com/zos/rmsportal/xZXhTxbglnuTmZEwqQrE.png',
'https://gw.alipayobjects.com/mdn/rms_fcd5b3/afts/img/A*g8cUQ7pPT9YAAAAAAAAAAAAAARQnAQ',
);
const i = 0;
const data = await response.json();
@ -41,7 +41,9 @@ export default class PointImage extends React.Component {
item.type = '00';
return item;
});
const imageLayer = new PointLayer()
const imageLayer = new PointLayer({
blend: 'normal',
})
.source(newData, {
parser: {
type: 'json',
@ -50,36 +52,14 @@ export default class PointImage extends React.Component {
},
})
.shape('type', (v: any) => {
console.log(v);
return v;
})
// .shape('triangle')
// .color('red')
.active(true)
.size(20)
.style({
offsets: [40, 40],
});
// imageLayer.on('click', (e) => {
// console.log(e);
// });
const imageLayer2 = new PointLayer()
.source(newData, {
parser: {
type: 'json',
x: 'longitude',
y: 'latitude',
},
})
.shape('type', (v: any) => {
return v;
})
// .shape('triangle')
// .color('red')
.active(true)
.size(10);
.active(false)
.size(20);
scene.addLayer(imageLayer);
scene.addLayer(imageLayer2);
}
public render() {
@ -92,7 +72,6 @@ export default class PointImage extends React.Component {
left: 0,
right: 0,
bottom: 0,
transform: 'scale(0.8)',
}}
/>
);

View File

@ -65,6 +65,7 @@ export default class TextLayerDemo extends React.Component {
const styleOptions = {
field: 'w',
strokeWidth: 0,
fontWeight: 500,
stroke: '#fff',
textAllowOverlap: false,
opacity: 1,