svgdotjs / svg.panzoom.js Goto Github PK
View Code? Open in Web Editor NEWA plugin for svg.js which enables panzoom for viewbox elements
License: MIT License
A plugin for svg.js which enables panzoom for viewbox elements
License: MIT License
Hi, i have this code:
svg = SVG('svg').size('100%', '100%').panZoom({panMouse: 2, zoomFactor: 0.03, zoomMin: 0.5, zoomMax: 20});
svg.on('zoom', function(ev) {
console.log(svg.zoom());
});
When i zoom in i get data from svg.zoom() like this:
1.0300000016911641
1.0599999740677215
1.089999925549374
1.1199998940773055
1.1499998489445757
1.1799998532704519
1.2099998871550262 //Here i stopped zooming in
And that looks OK, but when i zoom out i get this:
1.2399998435183597 //Here i started zooming out, this should be ~1.17999991514276
1.2099998888721086
1.17999991514276
SVG actualy zooms out properly but zoom info is incorrect and it is like 2 steps behind
This is my code:
node_panel = SVG.SVG().addTo(id).size(width, height).viewbox(0,0,width, height)
.panZoom({ panButton:1, zoomMin: 0.5, zoomMax: 2 ,zoomFactor:0.1,})
let circle=node_panel.circle(30)
.attr({
fill:'none',
stroke:'#d4d4d4',
strokewidth:8
})
node_panel.on('mousemove', function(e){
circle.center(e.offsetX,e.offsetY)
})
By the way, "panButton" is written as "panMouse" in the readme.md
Guys, once i run elementUi.panZoom({zoomMin:0.01}) i would like to cancel panZoom in the future but i can't.
I tried $(elementUi.node).unbind('pinchZoomStart'); elementUi.off('pinchZoomStart') but panZoom continue working
Hi,
I'm using the option wheelZoom, it's working fine but I got the following error.
45:18 Argument of type '{ wheelZoom: boolean; }' is not assignable to parameter of type 'false | options'.
Object literal may only specify known properties, but 'wheelZoom' does not exist in type 'options'. Did you mean to write 'doWheelZoom'?
43 | .size('400px', '400px')
44 | .viewbox(0, 0, 1200, 1920)
> 45 | .panZoom({ wheelZoom: false });
Looking into your source code, in file svg.panzoom.js.d.ts
interface options {
doPanning?: boolean
doPinchZoom?: boolean
doWheelZoom?: boolean
panMouse?: MouseButton
oneFingerPan?: boolean
margins?: boolean | marginOptions
zoomFactor?: number
zoomMin?: number
zoomMax?: number
}
But in src/svg.panzoom.js :
const doWheelZoom = options.wheelZoom ?? true
Thanks,
Is there any possibility to pan to a specific point with javaScript?
Something like draw.panZoom().pan({ x: 0, y:0}) ?
Its often useful to restrict the panning to a specified area so people dont move the object out of the canvas.
For this I propose the following api:
el.panZoom({
area: SVG.Box(x, y, width, height)
})
It has to be noted that the values passed must match for the zoom lvl 1. Restrictions for other zoom levels are calculated on the fly.
That means that the area expands when zooming in and shrinks when zooming out. Otherwise people could not pan to specific points when zoomed in. For shrinking it might be useful to stay at the canvas size for the minimal area
I need to set a max/min zoom for my map, to prevent that the user zoom so far out that the map disappears.
In order to know when to use ev.preventDefault()
I need to know if we're zooming in or out. Since panzoom handles the wheelZoom, the only way is to listen to the zoom
event.
My current code rely on getting the level
variable from the zoom
function.
world.on("zoom", function maxMin(ev) {
var newZoomLevel = world.zoom()
var lvl = ev.detail.level
var zoomingIn = newZoomLevel < lvl
if(zoomingIn && newZoomLevel > 7) ev.preventDefault()
else if(!zoomingIn && newZoomLevel < originalZoomLevel) ev.preventDefault()
})
If I just set my logic after newZoomLevel
then the user is trapped at the zoom level where I call ev.preventDefault()
, since wheelZoom skips some steps when getting to the desired zoom level (which is expected and sane). Imagine that newZoomLevel
is 7.1833495 and I call ev.preventDefault()
. Now, if the user tries to zoom out and wheelZoom goes to 7.021554, I will still call ev.preventDefault()
since it's higher than 7, hence trapping the user in a non zoomable state.
Adding this.fire('zoom', {box: box, focus: point, level: level})
to the zoom
function creates a misalignment with pinchZoom
, since level doesn't exist (on less we substitute level
with currentDelta
).
So the question is:
level
from box
and not add level
to zoom
(not sure how to do that yet)level
to zoom
but not to pinchZoom
level
in pinchZoom
so the event is alignedcurrentDelta
as level
in pinchZoom
so the event is aligned@Fuzzyma What do you think?
Sorry my English is not very good.
I would like to know if it is possible to lock the Pan on an axis. Example, move only on the y axis?
When panzom is initialized there is no way to disable it. I tried to pass false as parameter but all events still works and I have no idea how to unbind them.
Hi, I use the following combination of the plugin:
"svg.draggable.js": "^2.2.1",
"svg.js": "^2.6.6",
"svg.pan-zoom.js": "^2.7.0",
"svg.resize.js": "^1.4.3",
"svg.select.js": "^2.1.2",
"vue": "^2.6.10",
I added the draggable function to my svg container and then the panzoom function to the main group of the SVG image. But both the means to disable the wheelzoom dosent work.
group.panZoom(false)
group.panZoom({
wheelZoom: false,
zoomMin: 0.5,
zoomMax: 2
})
So is the issue related with my versions ? I can only use this specific version combinations for both zoom and drag to work in my project.
Or can the panzoom should not be applied at group level? if so, then how to get both zoom and drag functionality at same time?
There is no promise that it will work with Vue I'll be very appreciated for help though. There is the set up https://codesandbox.io/s/m324p7lpoy
What is interesting it getting works if you comment import panZoom from "svg.panzoom.js";
and then uncomment it again. It placed at the component/HelloWorld.vue
I have tried calling panZoom with some of the options described in the README, and they are not working.
I have looked in the code and they are not even being evaluated...
The only options that are checked are zoomFactor, zoomMin and zoomMax.
Did you forget to add the evaluation of the remaining options?
Thanks
We currently use this plugin and svg.js on a page with a full width SVG (contents are generated from database values so width is unknown) and the mousewheel zoom blocks the natural page scroll. We plan on implementing zoom buttons using the .zoom()
method so it would be good if there was an option to disable mouse wheel zooming. Willing to submit a PR if this would be of interest.
Currently it is only possible to zoom in to the given coordinates. When the max zoom level has been reached you will not be able to move to another set of coordinates.
Can we have a 'Pan to coordinates' method which will add the ability to move to the given coordinates?
Something very similar to the .zoom()
method? Something in the way of .pan(point)
.
It seems this code works great on Android devices, panning and zooming by using 2 fingers on the screen. On the iPad however this doesn't seem to work. Is this to be expected and if so are there any plans to provide iPad support in the near future?
Is it currently possible to enable single finger panning with this plugin? Or is there an alternate way to achieve this with SVG.js?
If not it would be a great addition to the library, I'd be happy to make a PR if pointed in the right direction.
There is a lot of info in the zoom and panEnd events which is great. But what I need to do is place a rect in the correct location on top of a zoomed in pattern
with the zoom level offsetting the xy location of the rect.
Below is my current code and the before and after zoom of the top left of the browser. For example, a mouseup at 20,20 in the first screenshot (no zoom) is a new rect to be placed at that location. But in the second screenshot the rect needs to be placed at 20,20 + zoomoffset. Let me know if there is a best practice or something existing in the API for this before I start hacking up some potential solutions. If it's as simple as multiplying by draw.viewbox().zoom
that will do. Thanks.
<div id="drawing"></div>
<script>
var size = {
x: window.innerWidth || document.body.clientWidth,
y: window.innerHeight || document.body.clientHeight
}
var draw = SVG('drawing').size(size.x, size.y).panZoom({
zoomMin: 1,
zoomMax: 5,
zoomFactor: .5
})
var rect = draw.rect(size.x, size.y)
var pattern = draw.pattern(10, 60, function(add) {
item = add.rect(10,60).fill('#141b26')
add.rect(9,60).fill('#dc3545')
})
rect.attr({ fill: pattern })
draw.on('zoom', function(ev) {
console.log(ev.detail)
console.log(draw.viewbox().zoom)
})
draw.on('panEnd', function(ev) {
console.log(ev.detail.event)
})
</script>
Hello,
when I Include the plugin after including the svg.js library in html document:
<script src="svg.js"></script>
<script src="svg.panzoom.js"></script>
I get this issue:
Uncaught SyntaxError: Cannot use import statement outside a module (svg.panzoom.js?ver=4.9.13:1)
I'd want to use svgjs and svg.panzoom in a wordpress plugin, so I prefer to grab them by cdn
How can I fix this issue? thanks!
When animate().zoom()
is called with two arguments then add
throws TypeError: Cannot set property 'zoom' of undefined.
We extend the FX module with:
zoom: function(level, point) {
this.add('zoom', new SVG.Number(level), point)
}
Looking at add
it is not clear how, or if it is even possible, to delegate multiple arguments to a function.
// adds one property to the animations
, add: function(method, args, type){
this.last()[type || 'animations'][method] = args
return this._callStart()
}
Since the 3th arguments has to be a type or 'animations'
I have tried wrapping the two arguments in both an Array and an Object to no avail.
@Fuzzyma How do I pass two arguments to our zoom
function while animating?
Hi,
please bump the version for your last fixes :)
The zoom behaviour is now a lot better and feels more natural thanks!
I'm very excited about the svg.js library and these awesome plugins. Thank you for this work. I'm having an issue, however, with this plugin, which is that while I can initiate the root SVG element and draw an image with 100% height and width, as soon as I try to pan or zoom the image disappears entirely. Here's how I have things setup--apologies if I'm missing something obvious:
<div id="delineator" class="h-100"></div>
<script src="js/jquery-3.3.1.min.js"></script>
<script src="node_modules/@svgdotjs/svg.js/dist/svg.js"></script><!-- 3.0.12 /-->
<script src="node_modules/@svgdotjs/svg.panzoom.js/dist/svg.panzoom.js"></script><!-- 2.0.2 /-->
<script type="application/javascript">
var delineate;
var canvas;
var image;
$(document).ready(function() {
delineate = SVG().addTo('#delineator')
.size("100%", "100%")
.attr('id', 'svg-delineator')
.panZoom({panMouse: 2, zoomFactor: 0.03, zoomMin: 0.5, zoomMax: 20});
canvas = delineate.group().attr('class', 'delineator-canvas');
image = canvas.image('img/newspaper.jpeg');
});
I've tried adding the image directly to the root SVG element instead of putting it inside a group element first. I've tried leaving the default options for .panZoom. I've tried setting an explicit height and width for the SVG root element. I've also tried capturing the "zoom" event to output the value of delineate.zoom() to the console, and it always outputs "Infinity." Any help would be greatly appreciated!
dirtyViewbox
appears to be unused.
Can elements events be disabled while performing pan-zoom ?
Now, when I click an element, it will move, but also pan-zoom moves, which triggers a weird behavior.
i tried to zoom in on specific id but the zoom would always zoom on the same position.
var testzoom = function (nodeId) {
var container = '#drawing1';
var elem = $(container).find(`#${nodeId}`);
var position = $(elem).offset();
var parentOffset = $(container).offset();
position.top -= parentOffset.top;
position.left -= parentOffset.left;
{
let width = $(container).width();
let height = $(container).height();
var x = width / 2 - position.left;
var y = height / 2 - position.top;
rsr.zoom(1,new SVG.Point( x, y))
.animate()
.zoom(4)
}
}
I would expect panEnd to fire only if some actual panning took place, right now it fires on every mouseup making it difficult to do something different for mouseup.
I do not have margins
set, but still I must use 2 fingers to pan on any of my mobile devices (iPhone, iPad & MS Surface).
Refs:
Hi, I got impression, that when I have two nested containers and apply panZoom on one of then, the entities in the second container do not pan and zoom.
The problem is demonstrated here: https://codepen.io/bpatzak/pen/XWmzMwv
The zooming does not work and the red rectangle (in nested container subjected to panZoom) moves only when the mouse is inside the rectangle.
Any help will be appreciated.
Is it possible to set pan on specific mouse button? I have use case in our application that requires pan to work only on middle mouse button.
There seems to be an issue with panStart to detect a mouseUp event to indicate dragging has stop. I tested this on firefox and internet explorer and both doesn't work. It does however work on chrome and safari.
Hi
How can I set the min and max levels for svg zoomable? Can you put min and max values as parameters in the zoom()? Thanks
draw.on('pinchZoomStart', function(ev) {
console.log("stopped")
ev.preventDefault()
})
function not triggering when we zoom.
My SVG is rendered at scale; meaning it's created with the SVG.js library with a viewBox
of -5 -5 1010 1010
but is resized to fit the available space via width
and height
attribute settings of 100% on the <svg>
tag.
So it's possible (and common) for the SVG to render smaller than 1010 x 1010. When I zoom in and back out again, with zoomMin
set to 1, then the SVG ends up larger than when the page first loaded (if it was originally drawn at 650 x 650, for example, then it can only be zoomed back "down" to 1010 x 1010).
There's not a reliable way to use a smaller zoomMin
value, as the browser window could be any size when the SVG is first drawn/rendered.
Is there a way to tell zoomMin
to use the original render size as the smallest zoom factor?
Hi, i have an issue with using panzoom/draggable together. I ask question on SO here: https://stackoverflow.com/questions/61497990/unexpected-behavior-of-svg-draggable-panzoom, and here is the jsfiddle: https://jsfiddle.net/grayter/uhde3ykw/29/
The problem is in dragging group - content of group is flowing. Is there some way to fix it? I need this very much to my project. Help will be appreciated.
In trying to prevent the SVG from getting dragged/panned out of sight, I'm using the margins
property like this:
panZoom({
margins: {
top: 1,
right: 1,
bottom: 1,
left: 1
},
zoomMin: .5,
zoomMax: 10,
oneFingerPan: true
});
I would expect that with a number so low, I would only get 1px (or so, depending on zoom level) of the SVG to remain in view when panning to the extreme edge of the available space.
However, whenever this property is set (using any numerical values), panning simply doesn't work at all. Instead, the SVG zooms with the mouse wheel with the anchor point remaining in the upper-left of the screen. Then it cannot be dragged/panned at all.
(For the record, I've also tried using higher numbers (500 all around), and get the same results.)
This is happening on:
Hi, do you plan to have a non-npm version of the Panzoom.js, just like the svg.js?
By simply putting <script src="svg.js"> alone with <script src="panzoom.js"> and it works.
el.panZoom(false) not disabling pan, it disables only zoom functionality
It seems that if multiple SVGs have panZoom()
applied to them, then usingpanZoom(false)
to disable multiple SVGs at once doesn't work. Any advice on this?
Hi,
you are using ev.deltaY in
svg.panzoom.js/src/svg.panzoom.js
Line 51 in 27f5e88
On firefox on linux, we get the following event when scrolling:
{ deltaY: 3, deltaMode: 1}
on chrome on linux, we get
{ deltaY: 53, deltaMode: 0}
This results in huge scrolling speeds which make the zooming almost unusable. Since we don't need absolute pixel precision here, I suggest to add code to multiply the deltaY by some value, maybe 17 or just 15 or 20 when deltaMode is (1) DOM_DELTA_LINE.
Reference: https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaY
Note that there are currently debates on what do to, but it's been going on for years:
https://bugzilla.mozilla.org/show_bug.cgi?id=1392460
w3c/uievents#181
Adding this would fix the problem right now.
Cheers,
Jon
Hello, when I use svg.panzoom.js
, I got svg viewbox
attribute 0, 0. For example: viewbox=281.8125 251.90625 0 0
. So the svg element is not visible in any case.
my code:
import SVG from '@svgdotjs/svg.js/src/svg'
import '@svgdotjs/svg.filter.js'
import '@svgdotjs/svg.panzoom.js
SVG()
.addTo('#graph')
.size(800, 800)
.panZoom({ zoomMin: 0.5, zoomMax: 20 });
When using a laptop touchpad, it's common that ev.deltaY
is -0, which gives a zoomAmount
of NaN
.
There is two resolutions, one is to ignore wheelZoom when ev.deltaY
is -0 another is to allow wheelZoom on another axis.
The former is the quick fix which I will try to get away with. But perhaps it makes sense to support other axis wheelZoom?
Is it possible to reset the pan programtically? i.e. With a reset button, I want to zoom to 1 and go back to original viewbox.
I'm fairly new to this and running out of google search ideas. This feature would be great if not already implemented!
I can't founf it
This is a bit weird to explain so please bare with me...
Right now when we use the scrollWheel what basically happens is that the SVG scale increases/decreases by a fixed amount (zoomFactor).
A better usability option seems to be using a 'multiplication factor'. This is inspired by another project, svg-pan-zoom which does a very similar thing.
This approach improves the usability because when you are zooming in if you use a fixed step you need to scroll a lot to really zoom in on what you want. By using a multiplication factor you "zoom more " as you are zooming in and "zoom less" when you are zooming out.
In my example I want to zoom from 0.5 to 10 with a zoomFactor of 0.2. You can check my example with the multiplication factor here: https://jsfiddle.net/95msu3jf/8/
Only change was var lvl = Math.pow(1 + options.zoomFactor, (-1) * ev.deltaY / 100) * this.zoom()
You can compare it with the original svg.panzoom.js code here: https://jsfiddle.net/95msu3jf/9/
Try these examples and specially zooming in. You can see in the original it's very annoying to get to zoom 10 as you need to scroll a lot. Yes, you can increase the zoomFactor so this is faster but then you lose a bit more control when you zoom out specially from 1 to 0.5.
I think using a multiplication factor improves the usability a lot but I welcome your feedback and if I should do a PR for this.
How to use panzoom with svg.js in npm?
Is anyone else finding that the bounds of the zoom are not centered around the provided coordinates?
I create a rectangle, find the centre using bounds and pass that to panzoom
the center point is highlighted using a small square
draw = SVG('svg').size(window.innerWidth, window.innerHeight)
draw.rect(100,100).fill('rgba(256, 256, 180, 0.1)')
var bounds = draw.bbox()
draw.panZoom({zoomMin: 0.3, zoomMax: 3})
draw.rect(bounds.width, bounds.height).fill('rgba(256, 0, 180, 0.1)').addClass('box').move(bounds.x, bounds.y)
draw.rect(4,4).fill('rgba(256, 0, 180, 1)').addClass('box').move(bounds.cx-2, bounds.cy-2)
var z = draw.zoom(0.3).animate().zoom(2, {x:bounds.cx, y: bounds.cy})
as I change the rectangle size, the amount the center is off changes. when I match the window width and height, it becomes centered.
I'm thinking this part of the code in svg.panzoom may be missing some additional translation
https://github.com/svgdotjs/svg.panzoom.js/blob/master/src/svg.panzoom.js#L187
Hey,
The panning event is not fired...
Seems it should be easy to add that. If you want I can do a pull request with the fix.
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.