javascript - 使用 fabricjs 执行语义缩放
问题描述
我想使用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);
});
更新
我们还希望保留相对于图像(平面图)的点位置,这不会发生。请检查更新的小提琴。
解决方案
推荐阅读
- c# - 如何避免 Newtonsoft JObject.Parse 类型转换
- android - 获取 Google 签名的用户信息
- django - 在不使用 url 方法的情况下在迭代期间显示图像 url
- reactjs - React jest 测试抛出“对象作为 React 子项无效(找到:带有键 {type,props} 的对象)”
- ssh - 流浪汉禁用密码身份验证不起作用
- android - 如何调试 Firebase Android Studio 应用程序,该应用程序因权限被拒绝而上传失败?
- html - 在搜索栏 HTML 中显示图像
- ios - 赋值相关对象核心数据
- google-apps-script - onSelectionChange Google 应用脚本示例
- c - 在调用者堆栈上分配的内联函数、宏和其他解决方案