Skip to content

Instantly share code, notes, and snippets.

@theaungmyatmoe
Last active September 5, 2023 08:59
Show Gist options
  • Save theaungmyatmoe/a9d87cd3b07b1f25ee1f5af282707d4b to your computer and use it in GitHub Desktop.
Save theaungmyatmoe/a9d87cd3b07b1f25ee1f5af282707d4b to your computer and use it in GitHub Desktop.
Canvas Scaling Factor calculation base on the image or the parent container

After carefully reviewing and conducting the provided code, I would like to suggest the following improvements:

  1. Code Refactoring and Canvas Responsiveness:

    Start from line 3308:

    answer_canvas.setAttribute(
      "style",
      "width: " + box_width * ratio + "%; height: " + box_height * ratio + "px; margin-top: 0.9%;"
    );
    
    answer_canvas_area.setAttribute(
      "style",
      "height: auto; width: 100%; background: whitesmoke;"
    );

    Instead, I propose the following suggestions:

    • Use Relative Units: Replace pixel values with percentage values based on the screen.
    • Initialize Canvas Size: Set the canvas size based on its container to ensure proper scaling.
    • Scale Coordinates: Scale the drawing points' x and y values based on the canvas size ratio.
    • Viewport Units: Consider using vw (viewport width) or vh (viewport height) for responsiveness.
    // Calculate scaling factors
    const originalImageWidth = 100; // original image width in pixels
    const originalImageHeight = 100; // original image height in pixels
    
    const canvas = document.getElementById("yourCanvasId"); // replace with your canvas element
    
    const canvasContainer = canvas.parentElement; // Get the container element that holds the canvas
    
    const ratio = canvasContainer.clientWidth / originalImageWidth;
    
    // Set canvas size
    canvas.style.width = canvasContainer.clientWidth + "px";
    canvas.style.height = originalImageHeight * ratio + "px";
    
    // Handle drawing points
    canvas.addEventListener("click", function (event) {
      const canvasRect = canvas.getBoundingClientRect();
      const x = (event.clientX - canvasRect.left) / ratio;
      const y = (event.clientY - canvasRect.top) / ratio;
    
      // Your drawing logic here using scaled x and y values
    });

Move Vector class from line 7285 to the new file. Move UI logic to the other file

For example, if the width of the image is 1200 pixels and the height is 800 pixels: Aspect Ratio = 1200 / 800 = 1.5

Alternatively, you can also calculate the aspect ratio by reducing the width and height to their simplest form. For example: Width = 1200 Height = 800 Find the greatest common divisor (GCD) of the width and height, which is 400 in this case. Reduced Width = 1200 / 400 = 3 Reduced Height = 800 / 400 = 2 So, the reduced aspect ratio is 3:2.

Determine Canvas Size and Orientation Calculate Base Point Size Adjust Point Size Based on Screen Size: use a percentage of the screen width or height to determine the point size. Consider Orientation Changes: When the orientation changes (from landscape to portrait or vice versa), re-evaluate the point size. You might have different point size adjustments for different orientations.

// Get a reference to the canvas element
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");

// Calculate base point size
const basePointSize = 5;

// Function to update point size based on screen size and orientation
function updatePointSize() {
  const screenWidth = window.innerWidth;
  const screenHeight = window.innerHeight;
  const orientation = screenWidth > screenHeight ? "landscape" : "portrait";

  // Calculate point size based on screen size and orientation
  let pointSize;
  if (orientation === "landscape") {
    pointSize = (screenWidth * 0.01) + basePointSize; // Adjust the coefficient as needed
  } else {
    pointSize = (screenHeight * 0.01) + basePointSize; // Adjust the coefficient as needed
  }

  // Clear canvas and redraw points
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = "black"; // Set the fill color
  ctx.beginPath();
  ctx.arc(50, 50, pointSize, 0, Math.PI * 2); // Example: drawing a point at (50, 50)
  ctx.fill();
}

// Initial call to set point size
updatePointSize();

// Listen for orientation change events and update point size
window.addEventListener("orientationchange", updatePointSize);

window.addEventListener("orientationchange", updatePointSize);

Canvas scaling factor

// Get a reference to the canvas element
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");

// Store original canvas size
const originalCanvasWidth = canvas.width;
const originalCanvasHeight = canvas.height;

// Define points with original coordinates
const points = [
  { x: 100, y: 100 },
  { x: 200, y: 200 },
  // Add more points as needed
];

// Function to update point positions on window resize
function updatePointPositions() {
  const newCanvasWidth = canvas.width;
  const newCanvasHeight = canvas.height;

  // Calculate scaling factors
  const xScale = newCanvasWidth / originalCanvasWidth;
  const yScale = newCanvasHeight / originalCanvasHeight;

  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Redraw points at updated positions
  ctx.fillStyle = "black"; // Set the fill color
  points.forEach(point => {
    const newX = point.x * xScale;
    const newY = point.y * yScale;

    // Draw the point at the updated coordinates
    ctx.beginPath();
    ctx.arc(newX, newY, 5, 0, Math.PI * 2); // Example: drawing a point
    ctx.fill();
  });
}

// Initial call to update point positions
updatePointPositions();

// Listen for window resize events and update point positions
window.addEventListener("resize", updatePointPositions);


// Get a reference to the canvas element
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");

// Store original canvas size
const originalCanvasWidth = canvas.width;
const originalCanvasHeight = canvas.height;

// Define points with original coordinates
const points = [
  { x: 100, y: 100 },
  { x: 200, y: 200 },
  // Add more points as needed
];

// Function to update point positions on window resize
function updatePointPositions() {
  const newCanvasWidth = canvas.width;
  const newCanvasHeight = canvas.height;

  // Calculate scaling factors
  const xScale = newCanvasWidth / originalCanvasWidth;
  const yScale = newCanvasHeight / originalCanvasHeight;

  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Redraw points at updated positions
  ctx.fillStyle = "black"; // Set the fill color
  points.forEach(point => {
    const newX = point.x * xScale;
    const newY = point.y * yScale;

    // Draw the point at the updated coordinates
    ctx.beginPath();
    ctx.arc(newX, newY, 5, 0, Math.PI * 2); // Example: drawing a point
    ctx.fill();
  });
}

// Initial call to update point positions
updatePointPositions();

// Listen for window resize events and update point positions
window.addEventListener("resize", updatePointPositions);

Scaling on the image

// Get a reference to the canvas element
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");

// Load the image onto the canvas
const image = new Image();
image.src = "path_to_your_image.jpg";

// Store original image size
let originalImageWidth, originalImageHeight;

// Define points with original coordinates
const points = [
  { x: 100, y: 100 },
  { x: 200, y: 200 },
  // Add more points as needed
];

// Function to update positions on window resize
function updatePositions() {
  // Get the current dimensions of the image
  originalImageWidth = image.width;
  originalImageHeight = image.height;

  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // Draw the image
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height);

  // Calculate scaling factors
  const xScale = canvas.width / originalImageWidth;
  const yScale = canvas.height / originalImageHeight;

  // Draw points at updated positions
  ctx.fillStyle = "black"; // Set the fill color
  points.forEach(point => {
    const newX = point.x * xScale;
    const newY = point.y * yScale;

    // Draw the point at the updated coordinates
    ctx.beginPath();
    ctx.arc(newX, newY, 5, 0, Math.PI * 2); // Example: drawing a point
    ctx.fill();
  });
}

// Wait for the image to load before updating positions
image.onload = updatePositions;

// Listen for window resize events and update positions
window.addEventListener("resize", update)

https://stackoverflow.com/questions/1664785/resize-html5-canvas-to-fit-window

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment