iPhone: Properly scaling lines / circle drawn in drawRect - iphone

I am drawing custom annotations over an image (circle, arrow etc) in my iPhone app. I allow pinch zooming & drag gestures for these annotations. These annotations are custom made AnnotationView with drawRect drawing circle / line etc.
I am finding issues with zooming
Try 1: The zoom is applied by scale transformation to the AnnotationView. Result: the annotations become blurred.
Try 2: To avoid blurring, I added redrawing with co-ords multiplied by scale factor instead of directly manipulating the transformation. This works without blurring, but, soon the circle etc goes out of the views bounds & is clipped.
I could use a bigger frame (size of full image), but, I am keeping the smaller frame so that I can easily move it back to position when it is dragged out of the window by user's zoom / pan gestures.
Question:
Is there a better way to manage this? I would like to zoom without blurring, while also having the ability to move it back to position if it is dragged out of original image bounds.

Related

Unity scrollview inherit scale and keep position relative to parent

I'm trying to add some buttons to a gameObject which is a scroll view child. The child is a very wide image, about 4 times as wide as normal screens, which is why I let it control the height, so that it is always from top to bottom, and only exeeds horizontally where scroll is allowed.
Here you can see my setting.
1. is the wide image
2. is a banner that used to be part of the image, but now I want it to be a individual gameObject.
I don't know how I can make the banner (2) inherit the behavior of the "full map" (1), right now when I choose free aspect and resized the game view, the "full map" scales nicely, so the it always fits from top to bottem. The more narrow the screen is, then more of the map will exceed to the right, and vice versa.
However the problem is that then banner (2) has a rect transform, which is set with x,y coordinates relative to the parent which scales. So as i resize around the view, the banner gets out of it's intended position, and also does not scale with the. I have tried many different components, but without luck. Here among, scale constraint, canvas scaler, position constraint
As you can see in this gif, the banner does not scale down, as the island gets smaller, also it stays in the same position horizontally.
Any suggestions on how I can make the children os the map behave as they were part of the map?
Deleted previous, misunderstood the question.
Proposed solution:
You remove the map part from UI and create it as an object: You attach the map image as a texture to (ie) a plane (see a video here). You add the "infinity island" as another texture and have it placed over the island image.
After that, you control the camera to zoom in/out of the island and not struggle with any scaling or moving UI.
I think you need to anchor the images to center of the island mini image, you can drag the anchor gizmo from the scene hierarchy.
If you see it as free aspect it gets buggy and difficult to handle, but if you choose a resolution everything is smooth.
Is this what you want?
Change the resolultion

Cocos2d-x zoom in zoom out in rendertexture

I are working on a coloring game for kids.I have used bucket fill and it working fine but the problem is coloring image contains some small areas which are impossible to fill by touching on it. I wanted to Implement zoom in and zoom out so that kids can zoom in to small area fill it and zoom out. I have tried scaling rendertexture but it scale around anchor point. Is there a way that I can scale around the touch location ?
Scaling will always be done around the anchor point. You have to reposition your RenderTexture, after scaling, so your touch location remains centered.

cocos2d: Show entire layer then zoom in on character

I have my main game layer that is larger than the screen when the scene currently starts you see the character (a ship in this case) in the screen but I want to show the entire layer to the user first, and then animate back a zoom level of 1.
How can I achieve this? I know I can use the scale property on CCLayer but how can I tell how much of the view I am seeing such that I can show all of it?
Animate your zoom using a CCAction such as CCScaleTo and set the end scale of the zoom in the CCScaleTo action to whatever you want as derived by comparing the screensize to the layer size. For example, to zoom in to a 2X magnification, your CCScaleTo would scale to a 2.0 scale. You could get even fancier and use the size of a particular object in the layer in comparison to the size of the layer and size of the screen to calculate a scale that brings the desired object to exactly the size you want after zooming.

Fastest / most efficient way to draw moving speech bubbles on screen - CoreAnimation, Quartz2D?

