cione-comp-lib
Version:
`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`
181 lines (180 loc) • 5.44 kB
JavaScript
import "../../../echarts/lib/echarts.mjs";
import Texture2D from "../../../claygl/src/Texture2D.mjs";
import { init } from "../../../zrender/lib/zrender.mjs";
function ZRTextureAtlasSurfaceNode(zr, offsetX, offsetY, width, height, gap, dpr) {
this._zr = zr;
this._x = 0;
this._y = 0;
this._rowHeight = 0;
this.width = width;
this.height = height;
this.offsetX = offsetX;
this.offsetY = offsetY;
this.dpr = dpr;
this.gap = gap;
}
ZRTextureAtlasSurfaceNode.prototype = {
constructor: ZRTextureAtlasSurfaceNode,
clear: function() {
this._x = 0;
this._y = 0;
this._rowHeight = 0;
},
add: function(el, width, height) {
var rect = el.getBoundingRect();
if (width == null) {
width = rect.width;
}
if (height == null) {
height = rect.height;
}
width *= this.dpr;
height *= this.dpr;
this._fitElement(el, width, height);
var x = this._x;
var y = this._y;
var canvasWidth = this.width * this.dpr;
var canvasHeight = this.height * this.dpr;
var gap = this.gap;
if (x + width + gap > canvasWidth) {
x = this._x = 0;
y += this._rowHeight + gap;
this._y = y;
this._rowHeight = 0;
}
this._x += width + gap;
this._rowHeight = Math.max(this._rowHeight, height);
if (y + height + gap > canvasHeight) {
return null;
}
el.x += this.offsetX * this.dpr + x;
el.y += this.offsetY * this.dpr + y;
this._zr.add(el);
var coordsOffset = [this.offsetX / this.width, this.offsetY / this.height];
var coords = [[x / canvasWidth + coordsOffset[0], y / canvasHeight + coordsOffset[1]], [(x + width) / canvasWidth + coordsOffset[0], (y + height) / canvasHeight + coordsOffset[1]]];
return coords;
},
_fitElement: function(el, spriteWidth, spriteHeight) {
var rect = el.getBoundingRect();
var scaleX = spriteWidth / rect.width;
var scaleY = spriteHeight / rect.height;
el.x = -rect.x * scaleX;
el.y = -rect.y * scaleY;
el.scaleX = scaleX;
el.scaleY = scaleY;
el.update();
}
};
function ZRTextureAtlasSurface(opt) {
opt = opt || {};
opt.width = opt.width || 512;
opt.height = opt.height || 512;
opt.devicePixelRatio = opt.devicePixelRatio || 1;
opt.gap = opt.gap == null ? 2 : opt.gap;
var canvas = document.createElement("canvas");
canvas.width = opt.width * opt.devicePixelRatio;
canvas.height = opt.height * opt.devicePixelRatio;
this._canvas = canvas;
this._texture = new Texture2D({
image: canvas,
flipY: false
});
var self = this;
this._zr = init(canvas);
var oldRefreshImmediately = this._zr.refreshImmediately;
this._zr.refreshImmediately = function() {
oldRefreshImmediately.call(this);
self._texture.dirty();
self.onupdate && self.onupdate();
};
this._dpr = opt.devicePixelRatio;
this._coords = {};
this.onupdate = opt.onupdate;
this._gap = opt.gap;
this._textureAtlasNodes = [new ZRTextureAtlasSurfaceNode(this._zr, 0, 0, opt.width, opt.height, this._gap, this._dpr)];
this._nodeWidth = opt.width;
this._nodeHeight = opt.height;
this._currentNodeIdx = 0;
}
ZRTextureAtlasSurface.prototype = {
clear: function() {
for (var i = 0; i < this._textureAtlasNodes.length; i++) {
this._textureAtlasNodes[i].clear();
}
this._currentNodeIdx = 0;
this._zr.clear();
this._coords = {};
},
getWidth: function() {
return this._width;
},
getHeight: function() {
return this._height;
},
getTexture: function() {
return this._texture;
},
getDevicePixelRatio: function() {
return this._dpr;
},
getZr: function() {
return this._zr;
},
_getCurrentNode: function() {
return this._textureAtlasNodes[this._currentNodeIdx];
},
_expand: function() {
this._currentNodeIdx++;
if (this._textureAtlasNodes[this._currentNodeIdx]) {
return this._textureAtlasNodes[this._currentNodeIdx];
}
var maxSize = 4096 / this._dpr;
var textureAtlasNodes = this._textureAtlasNodes;
var nodeLen = textureAtlasNodes.length;
var offsetX = nodeLen * this._nodeWidth % maxSize;
var offsetY = Math.floor(nodeLen * this._nodeWidth / maxSize) * this._nodeHeight;
if (offsetY >= maxSize) {
return;
}
var width = (offsetX + this._nodeWidth) * this._dpr;
var height = (offsetY + this._nodeHeight) * this._dpr;
try {
this._zr.resize({
width,
height
});
} catch (e) {
this._canvas.width = width;
this._canvas.height = height;
}
var newNode = new ZRTextureAtlasSurfaceNode(this._zr, offsetX, offsetY, this._nodeWidth, this._nodeHeight, this._gap, this._dpr);
this._textureAtlasNodes.push(newNode);
return newNode;
},
add: function(el, width, height) {
if (this._coords[el.id]) {
return this._coords[el.id];
}
var coords = this._getCurrentNode().add(el, width, height);
if (!coords) {
var newNode = this._expand();
if (!newNode) {
return;
}
coords = newNode.add(el, width, height);
}
this._coords[el.id] = coords;
return coords;
},
getCoordsScale: function() {
var dpr = this._dpr;
return [this._nodeWidth / this._canvas.width * dpr, this._nodeHeight / this._canvas.height * dpr];
},
getCoords: function(id) {
return this._coords[id];
},
dispose: function() {
this._zr.dispose();
}
};
export { ZRTextureAtlasSurface as default };