Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
12 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
4
Question by AdhikS · Dec 05, 2016 at 07:33 AM · imagescrollviewzoompanpinch

Pinch and Zoom functionality on Canvas UI Images

I have a scroll view with the set of images.When I click on one of the images They enlarge to fit the full screen.Now i want to provide pinch,zoom and Pan functionality on every image.Just like google play store or android Gallery.

Comment
Add comment · Show 4
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image QuentinLG · Dec 06, 2016 at 12:25 AM 0
Share

If you want to zoom in you can play with the Field Of View of the camera (if it's using perspective). Have a look at this post:

http://answers.unity3d.com/questions/218347/how-do-i-make-the-camera-zoom-in-and-out-with-the.html

avatar image AdhikS · Dec 06, 2016 at 06:02 AM 0
Share

@QuentinLG thank you for your suggestion actually i want to implement this functionality without camera.but i will take a look at that post and try to seek for solution

avatar image Mazer83 AdhikS · Nov 02, 2017 at 03:20 PM 0
Share

Why wouldn't you use the camera? You can use an orthographic camera, and just change the orthographic size and position, or a perspective one, and just change the position in all 3 dimensions for pan/zoom.

If you really don't want to use the camera, you could use the transform.localscale of the image to enlarge/shrink it, as if you were zoo$$anonymous$$g, then just alter the transform.position or transform.localPosition to simulate panning.

avatar image misher · Aug 27, 2018 at 12:57 PM 0
Share

If you want something similar to gallery, there should be 2 different views: 1- for scrolling images (in loop or not) and 2 - for previewing a single image. Both could be ScrollViews. I remember doing something similar with a single image in a ScrollView, zoo$$anonymous$$g is simply changing scroll content scale and the pan is grant as default for scroll view :)

7 Replies

· Add your reply
  • Sort: 
avatar image
16

Answer by $$anonymous$$ · Nov 02, 2017 at 01:33 PM

here a solution

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.UI;

 public class PinchableScrollRect : ScrollRect
 {
     [SerializeField] float _minZoom = .1f;
     [SerializeField] float _maxZoom = 10;
     [SerializeField] float _zoomLerpSpeed = 10f;
     float _currentZoom = 1;
     bool _isPinching = false;
     float _startPinchDist;
     float _startPinchZoom;
     Vector2 _startPinchCenterPosition;
     Vector2 _startPinchScreenPosition;
     float _mouseWheelSensitivity = 1;
     bool blockPan = false;
 
     protected override void Awake()
     {
         Input.multiTouchEnabled = true;
     }
 
     private void Update()
     {
         if (Input.touchCount == 2)
         {
             if (!_isPinching)
             {
                 _isPinching = true;
                 OnPinchStart();
             }
             OnPinch();
         }
         else
         {
             _isPinching = false;
             if (Input.touchCount == 0)
             {
                 blockPan = false;
             }
         }
         //pc input
         float scrollWheelInput = Input.GetAxis("Mouse ScrollWheel");
         if (Mathf.Abs(scrollWheelInput) > float.Epsilon)
         {
             _currentZoom *= 1 + scrollWheelInput * _mouseWheelSensitivity;
             _currentZoom = Mathf.Clamp(_currentZoom, _minZoom, _maxZoom);
             _startPinchScreenPosition = (Vector2)Input.mousePosition;
             RectTransformUtility.ScreenPointToLocalPointInRectangle(content, _startPinchScreenPosition, null, out _startPinchCenterPosition);
             Vector2 pivotPosition = new Vector3(content.pivot.x * content.rect.size.x, content.pivot.y * content.rect.size.y);
             Vector2 posFromBottomLeft = pivotPosition + _startPinchCenterPosition;
             SetPivot(content, new Vector2(posFromBottomLeft.x / content.rect.width, posFromBottomLeft.y / content.rect.height));
         }
         //pc input end
 
         if (Mathf.Abs(content.localScale.x - _currentZoom) > 0.001f)
             content.localScale = Vector3.Lerp(content.localScale, Vector3.one * _currentZoom, _zoomLerpSpeed * Time.deltaTime);
     }
 
     protected override void SetContentAnchoredPosition(Vector2 position)
     {
         if (_isPinching || blockPan) return;
         base.SetContentAnchoredPosition(position);
     }
 
     void OnPinchStart()
     {
         Vector2 pos1 = Input.touches[0].position;
         Vector2 pos2 = Input.touches[1].position;
 
         _startPinchDist = Distance(pos1, pos2) * content.localScale.x;
         _startPinchZoom = _currentZoom;
         _startPinchScreenPosition = (pos1 + pos2) / 2;
         RectTransformUtility.ScreenPointToLocalPointInRectangle(content, _startPinchScreenPosition, null, out _startPinchCenterPosition);
 
         Vector2 pivotPosition = new Vector3(content.pivot.x * content.rect.size.x, content.pivot.y * content.rect.size.y);
         Vector2 posFromBottomLeft = pivotPosition + _startPinchCenterPosition;
 
         SetPivot(content, new Vector2(posFromBottomLeft.x / content.rect.width, posFromBottomLeft.y / content.rect.height));
         blockPan = true;
     }
 
     void OnPinch()
     {
         float currentPinchDist = Distance(Input.touches[0].position, Input.touches[1].position) * content.localScale.x;
         _currentZoom = (currentPinchDist / _startPinchDist) * _startPinchZoom;
         _currentZoom = Mathf.Clamp(_currentZoom, _minZoom, _maxZoom);
     }
 
     float Distance(Vector2 pos1, Vector2 pos2)
     {
         RectTransformUtility.ScreenPointToLocalPointInRectangle(content, pos1, null, out pos1);
         RectTransformUtility.ScreenPointToLocalPointInRectangle(content, pos2, null, out pos2);
         return Vector2.Distance(pos1, pos2);
     }
 
     static void SetPivot(RectTransform rectTransform, Vector2 pivot)
     {
         if (rectTransform == null) return;
 
         Vector2 size = rectTransform.rect.size;
         Vector2 deltaPivot = rectTransform.pivot - pivot;
         Vector3 deltaPosition = new Vector3(deltaPivot.x * size.x, deltaPivot.y * size.y) * rectTransform.localScale.x;
         rectTransform.pivot = pivot;
         rectTransform.localPosition -= deltaPosition;
     }
 }
 
