Circle is created with an incorrect opacity.
This usually results in much darker than desired opacity.
This is the circle shape creation code.
const geometry = new Shape().absarc(startPoint.x, startPoint.y, startPoint.distanceTo(endPoint), 0, Math.PI * 2, true)
const plane = new ShapeGeometry(geometry)
const shapeArr: number[] = []
geometry.getPoints().forEach(item => {
shapeArr.push(item.x)
shapeArr.push(item.y)
shapeArr.push(0)
})
const mesh = drawGeometry(plane, shapeArr, 5, hexToRgba(circleBorder), hexToRgba(circleFill))
This function converts hex to rgb.
export const hexToRgba = (str: string) => {
let r = 0;
let g = 0;
let b = 0;
let a = 255;
const result: string = str
.replace('#', '')
// Replace short notation with long notation
.replace(/^([0-F]{6})$/i, (match, hex) => {
var m = hex.match(/.{1,2}/g);
r = parseInt(m[0], 16);
g = parseInt(m[1], 16);
b = parseInt(m[2], 16);
a = 255;
return `${r}${g}${b}`;
})
// Convert RRGGBBAA to rgba(r, g, b, a) notation
.replace(/^([0-F]{8})$/i, (match, hex) => {
const value = Number.parseInt(hex, 16);
const bitsPerChannel = 8;
const bitMask = 0xff;
a = value & bitMask;
b = (value >> bitsPerChannel) & bitMask;
g = (value >> (bitsPerChannel * 2)) & bitMask;
r = (value >> (bitsPerChannel * 3)) & bitMask;
return `${r}${g}${b}${a}`;
});
return {
r: r,
g: g,
b: b,
a: a / 255,
originA: a,
};
};
export interface RGBA {
r: number;
g: number;
b: number;
a: number;
originA: number;
}
This function combines Shape and LineGeometry.
/**
*
* @param geometry
* @param points Line Points
* @param thickness Line Width
* @param edge Edge Color
* @param fill Fill Color
* @returns
*/
export function drawGeometry(
plane: BufferGeometry,
tmpLine: number[],
thickness: number,
edge: RGBA,
fill: RGBA,
) {
const line = new LineGeometry().setPositions(tmpLine)
const borderPosition = (line.attributes.position as BufferAttribute).array
const planePosition = (plane.attributes.position as BufferAttribute).array
const borderIndex = (line.index as BufferAttribute).array;
const planeIndex = (plane.index as BufferAttribute).array;
const edgeMaterial = new LineMaterial({
color: new Three.Color(`rgb(${edge.r},${edge.g},${edge.b})`).getHex(),
opacity: edge.a,
linewidth: thickness,
transparent: true,
resolution: new Three.Vector2(window.innerWidth, window.innerHeight),
});
const Material = new Three.MeshBasicMaterial({
color: new Three.Color(`rgb(${fill.r},${fill.g},${fill.b})`).getHex(),
transparent: true,
opacity: fill.a,
});
const mergeGeometry = new LineGeometry();
const mergePosition = new Float32Array(
borderPosition.length + planePosition.length,
);
const edgeUv = (line.attributes.uv as InstancedBufferAttribute).array;
const fillUv = (plane.attributes.uv as InstancedBufferAttribute).array;
const mergeUv = new Float32Array(edgeUv.length + fillUv.length);
const mergeIndex = new Uint16Array(borderIndex.length + planeIndex.length);
mergeGeometry.addGroup(0, borderIndex.length, 0);
mergeGeometry.addGroup(borderIndex.length, planeIndex.length, 1);
for (let i = 0; i < borderPosition.length; i += 3) {
mergePosition[i] = borderPosition[i];
mergePosition[i + 1] = borderPosition[i + 1];
mergePosition[i + 2] = borderPosition[i + 2];
}
for (let i = borderPosition.length; i < mergePosition.length; i += 3) {
mergePosition[i] = planePosition[i - borderPosition.length];
mergePosition[i + 1] = planePosition[i - borderPosition.length + 1];
mergePosition[i + 2] = planePosition[i - borderPosition.length + 2];
}
mergeGeometry.setAttribute(
'position',
new Three.BufferAttribute(mergePosition, 3),
);
for (let i = 0; i < borderIndex.length; i += 1) {
mergeIndex[i] = borderIndex[i];
}
for (let i = borderIndex.length; i < mergeIndex.length; i += 1) {
mergeIndex[i] =
planeIndex[i - borderIndex.length] + borderPosition.length / 3;
}
mergeGeometry.setIndex(new Three.BufferAttribute(mergeIndex, 1));
for (let i = 0; i < edgeUv.length; i += 2) {
mergeUv[i] = edgeUv[i];
mergeUv[i + 1] = edgeUv[i + 1];
}
for (let i = edgeUv.length; i < mergeUv.length; i += 2) {
mergeUv[i] = fillUv[i - edgeUv.length];
mergeUv[i + 1] = fillUv[i - edgeUv.length + 1];
}
mergeGeometry.setAttribute('uv', new Three.BufferAttribute(mergeUv, 2));
//mergeGeometry.setAttribute("instanceDistanceEnd", line.attributes.instanceDistanceEnd as BufferAttribute)
//mergeGeometry.setAttribute("instanceDistanceStart", line.attributes.instanceDistanceStart as BufferAttribute)
mergeGeometry.setAttribute("instanceEnd", line.attributes.instanceEnd as BufferAttribute)
mergeGeometry.setAttribute("instanceStart", line.attributes.instanceStart as BufferAttribute)
const mesh = new Three.Mesh(mergeGeometry, [edgeMaterial, Material]);
console.log(mesh)
return mesh;
}
I don’t know why it appears darker than the opacity I want.
The 151 patch doesn’t seem to be related at all. If you know the reason, please advise. Thank you.