cotton123236 / zoomist

Zoomist is a library built with TypeScript that allows you to create zoom elements on website quickly and easily.
https://zoomist.vercel.app/
MIT License
104 stars 23 forks source link

Rotate Image? #18

Open MRoseBCC opened 1 year ago

MRoseBCC commented 1 year ago

I'm using zoomist with images that are being pulled in via an API, so they're of a set width, height, orientation, etc. It's working great but one thing that would be beneficial for my project is if the images were landscape as opposed to their original portrait. I have naturally tried doing this with CSS but Zoomist hates it because it's accounting for the image being portrait as opposed to landscape so it won't fit well in it's container and it sends the panning of the image off as well.

In short, is there any way to rotate an image in Zoomist which keeps the pan and zoom functionality intact?

cotton123236 commented 1 year ago

hey @MRoseBCC Because zoomist works based on css transform, it will clear your css transform when updates. I figure out a bad way can probably solve your problem. try this following code

const ele = document.querySelector('#my-zoomist')
new Zoomist(ele, {
  on: {
    ready() {
      const img = ele.querySelector('.zoomist-image')
      const wrapper = ele.querySelector('.zoomist-wrapper')
      const inner = document.querySelector('div')
      inner.classList.add('zoomist-inner')
      wrapper.append(inner)
      inner.append(img)
    }
  }
})

and use CSS position: absolute; top: 0; left: 0; width: 100%; height: 100%; transform: rotate(90deg); to .zoomist-inner

ESPRI-Paula commented 1 year ago

Hi @cotton123236 ,

I really like your work (thank you), but I had to add the options rotate on a short time (seems easier than to find another lib). If you plan to add it, maybe it can help : Adding rotate to options :

var DEFAULT_OPTIONS = {
    [...]
    // {Number} the degre of the rotation
    rotate: 0,
  };

In zoom(zoomRatio, pointer) {}

      const angle = options.rotate * (Math.PI / 180);
      const cos = Math.round(Math.cos(angle));
      const sin = Math.round(Math.sin(angle));

      const rotatedX =  transformX * cos + transformY * sin;
      const rotatedY =  -transformX * sin + transformY * cos;

      const newData = {
        width: newWidth,
        height: newHeight,
        left: newLeft,
        top: newTop
      };
      setObject(data.imageData, newData);
      setStyle(image, { ...newData,
        transform: `rotate(${options.rotate}deg) translate(${rotatedX}px, ${rotatedY}px)`
      });    

In dragMove

      const calcTransX = pageX - dragData.startX + dragData.transX;
      const calcTransY = pageY - dragData.startY + dragData.transY;

      const angle = options.rotate * (Math.PI / 180);

      const cos = Math.round(Math.cos(angle));
      const sin = Math.round(Math.sin(angle));

      const rotatedX =  calcTransX * cos + calcTransY * sin;
      const rotatedY =  -calcTransX * sin + calcTransY * cos;

      const transformX = roundToTwo(rotatedX);
      const transformY = roundToTwo(rotatedY);

      image.style.transform = `rotate(${options.rotate}deg)  translate(${transformX}px, ${transformY}px)`;

rotate(${options.rotate}deg) has to be added to every image.style.transform and setStyle change too...

It may needs to be perfected but I hope it helps someone.

cotton123236 commented 1 year ago

Hi @ESPRI-Paula ,

Thanks for your like! Actually, I'm working on new library Zoomist v2. I'll take your advice in v2.

R-W-C commented 1 year ago

Hello Cotton,

Any idea when v2 gonna be released?

And thank you for creating this great viewer 👍

cotton123236 commented 1 year ago

Hey, @R-W-C

The works on v2 has come to the end. I will try my best to release beta version this month!

trehoffman commented 1 year ago

I opened a Pull Request to integrate rotation functionality, but looks like you might already have implemented it for the next version!

cotton123236 commented 1 year ago

@trehoffman Thanks for your help! I already figured out a better solution to rotate image and implemented it for the next version. I'll publish it ASAP!

cotton123236 commented 11 months ago

Hi @R-W-C @trehoffman @ESPRI-Paula , Sorry for the wait! I rebuild Zoomist with TypeScript and already published on NPM just few days ago. You can checkout branch next. Now you can zoom any element not just image, so you can do anything you want inside .zoomist-image, includes rotate <img/>! I'll set v2 to default version after I build the documentation. If you have any question or suggestion for Zoomist version 2, please let me know! Thanks!!

trehoffman commented 11 months ago

@cotton123236 I tried out the new branch, but the rotate button is disabled initially. It becomes enabled when I zoom, but clicking it only resets the image back to inital zoom state and doesn't rotate the image.

cotton123236 commented 11 months ago

Hi @trehoffman , That is actually a reset button instead of a rotate button. The purpose of Zoomist is to "zoom" images or elements, so it may not be added a rotate button or methods.

But you can custom your own rotate button with version 2.X, for example:

<!-- html -->
<div class="zoomist-container">
  <div class="zoomist-wrapper">
    <div class="zoomist-image">
      <img class="my-image" src="..." />
    </div>
  </div>
</div>
<button class="rotate-btn" role="button">ROTATE</button>

<!-- js -->
<script>
let imageRotation = 0
const image = document.querySelector('.my-image')
const rotateBtn = document.querySelector('.rotate-btn')
rotateBtn.addEventListener('click', () => {
  imageRotation += (imageRotation >= 270 ? - 270 : 90)
  image.style.setProperty('transform', `rotate(${imageRotation}deg)`)
})
</script>

Hope this comment helps you!

azoyan commented 11 months ago

How to keep image dimensions after device rotation?

Vertical orientation: image

Expected: expected

Real: real