Comment
Add comment · Show 11 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TonyVT · Apr 07, 2018 at 04:52 PM 0
Share

Thanks, I tried your solution and works like a charm. Just a little caveat: the inside content has not to have a stretch anchor, otherwise things start beco$$anonymous$$g strange. A center anchoring is perfectly ok.

avatar image hosseinrooholamini · Apr 22, 2018 at 05:30 AM 0
Share

Perfect solution! just use this script in 'Screen Space - Overlay' canvas

avatar image freedom667 · Jul 12, 2018 at 02:19 PM 0
Share

how can i change it to Screen Space - Camera

avatar image MrAlter freedom667 · Aug 27, 2018 at 12:29 PM 0
Share

Add link to camera to ScreenPointToLocalPointInRectangle

avatar image freedom667 MrAlter · Sep 24, 2018 at 08:54 AM 0
Share

Well, do you know how can we make it with double tap?

avatar image LilGames · May 23, 2019 at 01:22 AM 0
Share

This is a great solution and i have rewarded you, but would you $$anonymous$$d explaining what we need to assign to "Viewport" as well as the two scrollbars?

avatar image better_walk_away · Jun 16, 2019 at 08:17 PM 0
Share

Thank you so much! This really saves me a lot of time.

Show more comments
avatar image
0

Answer by SunnyChow · Dec 06, 2016 at 02:29 AM

you could use event trigger to collect all the touches. when there are 2 points, you use their distance this frame and last frame to calculate how much you should scale in this frame

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image AdhikS · Dec 06, 2016 at 06:26 AM 0
Share

I can zoom in by using touch input but the problem is panning and zoom out.Panning is not smooth enough and while zoo$$anonymous$$g out image snaps. here's my code take a look-:

pinch-zoom.txt (3.3 kB)
avatar image QuentinLG · Dec 06, 2016 at 09:06 AM 0
Share

To smoothen the movement I suggest using interpolation. Have a look at SmoothDamp and Lerp.

avatar image
0

Answer by Saad1990 · May 25, 2017 at 02:54 PM

first apply event listener on gameobject like image in this case, then attach c# script with this code

public GameObject image; public static bool flag = false;

 public void OnImageTapBeginClick(){
     if (flag) {
         flag = false;
         image.transform.localScale = new Vector2 (1f, 1f);
     } else {
         flag = true;
         image.transform.localScale = new Vector2 (2f,2f);
     }
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by MathiasBlank · Jun 04, 2018 at 08:30 PM

Very useful script NoGame0life :)

If you're using a "clamped movement" your scroll view could goes out of limits when you're zooming out. I think it could be a good idea to add a callback function when the pinching is finished to keeps the scroll view into limits.

Here's a simple way to do this with NoGame0life's script:

 private void Update() {
     if (Input.touchCount == 2) {
         if (!_isPinching) {
             _isPinching = true;
             OnPinchStart();
         }
         OnPinch();
     } else {

         if (_isPinching) {
             // - Callback (pinch end)
             StartCoroutine(KeepsInLimits());
         }

         _isPinching = false;
         if (Input.touchCount == 0) {
             blockPan = false;
         }
     }/*

 IEnumerator KeepsInLimits() {
     this.movementType = MovementType.Elastic;
     yield return new WaitForSeconds(0.3f); // - for example
     this.movementType = MovementType.Clamped;
 }
Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image imad_bzitou · Jan 18, 2019 at 09:39 PM 0
Share

@Herinda can you please add this callback function to the NoGame0life's script, i try to edit the script of nogame0life's script in unity but i have a problem. please can you write the whole script with your edit? thank you

avatar image MathiasBlank · Jan 22, 2019 at 04:44 PM 1
Share

@imad_bzitou Oh yeah! I'm a bite busy this week but I will try to do it friday :).

avatar image nyonge MathiasBlank · Apr 09, 2020 at 10:25 PM 0
Share

Hi! Friendly request to share this in this thread :)

avatar image
0

Answer by nonameboy · Sep 22, 2019 at 07:02 AM

@imad_bzitou hey imad, it's enough if you set _minZoom to 0.5f in the Awake function. Greets

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

24 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to zoom and pan a gameobject not the whole scene 0 Answers

How to zoom and pan when you "pinch/swipe across screen" (iPhone) 5 Answers

restrict camera movement, Camera moves out of bounds! 2 Answers

[UI] proper way to add pinch zoom only to one UI element on the screen? 0 Answers

How To Create A Touch Zoom System 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges