任务是制作一个“屏幕放大镜”的类似物,以便在画布上使用它,您可以在画布上绘图。
保存的点是预先从数据库中加载的,并且需要增加它们。我对 Js 不是很强,所以我开始寻找现成的解决方案,但我发现只有使用图像、文本或画布中加载的静态图像的选项。
您能告诉我如何实施吗?
我想实现这样的目标,同时不使用图像,而仅使用预加载的点(它们是动态的)。
代码片段不是我的,取自codepen。
class Experience {
constructor(container) {
this.canvas = document.createElement("canvas");
container.appendChild(this.canvas);
this.context = this.canvas.getContext("2d");
const fps = 60;//60
this.fpsInterval = 1000 / fps;
this.then = Date.now();
this.point = { x: 0, y: 0 };
this.distPoint = { x: 0, y: 0 };
this.pos = { x: 0, y: 0 };
this.resize();
this.bind();
this.image = new Image();
this.image.src = "https://robindelaporte.fr/codepen/slide.jpg";
this.image.onload = () => {
this.loop();
};
}
bind() {
window.addEventListener("resize", this.resize.bind(this), false);
this.canvas.addEventListener("mousemove", this.onMouseMove.bind(this));
this.canvas.addEventListener("touchmove", this.onTouchMove.bind(this));
}
render() {
this.clear();
// this.context.save()
this.context.drawImage(this.image, 0, 0, this.canvas.width, this.canvas.height);
this.pos.x += (this.point.x - this.pos.x) * 0.2;
this.pos.y += (this.point.y - this.pos.y) * 0.2;
this.context.save();
this.context.beginPath();
this.context.arc(this.pos.x, this.pos.y, this.canvas.height * 0.15, 0, Math.PI * 2, true);
this.context.strokeStyle = "white";
this.context.lineWidth = 6;
// this.context.globalCompositeOperation = "screen";
this.context.stroke();
this.context.closePath();
this.context.clip();
this.context.drawImage(
this.image,
-this.canvas.width * 0.2 +
(this.canvas.width - this.canvas.width * 1.4) * (this.distPoint.x * 1), //0.05,
-this.canvas.height * 0.2 +
(this.canvas.height - this.canvas.height * 1.4) * (this.distPoint.y * 1), //0.05,
this.canvas.width * 1.4,
this.canvas.height * 1.4
);
// this.context.opacity = 1;
this.context.restore();
}
loop() {
this.raf = window.requestAnimationFrame(this.loop.bind(this));
const now = Date.now();
const delta = now - this.then;
if (delta > this.fpsInterval) {
// this.context.clearRect( 0, 0, this.canvas.width, this.canvas.height )
this.render();
this.then = now;
}
}
onMouseMove(ev){
var rect = this.canvas.getBoundingClientRect();
this.point = {
x:
(ev.clientX - 7) - rect.left,
y: (ev.clientY - 7) - rect.top
};
this.distPoint = {
x: (this.point.x - this.canvas.width * 0.5) / this.canvas.width,
y: (this.point.y - this.canvas.height * 0.5) / this.canvas.height
};
}
onTouchMove(ev){
var rect = this.canvas.getBoundingClientRect();
this.point = {
x:
ev.touches[0].clientX - rect.left,
y: ev.touches[0].clientY - rect.top
};
this.distPoint = {
x: (this.point.x - this.canvas.width * 0.5) / this.canvas.width,
y: (this.point.y - this.canvas.height * 0.5) / this.canvas.height
};
}
resize() {
this.canvas.width = window.innerWidth * 0.7;
this.canvas.height = window.innerWidth * 0.7 / 1.77;
this.screen = {
center: { x: this.canvas.width / 2, y: this.canvas.height / 2 }
};
//this.reset();
}
clear(){
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
reset() {
window.cancelAnimationFrame(this.raf);
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.loop();
}
}
const experience = new Experience(document.body);
body {
width: 100vw;
height: 100vh;
background: #fff;
margin: 0;
padding: 0;
position: relative;
overflow: hidden;
}
canvas {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 7px solid rgba(255, 255, 255, .1);
box-shadow: 0px 0px 10px #00000038;
cursor: pointer;
box-sizing: border-box;
}
.info {
position: absolute;
bottom: 1rem;
left: 0;
font-family: monospace;
width: 100%;
text-align: center;
font-size: 1rem;
}
在为我的任务编辑此代码时,我遇到了一个问题,此代码在画布本身上绘制放大镜并再次绘制图像,这不太适合数据库中的动态点(它们闪烁)
您可以使用第二个画布来放大:
UPD
为了避免模糊画布分辨率增加