You are unable to move the image to the top of the screen after zooming it with CSS

I implemented an image viewer component with interactive buttons for rotating, zooming in, and zooming out. Upon clicking a button, CSS transform is applied to the image.

However, I encountered an issue where, when zooming the image, it cannot be scrolled all the way to the top or left corner. I attempted to resolve this by adding transform-origin: top left; to the image, which fixed the zoom but caused rotation problems. How can I address this issue effectively?

The code for my implementation can be viewed here: https://codesandbox.io/s/delicate-star-eitj3s?file=/src/app/app.component.ts

EDIT: transform-origin: top left; successfully anchors the image to the top left corner, but I prefer to keep the image centered. Is there a way to fix the scrolling while maintaining the transformation origin at the center of the image?

Answer №1

To achieve zoom functionality, we can utilize height and width properties, while for rotation, we can make use of the transform property. By employing display:flex, we can ensure that the image remains centered on the screen. Check out this Demo

.image-viewer {
  display: flex;
  overflow: auto;
  width: 100%;
  height: 100%;
  border: 1px solid black;
}

.image-viewer img {
  margin:auto;
  width: 70%;
  height: 70%;
  transition: 0.3s;
}

.image-controls {
  width: 100%;
  text-align: center;
}

.image-controls button {
  transition: opacity 0.2s;
  opacity: 0.8;

  &:hover {
    opacity: 1;
  }
}

 private transformImage(): void {
    this.renderer.setStyle(
      this.image.nativeElement,
      "transform", `rotate(${this.angle}deg)`
    );
    this.renderer.setStyle(
      this.image.nativeElement,
      "width", `${100 * this.scale}%`
    );

    this.renderer.setStyle(
      this.image.nativeElement,
      "height", `${100 * this.scale}%`
    );
    /*this.image.nativeElement.scrollIntoView({
      behavior: "smooth",
      inline: "center",
      block: "start"
    });*/
  }

Answer №2

Indeed, the solution lies in using transform-origin: top left; Make sure to include a condition in your transformImage method as shown below and pass true or false accordingly

private transformImage(zoom): void {
this.renderer.setStyle(
  this.image.nativeElement,
  "transform",
  `rotate(${this.angle}deg) scale(${this.scale})`
);
if (zoom) {
  this.renderer.setStyle(
    this.image.nativeElement,
    "transform-origin",
    `top left`
  );
}

}

Explore more here

Answer №3

  updateRotation(): void {
    this.angle = this.angle + 90;
    this.transformElement("rotate");
  }

  private transformElement(transformType?: string): void {
    switch (transformType) {
      case "rotate":
        this.renderer.setStyle(
          this.element.nativeElement,
          "tranform-origin",
          "center center"
        );
        break;
      default:
        this.renderer.setStyle(
          this.element.nativeElement,
          "tranform-origin",
          "top left"
        );
        break;
    }

    this.renderer.setStyle(
      this.element.nativeElement,
      "transform",
      `rotate(${this.angle}deg) scale(${this.scale})`
    );
  }

View in codesandbox

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide to building a versatile dropdown component with Material UI or MUI in a React application

Is there a way to create a reusable dropdown component using Material UI or MUI in React? ...

Creating a new object in an empty array within my profile model (mongodb/mongoose) is simple. Just follow these steps to successfully add a

