问题描述
首先,我从一个空白的白色画布开始,它代表背景画布。 当用户上传图片时,该图片将被设置为全尺寸作为背景图片。 现在,我想为用户提供多种工具来操作相对于父背景画布上传的图像。这些工具是:
这是我的 ReferenceGrid.js 文件的样子:
import React,{useState,useEffect} from 'react'
const ReferenceGrid = ({onHandleSubmit}) => {
var bounds = null;
var ctx = null;
var hasLoaded = false;
var startX = 0;
var startY = 0;
var mouseX = 0;
var mouseY = 0;
let isDragging = false;
let dragStartPosition = [];
let imgHeight;
let imgWidth;
let imgPosX;
let imgPosY;
var scale = 1.5;
var originx = 0;
var originy = 0;
function onBgDown (e){
let cs = bgCanvasRef.current;
bounds = cs.getBoundingClientRect();
imgHeight = imageObjRef.current.height;
imgWidth = imageObjRef.current.width;
imgPosX = imagePosition.current[0];
imgPosY = imagePosition.current[1];
if ((mouseX >= imgPosX && mouseX <= imgWidth + imgPosX) && (mouseY >= imgPosY && mouseY <= imgHeight + imgPosY)){
isDragging = true;
dragStartPosition = [mouseX - imagePosition.current[0],mouseY - imagePosition.current[1]]
}
}
function onBgUp (e){
let cs = bgCanvasRef.current;
bounds = cs.getBoundingClientRect();
mouseX = e.clientX - bounds.left;
mouseY = e.clientY - bounds.top;
isDragging = false;
dragStartPosition = [];
}
function onBgMove (e){
let cs = bgCanvasRef.current;
bounds = cs.getBoundingClientRect();
mouseX = e.clientX - bounds.left;
mouseY = e.clientY - bounds.top;
imgHeight = imageObjRef.current && imageObjRef.current.height;
imgWidth = imageObjRef.current && imageObjRef.current.width;
imgPosX = imagePosition.current[0];
imgPosY = imagePosition.current[1];
if ((mouseX >= imgPosX && mouseX <= imgWidth + imgPosX) && (mouseY >= imgPosY && mouseY <= imgHeight + imgPosY)){
cs.style.cursor = "all-scroll"
}
else {
cs.style.cursor = "default"
}
if(isDragging){
imagePosition.current = [mouseX - dragStartPosition[0],mouseY - dragStartPosition[1]];
window.requestAnimationFrame(drawBgImage);
}
}
function onBgOut (e){
isDragging = false;
}
function onBgMousewheel (e){
console.log("SCROLLED WITH MOUSE WHEEL: ",e.wheelDelta)
//let cs = bgCanvasRef.current.getContext("2d");
var mousex = e.clientX - bgCanvasRef.offsetLeft;
var mousey = e.clientY - bgCanvasRef.offsetTop;
var wheel = e.wheelDelta / 120; //n or -n
//according to Chris comment
var zoom = Math.pow(1 + Math.abs(wheel) / 2,wheel > 0 ? 1 : -1);
bgCanvasRef.current.getContext("2d").translate(
originx,originy
);
bgCanvasRef.current.getContext("2d").scale(zoom,zoom);
bgCanvasRef.current.getContext("2d").translate(
-(mousex / scale + originx - mousex / (scale * zoom)),-(mousey / scale + originy - mousey / (scale * zoom))
);
originx = (mousex / scale + originx - mousex / (scale * zoom));
originy = (mousey / scale + originy - mousey / (scale * zoom));
scale *= zoom;
//bgCanvasRef.current.getContext("2d").clearRect(0,bgCanvasRef.current.width,bgCanvasRef.current.height);
window.requestAnimationFrame(drawBgImage);
}
const onLoadFunc = () => {
let bgCanvas = bgCanvasRef.current;
bgCanvas.width = 1200;
bgCanvas.height = 600;
bgCanvas.onmousedown = onBgDown;
bgCanvas.onmouseup = onBgUp;
bgCanvas.onmousemove = onBgMove;
bgCanvas.onmouSEOut = onBgOut;
bgCanvas.addEventListener('wheel',onBgMousewheel,{passive: true});
bounds = bgCanvas.getBoundingClientRect();
ctx = bgCanvas.getContext("2d");
ctx.fillStyle = "white";
ctx.fillRect(0,bgCanvas.width,bgCanvas.height);
bgCanvas && console.log("canvas loaded")
}
const loadImage = (path) => {
let bgImage = new Image();
let promise = new Promise((resolve,reject) => {
bgImage.onload = () => resolve(bgImage);
bgImage.onerror = reject;
});
bgImage.src = path;
return promise;
}
function drawBgImage() {
let cs = bgCanvasRef.current;
let ctx = cs.getContext("2d");
ctx.clearRect(0,cs.width,cs.height);
ctx.save();
ctx.setTransform(1,1,0);
ctx.translate( 1200/2,600/2 );
ctx.rotate( angle * Math.PI / 180 );
ctx.translate( -(1200/2),-(600/2) );
imageObjRef.current && ctx.drawImage(imageObjRef.current,imagePosition.current[0],imagePosition.current[1]);
ctx.restore();
}
const onChangeInputFile = (e) => {
if (e.target.files){
console.log("FILE UPLOADED: ",e.target.files[0])
setInputFile(e.target.files[0]);
}
}
const [inputFile,setInputFile] = useState();
const imageRef = React.useRef();
const [editimage,setEditimage] = useState(false);
const [angle,setAngle] = useState(0);
const bgCanvasRef = React.useRef();
const imagePosition = React.useRef([]);
const imageObjRef = React.useRef();
useEffect(() => {
imageRef.current = inputFile;
if(inputFile){
imagePosition.current = [0,0];
let imgSrc = imageRef.current ? URL.createObjectURL(imageRef.current) : URL.createObjectURL(inputFile);
loadImage(imgSrc).then((image) => {
imageObjRef.current = image;
drawBgImage();
});
}
},[inputFile])
useEffect(() => {
//console.log("REDRAWN AFTER STATE SET",angle);
window.requestAnimationFrame(drawBgImage);
},[angle])
useEffect(() => {
console.log("------------- RENDERING REFERENCEGRID --------------")
onLoadFunc();
},[])
return (
<Wrapper>
<h5>Reference Grid</h5>
<input onChange={(e) => onChangeInputFile(e)} type="file" id="input-img" accept=".png,.jpg,.jpeg"></input>
<button hidden={!inputFile} onClick={() => setEditimage(!editimage)}>{editimage ? "Bild sichern" : "Bild bearbeiten"}</button>
{ editimage &&
<input type="number" step="0.01" min="-180" max="180" value={angle} onChange={(e) => setAngle(e.target.value)} placeholder="Winkel"></input>
}
<CanvasWrapper>
<Canvas ref={bgCanvasRef} id="bgCanvas"></Canvas>
</CanvasWrapper>
</Wrapper>
)
}
export default ReferenceGrid
我想在滚动鼠标滚轮时更改 bgCanvas 的上下文,以便将其转换为另一个比例。 我现在的问题是,当我尝试缩放/变换时,更改角度时画布的上下文与上下文发生冲突。 为了转换画布上下文,我应该在绘制图像之前恢复保存的上下文。但是为了通过用户输入绘制旋转的图像,必须在我这样绘制图像后恢复上下文:
context.save();
// Use the identity matrix while clearing the canvas
context.setTransform(1,0);
context.clearRect(0,canvas.width,canvas.height);
// Restore the transform
context.restore();
// Draw on transformed context
context.drawImage(imageObj,300,300);
那么现在我如何设置我的 bgCanvas 的上下文,这样既可以在用户输入角度上旋转,又可以在用户滚动时进行变换和“缩放”?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)