文章目录
纯js不失真放大缩小拖拽canvas
视频
<div id="canvasrr" style="
width: 100%;
height: 100%;
"><canvas></canvas></div>
<script>
// //绑定canvas画布工具
var canvas_set=function(div_id){
//获取画布对象
let div_obj=document.getElementById(div_id);
//获取canvas对象
let canvas_obj=div_obj.firstChild
//为canvas对象创建css:用来控制canvas对象的大小
let canvas_obj_class_name=div_id+'_canvas_class'//定义css类名
canvas_obj.className=canvas_obj_class_name//赋值类名
canvas_obj.style.width='100%'
canvas_obj.style.height='100%'
canvas_obj.style.position='absolute'
canvas_obj.style.top='0px'
canvas_obj.style.left='0px'
let data_obj={};
data_obj.img = new Image();
data_obj.div=div_obj
data_obj.className=canvas_obj_class_name;
data_obj.canvas=canvas_obj
data_obj.scale=1;//当前canvas的缩放比例
data_obj.minScale=0.05;//scale的最小缩放比例
data_obj.maxScale=100;//scale的最大缩放比例
data_obj.startX=0;//鼠标滚动操作的时候的x值
data_obj.startY=0;//鼠标滚动操作的时候的y值
data_obj.temp_start_x=0//鼠标左击按下操作的时候鼠标的x值
data_obj.temp_start_y=0;//鼠标左击按下操作的时候鼠标的y值
data_obj.offsetx=0//鼠标左击按下操作的时候鼠标偏移的x值
data_obj.offsety=0;//鼠标左击按下操作的时候鼠标偏移的y值
data_obj.mousedown_flag=false;//鼠标是否按下操作
data_obj.x_val=0;//鼠标历史拖动x轴的值
data_obj.y_val=0;//鼠标历史拖动y轴的值
//判断是否已经创建了这个style节点
let styleobj_id=div_id+'_canvas_style_id'
if (document.getElementById(styleobj_id)==null){
let styleobj = document.createElement('style');//创建style节点
styleobj.innerHTML=`
.${data_obj.className} {
transform: scale(1.0);
} `;//设置初始放大倍数为1.0
document.getElementsByTagName('head')[0].appendChild(styleobj)//将刚才创建的节点添加进<head>节点内
styleobj.id=styleobj_id;
data_obj.styleobj=styleobj
}else{
let styleobj = document.getElementById(styleobj_id);
data_obj.styleobj=styleobj
}
let ctx = canvas_obj.getContext('2d');
data_obj.ctx=ctx;
//绑定绘画函数
let draw_img=fangdasuoxiaohuabu_draw_img(data_obj)
data_obj.draw_img=draw_img
//绑定按下鼠标左键函数
let mousedown=fangdasuoxiaohuabu_mousedown(data_obj)
data_obj.mousedown=mousedown
data_obj.div.addEventListener('mousedown', mousedown);
//绑定鼠标移动函数
let mousemove=fangdasuoxiaohuabu_mousemove(data_obj)
data_obj.mousemove=mousemove
data_obj.div.addEventListener('mousemove', mousemove);
//绑定释放鼠标键函数
let mouseup=fangdasuoxiaohuabu_mouseup(data_obj)
data_obj.mouseup=mouseup
data_obj.div.addEventListener('mouseup', mouseup);
//绑定鼠标滚轮操作函数
let handleScroll=fangdasuoxiaohuabu_handleScroll(data_obj)
data_obj.handleScroll=handleScroll
data_obj.div.addEventListener('wheel', handleScroll);
//绑定点击canvas修改图片函数:弹框输入地址
let changeimg=fangdasuoxiaohuabu_changeimg(data_obj)
data_obj.changeimg=changeimg
///绑定点击canvas修改图片函数:传参输入地址
let changeimg2=fangdasuoxiaohuabu_changeimg2(data_obj)
data_obj.changeimg2=changeimg2
//绑定重置函数
let reset=fangdasuoxiaohuabu_reset(data_obj)
data_obj.reset=reset
//绑定点击鼠标右键函数 div
let contextmenu2=fangdasuoxiaohuabu_contextmenu2(data_obj)
data_obj.contextmenu=contextmenu2
data_obj.div.addEventListener('contextmenu',contextmenu2)
//绑定点击鼠标右键函数 canvas
let contextmenu=fangdasuoxiaohuabu_contextmenu(data_obj)
data_obj.contextmenu=contextmenu
data_obj.canvas.addEventListener('contextmenu',contextmenu)
return data_obj
}
function fangdasuoxiaohuabu_draw_img(data_obj){
let now_data_obj=data_obj;
let res_func=function(e){
//清空画布
now_data_obj.ctx.clearRect(0, 0, now_data_obj.canvas.width, now_data_obj.canvas.height);
//放大画布
now_data_obj.styleobj.innerHTML=`
.${data_obj.className} {
transform: scale(${data_obj.scale});
} `;
console.log('fangdasuoxiaohuabu_draw_img',now_data_obj.scale)
// let parentNode = canvas.parentNode;
// canvas.width =parseInt( parentNode.offsetWidth ); // 实际渲染像素
// canvas.height = parseInt(parentNode.offsetHeight ); // 实际渲染像素
// console.log('画布大小:','height:',canvas.width,'width:', canvas.height)
// canvas.style.height='100%'//`${100/scale}%`//parseInt(parentNode.offsetHeight/scale)// 获取父节点的高度/scale
// canvas.style.width='100%'//`${100/scale}%`//parseInt(parentNode.offsetWidth/scale);// 获取父节点的宽度
// canvas.style.top=200-parseInt(parentNode.offsetHeight/scale)/2;// 获取父节点的宽度
// canvas.style.left=200-parseInt(parentNode.offsetWidth/scale)/2;// 获取父节点的宽度
//这个函数在canvas上绘制图像。在此处,img是一个图像对象,-img.width / 2和-img.height / 2是图像放置的位置。
// console.log(now_img_info['x'],now_img_info.y,-img.width / 2,-img.height / 2)
// ctx.draw_img(img, -img.width / 2+now_img_info.x, -img.height / 2+now_img_info.y);
// ctx.draw_img(img, -img.width / 2-now_img_info.x, -img.height / 2-now_img_info.y);
// 绘制缩放后的图形
now_data_obj.ctx.drawImage(now_data_obj.img,0,0);
}
return res_func
}
//绑定鼠标滚动操作的函数
function fangdasuoxiaohuabu_handleScroll(data_obj){
let now_data_obj=data_obj;
let res=function(e) {
e.preventDefault();//阻止默认事件
data_obj.scale += 0.1 * (e.deltaY < 0 ? 1 : -1);
if(data_obj.scale < data_obj.minScale) data_obj.scale = data_obj.minScale;
if(data_obj.scale > data_obj.maxScale) data_obj.scale = data_obj.maxScale;
data_obj.startX = e.clientX; // 记录鼠标按下的位置
data_obj.startY = e.clientY;
// console.log(e.deltaY,startX,startY)
data_obj.draw_img();
}
return res
}
//绑定鼠标左键按下操作的函数
function fangdasuoxiaohuabu_mousedown(data_obj){
let now_data_obj=data_obj;
let res =function(e) {
now_data_obj.mousedown_flag = true; // 开始拖动canvas
now_data_obj.temp_start_x = e.clientX; // 记录鼠标按下的位置
now_data_obj.temp_start_y = e.clientY;
now_data_obj.offsetx = now_data_obj.canvas.offsetLeft; // canvas的偏移量
now_data_obj.offsety = now_data_obj.canvas.offsetTop;
}
return res
}
//绑定鼠标移动操作的函数
function fangdasuoxiaohuabu_mousemove(data_obj){
let now_data_obj=data_obj;
let res=function(e) {
if (!now_data_obj.mousedown_flag) return; // 如果未开始拖动,则返回
var dx = parseInt((1/data_obj.scale)*(data_obj.temp_start_x-e.clientX)) ; // 计算鼠标移动的距离
var dy = parseInt((1/data_obj.scale)*(data_obj.temp_start_y-e.clientY));
var dx = parseInt(1*(data_obj.temp_start_x-e.clientX)) ; // 计算鼠标移动的距离
var dy = parseInt(1*(data_obj.temp_start_y-e.clientY));
// console.log('dx:',dx,'(1/scale):',(1/scale))
// console.log('temp_start_y,e.clientY',temp_start_y,e.clientY)
data_obj.temp_start_y=e.clientY
// console.log('temp_start_y,e.clientY',temp_start_y,e.clientY)
data_obj.temp_start_x=e.clientX
// console.log('dx:',dx)
data_obj.x_val= data_obj.x_val+dx
data_obj.y_val= data_obj.y_val+dy
// console.log('now_img_info.x :',now_img_info.x)
data_obj.canvas.style.left = -data_obj.x_val + 'px'; // 更新canvas的left属性,注意此处应为相对于窗口的偏移量
data_obj.canvas.style.top = -data_obj.y_val + 'px'; // 更新canvas的top属性,注意此处应为相对于窗口的偏移量
data_obj.startX = e.clientX; // 更新鼠标的位置
data_obj.startY = e.clientY;
data_obj.draw_img(); // 重新绘制canvas上的内容
}
return res
}
//绑定鼠标左键按下后释放的操作函数
function fangdasuoxiaohuabu_mouseup(data_obj){
let now_data_obj=data_obj;
let res=function(e) {
now_data_obj.mousedown_flag = false; // 停止拖动canvas
now_data_obj.startX = null; // 清空鼠标的位置
now_data_obj.startY = null;
now_data_obj.offsetX = null; // 清空canvas的偏移量
now_data_obj.offsetY = null;
now_data_obj.temp_start_x;
now_data_obj.temp_start_y;
now_data_obj.draw_img(); // 重新绘制canvas上的内容
};
return res
}
//弹出对话框输入图片路径
function fangdasuoxiaohuabu_changeimg(data_obj){
let now_data_obj=data_obj;
let res=function() {
data_obj.img.src = prompt("请输入新的图片URL:");
now_data_obj.reset()
}
return res
}
//传入图片路径修改
function fangdasuoxiaohuabu_changeimg2(data_obj){
let now_data_obj=data_obj;
let res=function(data) {
data_obj.img.src = data;
now_data_obj.reset()
}
return res
}
//重置参数
function fangdasuoxiaohuabu_reset(data_obj){
let now_data_obj=data_obj;
let res=function() {
data_obj.scale=1;//当前canvas的缩放比例
data_obj.minScale=0.05;//scale的最小缩放比例
data_obj.maxScale=100;//scale的最大缩放比例
data_obj.startX=0;//鼠标滚动操作的时候的x值
data_obj.startY=0;//鼠标滚动操作的时候的y值
data_obj.temp_start_x=0//鼠标左击按下操作的时候鼠标的x值
data_obj.temp_start_y=0;//鼠标左击按下操作的时候鼠标的y值
data_obj.offsetx=0//鼠标左击按下操作的时候鼠标偏移的x值
data_obj.offsety=0;//鼠标左击按下操作的时候鼠标偏移的y值
data_obj.mousedown_flag=false;//鼠标是否按下操作
data_obj.x_val=0;//鼠标历史拖动x轴的值
data_obj.y_val=0;//鼠标历史拖动y轴的值
data_obj.draw_img();
}
return res
}
//鼠标右击 canvas右击
function fangdasuoxiaohuabu_contextmenu(data_obj){
let now_data_obj=data_obj;
let res=function(e) {
e.preventDefault(); // 阻止默认的上下文菜单
alert('Right-click detected at ' + e.clientX + ',' + e.clientY);
}
return res
}
//鼠标右击2 div右击
function fangdasuoxiaohuabu_contextmenu2(data_obj){
let now_data_obj=data_obj;
let res=function(e) {
e.preventDefault(); // 阻止默认的上下文菜单
alert('Right-click detected at ' + e.clientX + ',' + e.clientY);
}
return res
}
var test=canvas_set('canvasrr')
test.img.src = 'C:\\Users\\Administrator.BF-202310091844\\Desktop\\ddd.jpg'
test.img.onload = test.draw_img;
</script>