Presenting my Profile model: const ProfileSchema = new mongoose.Schema({ user: { type: mongoose.Schema.Types.ObjectId, ref: "User", }, company: String, website: String, location: String, status: { type: String, require ...

Is there a way for me to retrieve the header values of a table when I click on a cell?

I have a project where I am developing an application for booking rooms using Angular 2. One of the requirements is to be able to select a cell in a table and retrieve the values of the vertical and horizontal headers, such as "Room 1" and "9:00". The data ...

Notification within the conditional statement in React JS

I am working on validating phone number input within a React JS component using an if/else statement. If the user enters letters instead of numbers, I want to display a message saying "please check phone number". While I have been able to create a function ...

I am looking to modify various attributes linked to Rails

My Desire for Reality I am looking to update multiple related values in Rails by sending an update request from JavaScript. While creating data was seamless, I encountered difficulties when attempting to update it. #Code JavaScript* export const actions ...

Using AJAX and PHP to dynamically fill HTML drop-down menus

In order to populate the DropDown controls on my HTML Form dynamically, I have implemented a code that utilizes AJAX to make a call to a .php file. This .php file is responsible for filling the DropDown control with values from a single column. Throughout ...

Transferring information between two components in separate Angular 4 modules

Within my application, I have defined two modules named AppModule and UserModule. I am currently encountering an issue with data sharing between the AppComponent and the LoginComponent (which belongs to the UserModule). Below is a snippet of app.componen ...

The functionality of the code in a stack snippet may differ from that in a standalone HTML file

My code works perfectly on a stack snippet, but when I insert it into my server or an .html file, the refresh button shrinks! I have copied and pasted the code exactly as it is. Are there any specific snippet features that need to be added for it to work, ...

Superimpose two actionlinks and prioritize the one appearing above

I have implemented a menu similar to http://tympanus.net/Tutorials/SlideDownBoxMenu/. Below this menu, I have placed a webgrid. The issue I am facing is that when I hover over the menu, the slidedownbox with two action links pops up directly over the heade ...

Struggling to make image uploading function with Flask and JQuery

Utilize the code snippet below to submit forms and retrieve a modified version of text from Flask using AJAX and JQuery: from flask import Flask, render_template, request, jsonify app = Flask(__name__) @app.route('/') def index(): return re ...

Creating a file structure for JavaScript files in a Vue CLI project

When structuring my Vue CLI project, I'm struggling to find clear documentation on best practices. Currently, I have 10 modules each with an associated JS file. My approach so far involves organizing all the pages in my router.js within a views direc ...

Adjusting the content and style of a div element upon clicking, and restoring the original settings when clicked once more

There is a div with the id #increase-text-weight that displays the text "INCREASE TEXT WEIGHT". Upon clicking on it, the font weight of another div with the id #post-content should be changed to font-weight: 500 and the text inside #increase-text-weight s ...

Enhance Your Highcharts Funnel Presentation with Customized Labels

I am working on creating a guest return funnel that will display the number of guests and the percentage of prior visits for three categories of consumers: 1 Visit, 2 Visits, and 3+ Visits. $(function () { var dataEx = [ ['1 Vis ...

Issue: React child components cannot be objects (received: object with keys)

Hey everyone, I could really use some help figuring out what I'm doing wrong. Here is the error message I'm receiving: Error: Objects are not valid as a React child (found: object with keys {id, title, bodyText, icon}). If you meant to render a ...

What is the best way to decrease the border width of a chartjs doughnut chart?

I have a vision for my chart based on the mockup: However, here is what I've been able to achieve using chartjs so far: This is the code I'm working with: datasets: [ { data: [3, 8, 13, 9, 2], backgroun ...

Looking for a solution to troubleshoot issues with the updateServing function in JavaScript?

I am attempting to create a function that will calculate the portion sizes for the ingredients on my website. This function is located in the Recipe.js file and appears as follows: updateServings(type) { // Servings const newServings ...

Using inline styles for progress bars in React

Struggling to apply styling to the element labeled as "progress", I've tried multiple options but just can't seem to get it right. Any assistance or clues would be greatly welcomed! Here is the code snippet for the component: constructor(pr ...

What is preventing the factory from gaining access to the controller?

I have set up a notification factory and passed it inside the controller. However, when I try to assign the factory to the scope within the controller, I am encountering an error. alertsManager MyApp.factory('alertsManager', function() { ...

Learn how to make a mesh in Three Js React refract its environment while keeping the background hidden from the camera

I've been grappling with this challenge for quite some time now, so any assistance would be highly valued! My aim is to create the illusion of an image being confined within a mesh structure. My initial idea was to utilize a mesh with defined thickne ...

Get the large data file in sections

I ran a test script that looks like this: async function testDownload() { try{ var urls = ['https://localhost:54373/analyzer/test1','https://localhost:54373/analyzer/test2'] var fullFile = new Blob(); for (le ...