I am adding some functionality to an iPhone app, and could use some help in picking the fastest / most efficient / best practice approach for solving this problem:
At the upper-half of my screen, I have speech bubbles (think comic book) that are UIImageViews translating across the screen (dynamic x & y position). It is a UIImageView because there is an image as the background of the speech bubble.
Each speech bubble has a matching image moving around the bottom of the screen (elsewhere in the layer tree)
I would like to draw a tail (that triangle bit from a speech bubble) so the point of the triangle is tracking the lower image, with the base of the triangle being attached to the bottom of the upper UIImageView. (technically the base doesn't have to be butted against, it can overlap as long as I can match the color of my background image to the triangle).
I have already done all the tracking & drawn a line with CGContextStrokePath methods, and now I am stuck on how to replace the line with a triangle.
I have looked at drawing a triangle in Quartz and filling it. My concern is the speech bubbles are repositioned every 1/10th of a second, and it looks like drawing just the line used for proof of concept had a pretty severe performance / visual smoothness impact.
One idea I have is to do the trigonometry myself, and stretch & rotate an image of a triangle to connect each of these speech bubbles with the lower spot. Something is telling me there is a more efficient / more elegant solution, but I am not able to see it looking through the documentation. Any help on how you have or would approach this issue is appreciated. Thanks.
If the speech bubbles are fixed in size, just use a static UIImage. Set the image view's layer.position property at the point of the triangle. Then you can use view animation to move the bubbles around.
If you need the speech bubbles to be different sizes, I'd create a resizeable image using resizableImageWithCapInsets. Then I'd do the same as above to position it.
If there was something special about the speech bubble that I could't achieve with either a static image or a resizable image, I'd probably create a custom CA Layer or layers to get the effect I wanted (Like a gradient layer with a shape layer as it's mask layer)

Overlaying 2D paths on UIImage without scaling artifacts

I need to draw a path along the shape of an image in a way that it is always matching its position on the image independent of the image scale. Think of this like the hybrid view of Google Maps where streets names and roads are superimposed on top of the aerial pictures.
Furthermore, this path will be drawn by the user's finger movements and I need to be able to retrieve the path keypoints on the image pixel coordinates. The user zooms-in in order to more precisely set the paths location.
I manage to somehow make it work using this approach:
-Create a custom UIView called CanvasView that handles touches interaction and delivers scaling, rotation, translation values to either the UIImageView or PathsView (see bellow) depending on a flag: deliverToImageOrPaths.
-Create a UIImageView holding the base image. This is set as a children of CanvasView
-Create a custom UIView called PathsView that keeps track of the 2D paths geometry and draws itself with a custom drawRect. This is set as children of the UIImageView.
So hierarchy: CanvasView -> UIImageView ->PathsView
In this way when deliverToImageOrPaths is YES, finger gestures transforms both the UIImageView and its child PathsView. When deliverToImageOrPaths is NO the gestures affect only the PathsView altering its geometry. So far so good.
QUESTION:
The problem I have is that when scaling the base UIImageView (via its .transform property) the PathsView is scaled with aliasing artifacts. drawRect is still being called on the PathsView but I guess it's performing the drawing using the original buffer size and then interpolating.
How can I solve this issue? Are there better ways to implement these features?
PS: I tried changing the PathsView layer class to CATiledLayer with levelsOfDetailBias 4 and levelsOfDetail 4. It solves the aliasing problem to some extent but it's unacceptable slow to render.
If you're holding onto the path values as they are being drawn, you can capture the % scaling of the underlying image, then reposition the path values and redraw them in the PathsView's drawRect method.
It would involve a bit of math (mostly along the lines of map projections) but instead of scaling bitmaps and getting artifacts, you would be scaling point distances and redrawing using vectors, which would make it smooth at any resolution (especially if you're connecting dots with beziers instead of pixels or lines).
If you're laying paint along the paths as the user draws them and throwing away the point data, then the only solution is to do bitmap anti-aliasing which is essentially what CATiledLayer is doing for you and as you've discovered, can be slow.
If you are targeting iPhone OS 3.0+ you could use a CAShapeLayer for your path. You assign a CGPathRef to the layer and it will handle all the drawing and scaling for you. You just set the layer's transform.