Я хочу добиться семантического масштабирования с использованием fabricjs.
У меня есть плотные точки на холсте. Однако, когда мы увеличиваем или уменьшаем масштаб, размер точек должен оставаться без изменений, но расстояние между ними должно увеличиваться или уменьшаться соответственно.
Взгляните на эти 2 примера
Геометрическое масштабирование холста
https://bl.ocks.org/mbostock/3680958
Семантическое масштабирование холста
https://bl.ocks.org/mbostock/3681006
Я хочу добиться масштабирования, аналогичного семантическому, с использованием fabricjs.
Я пытался найти решение с использованием fabricjs и до сих пор, кажется, работает нормально. Я хочу знать или проверить, есть ли лучший способ добиться того же, используя fabricjs.
Мы также хотим сохранить положение точки относительно изображения (план этажа), чего не происходит. Пожалуйста, проверьте обновленную скрипку.
Мое решение, скриптовая ссылка
https://jsfiddle.net/bharatpatil/v7658dn9/43/
HTML
<button id="zoomIn">Zoom In</button>
<button id="zoomOut">Zoom Out</button>
<br>
<canvas id="c"></canvas>
Javascript
var i, dot,
getRandomInt = fabric.util.getRandomInt,
rainbow = ["#ffcc66", "#ccff66", "#66ccff", "#ff6fcf", "#ff6666"],
rainbowEnd = rainbow.length - 1;
var circle1Radius = 20;
// create canvas instance
var canvas2 = new fabric.Canvas('c', {
backgroundColor: "#fff",
renderOnAddRemove: false
});
fabric.Image.fromURL('https://upload.wikimedia.org/wikipedia/commons/9/9a/Sample_Floorplan.jpg', function(img) {
img.scaleX = canvas2.width / img.width;
img.scaleY = canvas2.height / img.height;
img.set('selectable', false);
img.opacity = 0.3;
canvas2.add(img);
createDots();
});
function createDots() {
// draw random dots
for (i = 100; i >= 0; i--) {
dot = new fabric.Circle({
left: getRandomInt(0, 400),
top: getRandomInt(0, 350),
radius: circle1Radius,
selectable: false,
lockScalingX: true,
lockScalingY: true,
lockRotation: true,
hasControls: false,
hasBorders: true,
hasRotatingPoint: false,
objectType: 'AppCircle'
});
dot.setGradient('fill', {
type: 'radial',
r1: 0,
r2: circle1Radius,
x1: circle1Radius,
y1: circle1Radius,
x2: circle1Radius,
y2: circle1Radius,
colorStops: {
0: 'rgb(85, 196, 255, 1)',
0.1: 'rgb(85, 196, 255, 0.5)',
0.2: 'rgb(85, 196, 255, 0.4)',
0.3: 'rgb(85, 196, 255, 0.3)',
0.4: 'rgb(85, 196, 255, 0.2)',
1: 'rgba(85, 196, 255, 0.1)',
}
});
canvas2.add(dot);
}
canvas2.renderAll(); // Note, calling renderAll() is important in this case
}
function zoom(isZoomingIn) {
var SCALE_FACTOR = 1.1;
var objects = canvas2.getObjects();
var dd = 1;
if (isZoomingIn) dd = SCALE_FACTOR;
if (!isZoomingIn) dd = 1 / SCALE_FACTOR;
for (var i in objects) {
if (objects[i].objectType !== 'AppCircle') {
console.log(objects[i]);
objects[i].scaleX = objects[i].scaleX * dd;
objects[i].scaleY = objects[i].scaleY * dd;
}
objects[i].left = objects[i].left * dd;
objects[i].top = objects[i].top * dd;
objects[i].setCoords();
}
canvas2.setHeight(canvas2.height * dd);
canvas2.setWidth(canvas2.width * dd);
canvas2.renderAll();
canvas2.calcOffset();
}
document.getElementById('zoomIn').addEventListener('click', () => {
zoom(true);
});
document.getElementById('zoomOut').addEventListener('click', () => {
zoom(false);
});
Обновление
Мы также хотим сохранить положение точки относительно изображения (план этажа), чего не происходит. Пожалуйста, проверьте обновленную скрипку.
https://jsfiddle.net/bharatpatil/v7658dn9/43/