我的HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Ionic App</title>
<!--script type="text/javascript" language='javascript' src="fabric.js"></script-->
<script type="text/javascript" language='javascript' src="index.js"></script>
<style type="text/css">
html, body {
width: 100%;
height: 100%;
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
}
#left {
float: left;
width: 20%;
height: 100%;
border: 0px solid red;
padding: 0px;
margin: 0px;
}
#center {
float: left;
width: 80%;
height: 100%;
border: 0px solid green;
}
#canvasWrapper {
overflow: scroll;
background: #FFFFFF;
}
#canvas{
border: 0px solid black;
}
</style>
</head>
<body id='body'>
<div id='left'>
<button onclick="init()">Init Canvas</button>
<input type="file" onchange="chooseImage(event)"/><br/>
<button onclick="zoomIn()">Zoom In</button>
<button onclick="zoomOut()">Zoom Out</button><br/>
</div>
<div id='center'>
<div id='canvasWrapper' tabIndex='0'>
<canvas id="canvas" ></canvas>
</div>
</div>
</body>
</html>
index.js代码:
/*! index.js 使用FabricJS对钡条逻辑封装的*/
// 0 1 2 3 4 5 6 7 8 9 10
var zoomArray = [0.33, 0.4, 0.5, 0.66, 0.8, 1, 1.25, 1.5, 2, 2.5, 3]; //缩放的比例,都是对称的
var zoomIndex = 5; //当前的zoomIndex
var canvasWrapper = null; //Canvas的包裹物,当外部的window大小变化时候需要对它的宽度和高度设置
var canvas = null; //Canvas
var fCanvas = null; //中间的Fabric.Canvas
var backgroundBase64 = null;
var backgroundImage = null; //背景fabric.Image
var backgroundImageWidth = 0 //Canvas的宽度,由图片的宽度决定
var backgroundImageHeight = 0; //Canvas的高度,由图片的高度决定
//Canvas的属性
var canvasAttrs = {
imageSmoothingEnabled: false,
enableRetinaScaling: false,
stopContextMenu: true, //Menu禁用
fireLeftClick: true, //左按键启用
fireMiddleClick: true, //滚动键启用
fireRightClick: false, //右按键禁用
//selectionColor: '#CC00FF', //selection的颜色
selectionLineWidth: 2, //selection的线宽
selection: true, //selection启动
selectionBorderColor: '#FFFF00',//selection边框颜色
selectionFullyContained: true, //只有当selection全部包含Canvas.Object的时候才会被选中
selectionKey: 'ctrlKey' //使用ctrlKey进行多选
};
//图片属性,中间Canvas的背景图和坐下那个图
var imageAttrs = {
left: 0,
top: 0,
selectable: false, //设置不能被选中,这样就可以作为背景图了
hoverCursor: "default", //设置它的鼠标形状
crossOrigin: 'Anonymous'
};
/*!
* OK选择文件
*/
function chooseImage(event) {
var file = event.target.files[0];
var reader = new FileReader();
reader.onload = function(event) {
var imgBase64 = event.target.result;
backgroundBase64 = imgBase64;
//构造数据
var data = {};
var dataMap = {};
data['partitions'] = [];
data['items'] = [];
data['filters'] = {};
dataMap['data'] = data;
dataMap["base64"] = backgroundBase64;
loadData(dataMap);
}
reader.readAsDataURL(file)
}
/*!
* OK这是上来执行的函数
*/
function init() {
__initFilterBackend();
__initCanvasWrapper();
__initCanvas();
}
function loadData(dataMap) {
if (dataMap == null) return;
//图片的Base64编码。这个值肯定是有的
backgroundBase64 = dataMap['base64'];
//加载背景图
fabric.util.loadImage(backgroundBase64, function(img) {
//背景图
backgroundImage = new fabric.Image(img, imageAttrs);
backgroundImageWidth = backgroundImage.width;
backgroundImageHeight = backgroundImage.height;
fCanvas.setWidth(backgroundImageWidth);
fCanvas.setHeight(backgroundImageHeight);
fCanvas.add(backgroundImage);
});
}
/*!
* OK放大按钮触发
*/
function zoomIn() {
var oldZoom = zoomArray[zoomIndex];
++zoomIndex;
if (zoomIndex > (zoomArray.length - 1)) {
zoomIndex = (zoomArray.length - 1);
//直接return掉,因为zoomIndex > (zoomArray.length - 1)说明之前的zoomIndex已经是数组最后一个了
return;
}
__zoom(oldZoom);
}
/*!
* OK缩小按钮触发
*/
function zoomOut() {
var oldZoom = zoomArray[zoomIndex];
--zoomIndex;
if (zoomIndex < 0) {
zoomIndex = 0;
//直接return掉,因为zoomIndex < 0说明之前的zoomIndex已经是0了
return;
}
__zoom(oldZoom);
}
/*!
* OK初始化Filter后端。使用Canvas2dFilterBackend,因为如果用new fabric.WebglFilterBackend()会报错
*/
function __initFilterBackend() {
fabric.filterBackend = new fabric.Canvas2dFilterBackend();
}
/*!
* OK初始化CanvasWrapper
*/
function __initCanvasWrapper() {
//如果已经初始话好了就直接return
if (canvasWrapper != null) return;
var centerDiv = window.document.getElementById('center');
var width = centerDiv.offsetWidth;
var height = centerDiv.offsetHeight;
canvasWrapper = window.document.getElementById('canvasWrapper');
//这里通过style的width和height里设置加上px,并且这里我不设置style的maxWidth和maxHeight
//因为如果设置了maxWidth和maxHeight后当我们对里面的Canvas进行缩小的时候,如果里面的Canvas变的太小,这样
canvasWrapper.style.width = width + 'px';
canvasWrapper.style.height = height + 'px';
}
/*!
* OK初始化Canvas
*/
function __initCanvas() {
//如果已经初始化好了就直接return
if (fCanvas != null) return;
canvas = window.document.getElementById('canvas');
//这里不设置宽度和高度,通过导入图片的宽高来设置
fCanvas = new fabric.Canvas(canvas, canvasAttrs);
//单纯设置canvas.backgroundColor内容无效,必须和下面的canvas.add一起才会起效果
fCanvas.backgroundColor = 'black';
}
/*!
* OK缩放的核心函数
*/
function __zoom(oldZoom) {
//记录一开始的left和top值
//var scrollLeft = canvasWrapper.scrollLeft;
//var scrollTop = canvasWrapper.scrollTop;
//以下是放大缩小操作,重新设置放大缩小的比例
var zoom = zoomArray[zoomIndex];
//在指定的点进行缩放
fCanvas.setZoom(zoom);
//!Important,加入对Canvas大小的设置,这样可以让CanvasWrapper也能进行调整
fCanvas.setWidth(backgroundImageWidth*zoom);
fCanvas.setHeight(backgroundImageHeight*zoom);
//放大完后要重新设置transform
//var vpt = fCanvas.viewportTransform;
//console.log('-----' + vpt[4] + ' and ' + vpt[5]);
//vpt[4] = 0;
//vpt[5] = 0;
//fCanvas.requestRenderAll();
/* oldleft newLeft
* --------- = ---------
* oldZoom newZoom
*/
//canvasWrapper.scrollLeft = (scrollLeft*zoom)/oldZoom;
//canvasWrapper.scrollTop = (scrollTop*zoom)/oldZoom;
}
FabricJS 在mac机器上对Canvas调整大小屏幕会闪烁
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
- 自在猫先生 2023-07-03 11:07关注
源于chatGPT仅供参考
这个问题可能是由于在调整大小屏幕时,Canvas重新渲染造成的。为了解决这个问题,你可以尝试以下几点: 1. 在调整大小屏幕之前先隐藏Canvas,然后调整完大小后再显示出来,这样可以减少闪烁的效果。 2. 使用`requestAnimationFrame`方法来延迟Canvas的重绘,这样可以确保在屏幕刷新的时候进行渲染,减少闪烁的可能性。 下面是修改后的JavaScript代码示例: ```javascript // ... /*! * OK缩放的核心函数 */ function __zoom(oldZoom) { //记录一开始的left和top值 //var scrollLeft = canvasWrapper.scrollLeft; //var scrollTop = canvasWrapper.scrollTop; //以下是放大缩小操作,重新设置放大缩小的比例 var zoom = zoomArray[zoomIndex]; // 隐藏Canvas fCanvas.wrapperEl.style.display = 'none'; // 使用requestAnimationFrame延迟重绘 window.requestAnimationFrame(function() { //在指定的点进行缩放 fCanvas.setZoom(zoom); //!Important,加入对Canvas大小的设置,这样可以让CanvasWrapper也能进行调整 fCanvas.setWidth(backgroundImageWidth*zoom); fCanvas.setHeight(backgroundImageHeight*zoom); //放大完后要重新设置transform //var vpt = fCanvas.viewportTransform; //console.log('-----' + vpt[4] + ' and ' + vpt[5]); //vpt[4] = 0; //vpt[5] = 0; //fCanvas.requestRenderAll(); // 显示Canvas fCanvas.wrapperEl.style.display = 'block'; }); /* oldleft newLeft * --------- = --------- * oldZoom newZoom */ //canvasWrapper.scrollLeft = (scrollLeft*zoom)/oldZoom; //canvasWrapper.scrollTop = (scrollTop*zoom)/oldZoom; } // ...
通过上述修改,你可以尝试解决在调整大小屏幕时Canvas闪烁的问题。希望能对你有所帮助!
```
解决 无用评论 打赏 举报