I wonder is it possible to exclude SVG element (like circle) only from zoom (scale) functionality and preserve his panning. For example: in map i point my current position with red filled circle. When user zoom, i want that this circle have a constant radius. When user pan - i want circle to pan with all other viewport content.
I found this solution:
Scale independent elements
But it seems that i can't figure out how to use it correctly with svg-pan-zoom library.
Also I wonder for similar task - is it possible to drag and drop some element? Mean just that element to be excluded from pan functionality? I was try some approach like jQuery draggable but with no luck.
Thank you
Well after a few weeks I've some kind of workaround. I use onZoom event handler of ariutta/svg-pan-zoom library and write a simple function like this:
onZoom=function(currZoom){
document.getElementById("marker").setAttribute("r", 2/currZoom);
}
In my case I have a little circle which represent current position. Now, when user zoom, library pass current zoom level as argument, and we divide him to radius and off we go!
Also i found a way to achieve my other question. Drag and drop is possible if we use enablePan / disablePan in corresponding mouse event on desired element. I can't post code example for now, because i still cant clarify how to calculate exact dX/dY to match to current zoom level, but that definitely work.
Related
I would like to create some mouse interactions on several moving planes and for that, I need to know which planes I'm hovering on. I've implemented the Raycasting method like in your example here but it seems like I'm hovering all my planes in the center of the canvas, just like if the raycasting method wasn't considering my position.set() modifications.
You can see here an example of what I did here, I logged the result of the hits array at the end of the canvasSlider.js file and all planes are logging when hovering in the center.
Is there a way around that? Or I'm I doing something wrong? Thanks a lot.
The main issue is that you are setting the z scale to 0.
plane.scale.set(1, size.height/size.width, 0);
Replace the 0 with a 1 to enable the hit tests to function.
Another issue I noticed was that your mouse values are relative to the screen and not the canvas. As the canvas is on a scrolling page it may not be taking up the full screen at all times.
I'm doing a platformer game using cocos2d-x v3 in c++, where the maps are usually very large, the visible screen follows the object through the map but I can't find a way to get the position of the visible screen in the map.
Using Size visibleSize = Director::getInstance()->getVisibleSize();gives me the dimensions of the entire map.
Let's say I want to show a sprite in the top right corner os the screen whenever the object reaches a point in the map, and this sprite would be always in the top right corner os the screen.
Using the object position doesn't do it.
Is there a way to get the position of the current screen?
Or is there a way to show a sprite or whatever in the screen and it would be in the screen even when the screen is moving?
Ps. I'm super noob in game development
There is a simple resolution:
You need two layer:
1: gamelayer
2: uilayer
Gamelayer is the one which you can move.Your map is added on gamelayer and when you need move the map you can just move the gamelayer.
Uilayer doesnt't move and its zorder is larger than the gamelayer.The sprite that shuold be always in the top right corner of the screen is on this layer.
Also:
There is a more complicated way:
You doesn't need to move the gamelayer.Just bind a camera to gamelayer and bind another camera to uilayer.
When you need to see the rest of your big map,you just move the camera of the gamelayer where you want.
BTW:
This is my first answer on stackoverflow.
English is not my first language,not very fluent.
Hope this can help you :)
I answered this question for you, which is a duplicate of the current question. The exact same solution applies to both situations. Add your sprite to the HudLayer as described in this question.
I currently have an html page that produces a line graph inside a canvas element. I have also implemented a feature so that when you click on a point in the graph, a table below the canvas displays the information for that graph point, and clears if you click somewhere that isn't a graph point on the canvas. However, there is currently no indicator for what graph point you have selected.
I would like to make it so that the dot you click on either gets bigger, or highlighted, or something. Unfortunately, I don't think there's any way to do that on the one canvas without needing to redraw the entire graph afterwards. If I drew a bigger dot on top of the original, I would then need to erase it and replace it with the smaller one, as well as redrawing the segment of the line graph that was covered by the larger dot.
I was looking into using a second canvas on top of the first with identical dimensions, using a z-index to control which was on top. However, I don't know how this would affect the click event. If two canvasses are on top of each other, is it possible for the click event to register the lower canvas? Does it only register the higher one? I guess I could just change the click event to be for whichever canvas is on top, but keep all the code for drawing on the canvas the same.
Any advice for how to solve this problem?
Solved a few of my own questions.
Firstly, the click event will only recognize whichever canvas is on top. However, I did like I said, and changed my click event to be for the top canvas, while leaving all instructions on the inside to be for the top canvas. Thank goodness I didn't use the 'this' keyword, or the change would have been much more annoying.
To make the graph points highlight, I first added a second canvas on top of my first one, placing them on top of each other by making their positions "absolute" and giving them a z-index of 0 and 1 respectively. Then, inside the if statement where the original click event recognized that a point had been clicked on, I told the top canvas to draw a larger dot on the same coordinates as the first dot (which I had saved in an array). First, I had it clear the top canvas though, so any other highlighted dots would no longer be highlighted. If the canvas was clicked on somewhere other than a dot, nothing was highlighted.
Im looking for an easy to use method of assigning drag behavior to multiple objects (images, shapes etc) in canvas. Does anyone have a good way or know of any libraries for dragging objects around? Thanks
Creating your own mouse events takes a little work - ideally you should either create or use some kind of mini-library. I'm thinking of creating something like this in the near future. Anyway, I created a drag and drop demo on jsFiddle showing how to drag images - you can view it here.
You can create draggable images like this:
var myImage = new DragImage(sourcePath, x, y);
Let me know if you have any questions about this. Hope it helps.
EDIT
There was a bug when dragging multiple images. Here is a new version.
Another thing you might want to check out is easeljs it sort of in the style of AS3... mouseEvents dragging etc...
The HTML Canvas—unlike SVG or HTML—uses a non-retained (or immediate) graphics API. This means that when you draw something (like an image) to the canvas no knowledge of that thing remains. The only thing left is pixels on the canvas, blended with all the previous pixels. You can't really drag a subset of pixels; for one thing, the pixels that were 'under' them are gone. What you would have to do is:
Track the mousedown event and see if it's in the 'right' location for dragging. (You'll have to keep track of what images/objects are where and perform mouse hit detection.)
As the user drags the mouse, redraw the entire canvas from scratch, drawing the image in a new location each time based on the offset between the current mouse location and the initial mousedown location.
Some alternatives that I might suggest:
SVG
Pure HTML
Multiple layered canvases, and drag one transparent canvas over another.
The HTML Canvas is good for a lot of things. User interaction with "elements" that appear to be distinct (but are not) is not one of those things.
Update: Here are some examples showing dragging on the canvas:
http://developer.yahoo.com/yui/examples/dragdrop/dd-region.html
http://www.redsquirrel.com/dave/work/interactivecanvas/
http://langexplr.blogspot.com/2008/11/using-canvas-html-element.html
None of these have created a separate library for tracking your shapes for you, however.
KineticJS is one such Javascript Library that u can use exclusively for animations
Heres the Link html5canvastutorials
Canvas and jCanvas
You're definitely gonna want to check out jCanvas. It's a super clean wrapper for Canvas, which kicks open a lot of doors without adding code complexity. It makes things like this a breeze.
For example, here's a little sandbox of something close to what you're after, with dragging and redrawing built right in:
Drawing an Arrow Between Two Elements.
I ventured down the road of doing everything with DIVs and jQuery but it always fell short on interactivity and quality.
Hope that helps others, like me.
JP
As you create new objects whether they are windows, cards, shapes or images to be draggable, you can store them in an array of "objects currently not selected". When you click on them or select them or start dragging them you can remove them from the array of "objects not selected". This way you can control what can move in the event of a particular mousedown event or mousemove event by checking if it isn't selected. If it is selected it will not be in the "not selected" array and you can move the mouse pointer over other shapes while dragging shapes without them becoming dragged.
Creating arrays of objects you would like to drag also helps with hierarchy. Canvas draws the pixels belonging to the foremost object last. So if the objects are in an array you simply switch their instance as in element in the array say from objectArray[20] to objectArray[4] as you iterate through the array and draw the objects stored in the array elements you can change whether other objects are seen on top or behind other objects.
I'm trying to figure out how to drag and drop an image from one canvas to another canvas. Assuming the canvases are next to each other, would it be possible to seamlessly drag something across the border? If not, is it a better idea to drag a div over the canvas, get its ID, and place it by responding to the mouseup location on the canvas?
You don't drag items on a canvas. A canvas is a non-retained mode (or immediate mode) graphics API. You issue draw commands and you get pixels. Simulating dragging is comprised of tracking the user's mouse movements and choosing to repeatedly clear and re-draw the canvas with different parameters to make some subset of the pixels appear to move as a cohesive object.
Contrast this with HTML or SVG where you actually change position/transform properties of a real DOM object and the watch as the visual representation of your document updates automatically.
If you have two canvases and want to drag something from one to the other, what I would do is:
On mouse down on the 'menu' canvas, create a new canvas programmatically just as large as the object, and (using absolute CSS positioning) place it over top of the item the user clicked on.
Draw the item onto that canvas.
Track the mousemove event on the document, and update the position of the canvas relative to the mouse.
When the user releases the mouse over the destination canvas, throw away (or hide) your tiny 'dragging' canvas, and re-draw the main canvas with the item that was dragged in the appropriate location.
Though, what I'd probably really do here is use SVG. ;)
Check this answer.
It is for multiple select drag & drop, but maybe will be useful.
Why does this need to be 2 canvases? The canvas is your drawing area, you control it. Why do you need 2?