I have a svg where I have implemented zooming via D3.js. I am not satisfied with the zoom factor when using the mousewheel. How can I adjust the zoom factor?
I made a JSfiddle with an example of how I implemeted the zooming.
I thought I need something like this but it is wrong:
zoom.scaleBy()
I am trying to make my problem a bit clearer:
I want to set a factor, that acts as the zoom factor for one mousewheel revolution. Illustration with pictures:
The SVG without zoom:

After one mousewheel revolution:

What I would like to have after one mousewhell revolution:

I know how this worked in older versions of D3.js but can someone help me with the current version?
You are very close in your JS Fiddle!
The crux of the issue here is that the scaling factor k is automatically updated when the event callback is called. The goal here is when we change from the previous k (old_k) to the new k, we need to scale the change, delta, and reapply it to get the new k value.
So the code changes to do this are as follows...
keep track of the old k value
var old_k = 1;
calculate the delta k
var delta = d3.event.transform.k - old_k
update with transform with scaled delta!
d3.event.transform.k = old_k + zoomFactor*delta
reapply transform
svg.attr("transform", d3.event.transform);
save new k for the next event
old_k = d3.event.transform.k
Play around with var zoomFactor = .7; to see that it works.
console.clear()
//movement and controls
var stepLR = 30;
var controller;
var speed = 0.007;
//pendulum vertical
var cx = 609, cy = 0;
var radius = 350; // cm
var g = 981; // cm/s^2
var angle = Math.PI/8; // radians
var vel = 0; // cm/s
var dx = 0.02; // s
var acc, vel, penx, peny;
//svg and d3.js
var sphere;
var string;
var string2;
var sphere2;
//timing
var start;
var old_k = 1;
var zoomFactor = .7;
$( document ).ready(function() {
start = (new Date()).getTime(); //start time on page load
var svg = d3.select("body")
.append("svg")
.attr("width", '100%')
.attr("height", '600px')
.call(d3.zoom().on("zoom", function () {
var delta = d3.event.transform.k - old_k
d3.event.transform.k = old_k + zoomFactor*delta
svg.attr("transform", d3.event.transform);
old_k = d3.event.transform.k
}))
.append("g");
var viewport = svg.append('g')
var layer1 = viewport.append('g');
var layer2 = viewport.append('g');
sphere = layer2.append("circle")
.attr("cx", 30)
.attr("cy", 30)
.attr("r", 20)
.attr('fill', '#FF0000');
string = layer1.append("rect")
.attr("x", 27)
.attr("y", 0)
.attr("width", 6)
.attr("height", 10);
//The vertical pendulum
sphere2 = layer2.append("circle")
.attr("cx", 609)
.attr("cy", 300)
.attr("r", 20)
.attr('fill', '#FF0000');
string2 = layer1.append("line")
.attr("x1", 609.5)
.attr("y1", 0)
.attr("x2", 609.5)
.attr("y2", 310)
.attr("stroke-width", 4)
.attr("stroke", "black");
var roof = layer1.append("rect")
.attr("x", -100000)
.attr("y", -60)
.attr("height", 55)
.attr("width", 200000)
.attr('fill', 'url(#diagonal-stripe-3)');
var border = layer1.append("rect")
.attr("x", -100000)
.attr("y", -10)
.attr("height", 10)
.attr("width", 200000)
.attr('fill', '#000000');
controller = setInterval(controller, 30); //start controller
});
function controller(){
//horizontal pendulum
sphere.attr('cy', Math.sin(start-(new Date()).getTime()/400-(Math.PI/4))*310+350);
string.attr('height', Math.sin(start-(new Date()).getTime()/400-(Math.PI/4))*310+337);
string.attr('width', Math.sin((start-(new Date()).getTime()/400-(Math.PI/4))-Math.PI)*3+6);
string.attr('x', Math.sin((start-(new Date()).getTime()/400-(Math.PI/4)))*1.5-3+stepLR);
//vertical pendulum
acc = g * Math.cos(angle) * dx;
vel += acc * dx;
angle += vel * dx;
setPenPos();
document.addEventListener("keydown", function (e) {
if([e.keyCode] == 37){
left();
}
if([e.keyCode] == 39){
right();
}
});
}
function left(){
stepLR=stepLR-speed;
sphere.attr('cx', stepLR);
string.attr('x', stepLR);
}
function right(){
stepLR=stepLR+speed;
sphere.attr('cx', stepLR);
string.attr('x', stepLR);
}
function setPenPos(){
penx = cx + radius * Math.cos(angle);
peny = cy + radius * Math.sin(angle);
string2.attr("x2", penx);
string2.attr("y2", peny);
sphere2.attr("cx", penx);
sphere2.attr("cy", peny);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg" version="1.1"> <defs> <pattern id="diagonal-stripe-3" patternUnits="userSpaceOnUse" width="10" height="10"> <image xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPSd3aGl0ZScvPgogIDxwYXRoIGQ9J00tMSwxIGwyLC0yCiAgICAgICAgICAgTTAsMTAgbDEwLC0xMAogICAgICAgICAgIE05LDExIGwyLC0yJyBzdHJva2U9J2JsYWNrJyBzdHJva2Utd2lkdGg9JzMnLz4KPC9zdmc+" x="0" y="0" width="10" height="10"> </image> </pattern> </defs> </svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With