canvasthree.jshtml5-canvasshaderreact-three-fiber

Text shrinking problem on 3d model through shader and canvas


Hello currently i am developing a configurator but have some issues with texts. I am trying to render text on off canvas on 3d model through shaders but its acting weird. i can not set width and height like i want. canvas is always square on model and text inside shrinks

export const createTextCanvasTexture = (text, color, font) => {
  // Create a temporary canvas to calculate text dimensions
  const canvasGetDimensions = document.createElement("canvas");
  const ctxGetDimensions = canvasGetDimensions.getContext("2d");

  // Set an initial font size for measuring
  let fontSizeForDimensions = 256;
  ctxGetDimensions.font = `${fontSizeForDimensions}px ${font}`;

  // Measure the text width based on the font size
  const textWidth = ctxGetDimensions.measureText(text).width;

  // Calculate the canvas height based on the font size
  const textHeight = fontSizeForDimensions;

  // Create the actual canvas for the texture
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");

  // Set the canvas dimensions dynamically based on the text size
  canvas.width = textWidth;
  canvas.height = textHeight;

  // Reapply font and styles after setting canvas dimensions
  ctx.font = `${fontSizeForDimensions}px ${font}`;
  console.log("text", color);

  ctx.fillStyle = color; // Text color
  ctx.textAlign = "center"; // Center text horizontally
  ctx.textBaseline = "middle"; // Center text vertically
  ctx.fillText(text, canvas.width / 2, canvas.height / 2); // Draw the text in the center

  // Create and return the texture
  const canvasTexture = new THREE.CanvasTexture(canvas);
  canvasTexture.flipY = false;

  return canvasTexture;
};

and this is my fragment

export const createTextFragment = (index) => `
  // Translate UVs relative to the center
  vec2 translatedUVText${index} = (vUv - textPosition${index});
  translatedUVText${index} /= textScale${index}; // Scale it

  // Apply rotation
  float cosThetaText${index} = cos(textRotation${index});
  float sinThetaText${index} = sin(textRotation${index});
  mat2 rotationMatrixText${index} = mat2(
    cosThetaText${index}, -sinThetaText${index},
    sinThetaText${index}, cosThetaText${index}
  );
  vec2 rotatedUVText${index} = rotationMatrixText${index} * translatedUVText${index};

  // Sample the text texture if within bounds
  if (rotatedUVText${index}.x >= -0.5 && rotatedUVText${index}.x <= 0.5 &&
      rotatedUVText${index}.y >= -0.5 && rotatedUVText${index}.y <= 0.5) {
      vec4 textColor${index} = texture2D(textTexture${index}, rotatedUVText${index} + 0.5);
      baseColor = mix(baseColor, textColor${index}.rgb, textColor${index}.a * 0.8);
  }
`;

this is an example image.. with 3 letters its fine but if there is more letters word just shrinks example image


Solution

  • I solved the problem by creating a big canvas and small text in canvas and than i cut it with shaders.