Using GWT, I am displaying an image on the web page and my goal is to allow the user to crop it. The user draws an imaginary boundary box by clicking on a specific part of the image, moving the mouse, and releasing it somewhere else. With the use of MouseDownHandler() and MouseUpHandler(), I am planning to record the start and end corners of the mouse cursor.
However, when I deploy my work on the web, there is this problem: When the user clicks on the image and tries to draw the imaginary bounding box, the web browser (Google Chrome in my case) detects it as a drag and drop operation.
Therefore, I cannot get my mouseDown() and mouseUp() functions to work. How can I avoid the browser to do a drag and drop operation?
The code:
public void onModuleLoad(){
RootPanel.get().add(img1);
img1.addMouseDownHandler(new MouseDownHandler() {
#Override
public void onMouseDown(MouseDownEvent event) {
startX = event.getX();
startY = event.getY();
}
});
img1.addMouseUpHandler(new MouseUpHandler() {
#Override
public void onMouseUp(MouseUpEvent event) {
endX = event.getX();
endY = event.getY();
img1.setVisibleRect(startX, startY, endX-startX, endY-startY);
}
});
}
Maybe you can use HTML5. I have found this earlier question here on Stack OverFlow that describes the same problem as you have. Also I found a code example on code.google.com
Hopefully this will lead you to an solution.
Related
I have created an IDrawable that draws different arcs of a circle in a GraphicsView in order to create a pie chart.
No problem so far, except that now I would like to detect the click or hover of one of these circle portions. But I don't see anything that would allow me to do that easily.
Even inheriting my IDrawable from View to attach a tapgesture to it doesn't seem to work (and even then it wouldn't really answer my problem which is to be able to know which portion is clicked).
public class PieChartDrawable : View, IDrawable
{
private readonly PieChart _chart;
public PieChartDrawable(PieChart chart)
{
_chart = chart;
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += OnTapped;
GestureRecognizers.Add(tapGestureRecognizer);
}
private void OnTapped(object sender, EventArgs e)
{
// Does not trigger.
}
public void Draw(ICanvas canvas, RectF dirtyRect)
{
if (_chart.Entries == null)
return;
[...]
}
}
Am I doing it wrong, or is there a way to do it?
(I'm looking for a solution for MAUI, but I guess something that works under Xamarin Forms will do very well).
Thanks in advance.
It seams it can be a solution from the first sight:
Use the solution described in this one to detect the point
Write the function PointInPolygon to detect the selected area
(Point in the big circle, Point out of small circle and angle to detect sector)
Other one I have found at the moment the more complex to quick reuse :)
ADDED:
Invoking Events from Effects
I'm making an Idle Game but now I don't know how to make the listeners of the HUD. It's okay to instantiate an InputListener() in every button of my hud? I have like 20 buttons or actors to touch.
Simply use addListener() method for every actor that you want to be clicable. I used to use ClickListener for this purpose although it is sometimes recommended to use ChangeListener due to better behaviour when the button is being disabled.
So what you need to do is just
Button button;
//creating button...
button.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y)
{
//Do something
}
});
and the same for another buttons/actors on your HUD stage.
You can also take a look at this thread where I have asked about performance of many listeners.
Here is a scene2d button, which is really easy to use, I dont understand what the issue is or why you are worried about having a listener on each button or UI object, seems pretty logical to me.
button = new Button(buttonStyle);
button.setPosition(x, y);
button.addListener( new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log(TAG, "Button clicked");
};
});
I have a 3d-object (cube), which I want to use as a button. I've written the code in order to detect, if the cube was pressed but it doesn't look like it was pressed, since it lacks the "clicking animation". How can I create a clicking animation on my 3d-object ?
A good idea is to play an aninimation which skrinks the cube a bit and releases it immediately afterwards. The handler code you want to execute on a click might block the game loop, e.g. when you load a level. Then it might be useful to load the level aysnchronously to be able to see the animation. Or you execute the handler code after the animation. Or you play the scale down animation on the press event and the scale up animation on the release event.
Technically you can use the build in animation editor, the Update() method, start a coroutine or use the assets iTween or HOTween.
http://docs.unity3d.com/ScriptReference/Transform-localScale.html
Let me know if you like the idea or questions arise.
Unity makes it easier now to do this using Unity Canvas UI. Instead of real 3d buttons, you could place a canvas UI in world space at the location where you want the buttons. Add a UI Panel to the canvas then add a UI Button.
Now, you have out of the box several clicking effects. The default it color tint, but you can choose sprite swap, or animation.
If you do want animation, when you select button animation it will create an animator for you. Click on your UI button Game Object in the scene hierarchy and open the animation window. You can choose Pressed animation from the drop down, and press RECORD button, then edit your buttons scale, say make it 0.75 for x,y,z. Now when you click on the button it will animate a cool scale down for you.
Sorry, I know that is a lot of information dumped! But you will find it pretty great once you start working with it in world space.
You can scale it down a tiny bit once click happen. For example:
void OnMouseDown() {
this.transform.localScale += new Vector3(0.05f, 0.05f, 0.05f);
}
Then after click scale it back to the original size.
Perhaps look into iTween (free on Unity Asset store).
Its very easy to use and you can produce some nice looking animations.
you can scale it when pressed or just change the color a little bit. On mouse up, rescale or recolor it.
void OnMouseDown()
{
transform.localScale -= new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color += new Color(40,40,40);
}
void OnMouseUp()
{
transform.localScale += new Vector3(0.05, 0.05 , 0);
//or
transform.GetComponent<SpriteRenderer>().color -= new Color(40,40,40);
}
You can implement your button using new Event system of unity. Here are the functions you can implement :
public class ExampleClass : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler
{
public void OnPointerEnter(PointerEventData eventData)
{
//it is the function when you hover your mouse to the object
//You can change the color of your object to make your users
//understand that it is not just a cube but also a clickable item
}
public void OnPointerExit(PointerEventData eventData)
{
//You can revert your color back to its original
}
public void OnPointerDown (PointerEventData eventData)
{
//You can play with local scale as suggested by other answers here
}
public void OnPointerUp (PointerEventData eventData)
{
// Revert back the changes you made at onPointerDown
}
public void OnPointerClick (PointerEventData eventData)
{
//Use here for operations when your button is clicked
}
}
I have a gallery application that needs to zoom and pan. Instead of using default imageview , I found a sample touchmageview on internet and copied it. I called my images with TouchImageView and now i can zoom and pan the images that I called from my drawable folder. Then I added gallery to my project. Now the problem is that I can not fit the images to the screen.When I use scaletype.center then it fits the image to the screen but now zoom and pan features are not working. This is my gallerylistener ;
gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(Display.this, "Your selected position = " + position, Toast.LENGTH_SHORT).show();
// show the selected Image
img.setScaleType(ScaleType.CENTER_INSIDE);
img.setImageResource(Imgid[position]);
}
});
As you see , if I add img.setScaleType(ScaleType.CENTER_INSIDE); then the TouchImageView class doesn't work and I am not able to zoom and pinch and pan etc.. It only display the image. When I delete this code , then I can zoom but then when I change the picture to another one , the new one has the previous image's size. But I want to fit them to the center. Is there any way to reset the scaletype before calling the new image ?
By the way I have only one imageview in xml.
There is a similar question on this link but the solution did not work for me.
how to get setScaleType(ImageView.ScaleType.FIT_CENTER) effect using setScaleType(ImageView.ScaleType.MATRIX)
I'm having some issues with image rendering on Android. I can see the game correctly in my Desktop build and also in the Android Emulator but when it comes to a real Android device nothing is painted.
Objects are there because if I click on the button I can't see the action is performed, I can hear sounds and see BitmapFonts painted correctly.
The problem happens with images painted as textures with spritebatcher or Actors (Image for instance).
Any ideas? Thanks in advance.
In Assets Class:
public static void texturePacker(){
if(S.DEBUG){
Settings settings = new Settings();
settings.maxWidth = 16384;
settings.maxHeight = 16384;
settings.jpegQuality = (float) 0.7;
TexturePacker2.process(settings, "imgs/res", "imgs/packs","pack");
}
}
public static void loadGameAssets() {
//Cargo todas las texturas del menu
enemy_punch_static=atlas.findRegion("punch_static");
enemy_punch_punyo1=atlas.findRegion("punch_punyo1");
...
}
In a Screen implementing class:
...
Image countdown_go=new Image(Assets.countdown_go);
stage.addActor(countdown_go);
...
#Override
public void render(float delta) {
super.render();
Gdx.gl.glClear(Gdx.gl.GL_COLOR_BUFFER_BIT | Gdx.gl.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glClearColor(0.18431f,0.647058f,0.878431f, 1);
stage.act(delta);
stage.draw();
}
You can't use 16kx16k textures on devices. You can query GL_MAX_TEXTURE on all the devices you want to support to see if you can get away with something like 2048x2048 but you might want to switch to 1024x1024 to play it safe.