如何使用JavaScript实现类似Facebook封面的拖拽图片位置保存功能?
实现方案及注意事项
位置处理的特殊要求
- 首先需要把
background-position-y的返回值转成纯数值,该属性默认返回带px单位的字符串,直接做数值计算会出现异常 - 拖拽位移更新必须加
mouseDown状态判断,你现有代码的mousemove事件未加判断,未按下鼠标时也会触发位置修改,属于逻辑漏洞 - 存储当前位置的变量需要在每次拖拽位移更新后同步修改,否则复位逻辑会回到初始位置,不符合交互逻辑
- 绘制导出用的canvas时,图片的绘制偏移量必须和实际设置的
background-position完全一致,否则导出结果和页面显示效果不符 - 跨域图片需要服务端配置CORS规则,否则浏览器会拦截canvas的导出操作,触发跨域安全报错
保存功能实现思路
你当前用背景图实现拖拽效果,保存时需要借助canvas把调整后的效果绘制出来,再触发浏览器下载,具体步骤如下:
- 补全拖拽逻辑,实时更新背景图的y轴偏移
- 给保存按钮绑定点击事件,创建和
#image容器尺寸相同的canvas元素 - 按当前的背景偏移量把图片绘制到canvas上
- 将canvas转成dataURL或者blob格式,动态创建a标签触发下载
完整可运行代码
HTML代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <style> #image { width: 860px; height: 550px; background-repeat: no-repeat; background-position: 0 0; cursor: grab; } #image:active { cursor: grabbing; } </style> <div id="image"></div> <button type="button" id="save" class="modal-add-btn">Save</button>
JS代码
var imgWidth; var imgHeight; var img = new Image(); // 跨域图片需要加这个配置,配合服务端CORS使用 img.crossOrigin = 'anonymous'; img.src = 'https://picsum.photos/860/550/?image=316'; var start_y; var curPosY = 0; // 直接用数值存y轴偏移,避免单位转换问题 var mouseDown = false; $(img).on('load', function() { imgWidth = img.width; imgHeight = img.height; $('#image').css('background-image', 'url(' + img.src + ')'); }); $('#image').mousedown( function(e) { mouseDown = true; start_y = e.clientY; }); $(document).mouseup( function() { mouseDown = false; }); $(document).mousemove( function(e) { if (!mouseDown) return; var moveDistance = e.clientY - start_y; curPosY += moveDistance; start_y = e.clientY; $('#image').css('background-position-y', curPosY + 'px'); }); // 保存按钮逻辑 $('#save').on('click', function() { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); // canvas尺寸和容器一致 var container = $('#image')[0]; canvas.width = container.clientWidth; canvas.height = container.clientHeight; // 按当前偏移绘制图片 ctx.drawImage(img, 0, curPosY, imgWidth, imgHeight); // 触发下载 var link = document.createElement('a'); link.download = '拖拽调整后图片.png'; link.href = canvas.toDataURL('image/png'); link.click(); })
内容的提问来源于stack exchange,提问作者sana rana
相关产品推荐
相关产品推荐

