| 
			 
					阅读:749回复:11
				 
				让deepseek为MouseGestures2_e10s.uc.js添加鼠标轨迹功能方案[color=var(--dsw-alias-label-secondary)] 原始脚本MouseGestures2_e10s.uc.jshttps://github.com/alice0775/userChrome.js/blob/master/143/MouseGestures2_e10s.uc.js 嗯,用户提供了一个很长的Firefox用户脚本,想要添加鼠标轨迹功能。这个脚本本身已经实现了鼠标手势、滚轮手势和摇摆手势,但没有视觉反馈。 需要先理解脚本的现有结构。这是一个复杂的鼠标手势脚本,通过监听鼠标事件来触发各种浏览器操作。用户想要添加的是绘制鼠标移动轨迹的功能。从代码结构来看,主要需要修改的是_progressGesture方法,在这里添加轨迹绘制逻辑比较合适。需要创建一个半透明的canvas覆盖层来绘制线条,同时要注意性能优化和跨浏览器兼容性。 考虑到用户可能想要自定义轨迹颜色和粗细,应该把这些作为可配置选项。还需要在手势结束时清理canvas,避免残留痕迹。因为这是对现有脚本的增强,应该尽量保持原有逻辑不变,只是添加视觉反馈功能。需要特别注意事件处理和性能问题,避免影响浏览器流畅度。 [color=var(--dsw-alias-label-primary)] 我可以为这个脚本添加鼠标轨迹绘制功能。这将在您执行鼠标手势时在屏幕上绘制出可视化的轨迹线,提供更好的视觉反馈。 以下是需要添加的代码部分: // 在 ucjsMouseGestures 对象中添加以下属性和方法
    
// == config ==
// 新增配置选项
showMouseTrail: true,        // 显示鼠标轨迹
trailColor: "rgba(255,165,0,0.7)", // 轨迹颜色 (橙色半透明)
trailWidth: 3,               // 轨迹线宽
trailLength: 20,             // 轨迹长度(点数)
    
// 在 init 方法中添加
init: function() {
  // 现有代码...
      
  // 添加轨迹画布
  if (this.showMouseTrail) {
    this._createTrailCanvas();
  }
},
    
// 添加创建轨迹画布的方法
_createTrailCanvas: function() {
  this._trailCanvas = document.createElement("canvas");
  this._trailCanvas.id = "ucjs-mouse-gestures-trail";
  this._trailCanvas.style.cssText = `
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 9999;
  `;
  document.documentElement.appendChild(this._trailCanvas);
      
  this._trailCtx = this._trailCanvas.getContext("2d");
  this._trailPoints = [];
      
  // 调整画布大小以适应窗口
  this._resizeTrailCanvas();
  window.addEventListener("resize", () => this._resizeTrailCanvas());
},
    
// 调整画布大小
_resizeTrailCanvas: function() {
  this._trailCanvas.width = window.innerWidth;
  this._trailCanvas.height = window.innerHeight;
},
    
// 在 _startGesture 方法中添加
_startGesture: function(event) {
  // 现有代码...
      
  // 初始化轨迹
  if (this.showMouseTrail) {
    this._trailPoints = [];
    this._addTrailPoint(event.screenX, event.screenY);
    this._clearTrail();
  }
},
    
// 在 _progressGesture 方法中添加
_progressGesture: function(event) {
  // 现有代码...
      
  // 添加轨迹点
  if (this.showMouseTrail) {
    this._addTrailPoint(event.screenX, event.screenY);
    this._drawTrail();
  }
},
    
// 在 _stopGesture 方法中添加
_stopGesture: function(event) {
  // 现有代码...
      
  // 清除轨迹
  if (this.showMouseTrail) {
    setTimeout(() => this._clearTrail(), 300); // 短暂延迟后清除
  }
},
    
// 添加轨迹相关方法
_addTrailPoint: function(x, y) {
  this._trailPoints.push({x, y});
  // 保持轨迹长度
  if (this._trailPoints.length > this.trailLength) {
    this._trailPoints.shift();
  }
},
    
_drawTrail: function() {
  this._clearTrail();
      
  if (this._trailPoints.length < 2) return;
      
  this._trailCtx.strokeStyle = this.trailColor;
  this._trailCtx.lineWidth = this.trailWidth;
  this._trailCtx.lineJoin = "round";
  this._trailCtx.lineCap = "round";
  this._trailCtx.beginPath();
      
  // 绘制轨迹线
  this._trailCtx.moveTo(this._trailPoints[0].x, this._trailPoints[0].y);
  for (let i = 1; i < this._trailPoints.length; i++) {
    this._trailCtx.lineTo(this._trailPoints[i].x, this._trailPoints[i].y);
  }
      
  this._trailCtx.stroke();
},
    
_clearTrail: function() {
  this._trailCtx.clearRect(0, 0, this._trailCanvas.width, this._trailCanvas.height);
},
    
// 在 uninit 方法中添加清理代码
uninit: function() {
  // 现有代码...
      
  // 移除轨迹画布
  if (this._trailCanvas && this._trailCanvas.parentNode) {
    this._trailCanvas.parentNode.removeChild(this._trailCanvas);
  }
},这些修改将为您的鼠标手势脚本添加可视化的轨迹功能。轨迹会在您执行手势时显示,并在手势完成后短暂保留后消失。 您可以通过修改配置选项来自定义轨迹的外观: •  showMouseTrail : 启用/禁用轨迹显示  •  trailColor : 更改轨迹颜色  •  trailWidth : 调整轨迹线宽  •  trailLength : 控制轨迹的长度(点数)   这个功能不会影响现有的手势识别逻辑,只是添加了视觉反馈。				 | 
	|
| 
			 1楼# 
								发布于:2025-09-09 18:07				
			
					问:查看了原始脚本里有3个init: function() {   。需要修改代码里也有2个init: function() {  怎么办?				 
							 | 
	|
| 
			 2楼# 
								发布于:2025-09-09 18:12				
			
					我们注意到原始脚本中有多个init函数,分别属于不同的对象。我们需要将轨迹绘制功能添加到主对象ucjsMouseGestures的init中,并确保在适当的时候创建和销毁画布。 由于原始脚本较长,我将只提供需要添加的代码部分,并指出应该添加的位置。 
 
							1. 首先,在ucjsMouseGestures对象的配置部分添加轨迹绘制的配置选项。 2. 在ucjsMouseGestures的init方法中添加创建轨迹画布的代码。 3. 在_startGesture、_progressGesture和_stopGesture方法中添加轨迹绘制的逻辑。 4. 在uninit方法中移除画布。 注意:由于轨迹绘制需要屏幕坐标,而我们在事件中获取的是screenX和screenY,但是画布是相对于窗口的,所以需要将screen坐标转换为窗口的client坐标。 但是,由于画布是固定定位且覆盖整个窗口,我们可以使用screenX和screenY减去窗口的位置来得到画布内的坐标。然而,由于screenX和screenY是相对于整个屏幕的,而画布覆盖整个窗口,我们需要考虑窗口的滚动和位置。 实际上,由于画布是fixed定位,并且覆盖整个视口,我们可以使用clientX和clientY,但是事件对象中我们只有screenX和screenY。因此,我们需要计算窗口的位置。 另一种方法是使用clientX和clientY,但是注意在mousemove事件中,我们是在tabpanels上监听的,而tabpanels可能不是全窗口的,所以事件对象中的clientX和clientY是相对于窗口的,可以直接使用。 但是,在原始脚本中,我们在处理手势时使用的是screenX和screenY。为了保持一致,我们仍然使用screenX和screenY,然后转换为画布坐标。 然而,画布是固定在视口中的,所以我们需要将screen坐标转换为视口坐标: 视口X = screenX - window.screenX 视口Y = screenY - window.screenY 但是,window.screenX和screenY是窗口相对于屏幕的位置,但是存在多显示器的问题,并且不同浏览器的实现可能不一致。 考虑到兼容性,我们可以改用clientX和clientY,因为clientX和clientY是相对于窗口的,而我们的画布也是相对于窗口的。 因此,我建议修改轨迹绘制使用clientX和clientY。 但是,在原始脚本的handleEvent中,我们只记录了screenX和screenY。为了获取client坐标,我们需要在事件处理中同时记录clientX和clientY。 不过,为了不破坏原有逻辑,我们可以在轨迹绘制时进行坐标转换,或者修改事件处理同时记录client坐标。 由于原有逻辑都是基于screen坐标,我们不想改变原有逻辑,所以我们在轨迹绘制时进行坐标转换: 视口X = screenX - window.screenX 视口Y = screenY - window.screenY 但是,window.screenX和screenY在某些情况下可能不准确(例如窗口有边框时)。 因此,我们可以使用另一种方法:在画布上使用绝对定位,然后使用screenX和screenY减去画布相对于屏幕的偏移。 但是,画布是fixed定位,覆盖整个视口,所以画布的左上角就是视口的左上角,而screenX和screenY是屏幕坐标,视口左上角的屏幕坐标是(window.screenX, window.screenY)。因此,画布上的点应该是(screenX - window.screenX, screenY - window.screenY)。 但是,这里有一个问题,window.screenX和screenY是整数,而屏幕可能有缩放,所以还需要考虑设备像素比。 为了避免复杂计算,我建议改用clientX和clientY,因为clientX和clientY是相对于视口的,而且我们的画布也是相对于视口的。 因此,我们需要在事件处理时同时记录client坐标。我们可以在_startGesture和_progressGesture中同时记录clientX和clientY,然后用于轨迹绘制。 但是,为了尽量减少对原有代码的修改,我们可以在轨迹绘制函数中通过事件对象获取client坐标,但是事件对象在轨迹绘制时已经不可用了。 所以,我们修改思路:在_startGesture和_progressGesture中,除了记录screen坐标,也记录client坐标,然后用client坐标来绘制轨迹。 修改如下: 1. 在ucjsMouseGestures对象中添加client坐标的记录:_lastClientX: 0, _lastClientY: 0, 2. 在_startGesture中记录client坐标:this._lastClientX = event.clientX; this._lastClientY = event.clientY; 3. 在_progressGesture中记录client坐标,并使用client坐标来添加轨迹点。 4. 这样,轨迹绘制就可以直接使用client坐标,无需转换。 但是,注意:在Fullscreen模式下,client坐标和画布的位置关系可能发生变化。不过,由于画布是fixed定位,并且宽高设置为100%,应该可以覆盖全屏。 考虑到这些,我们决定使用client坐标来绘制轨迹。 以下是具体的代码添加和修改步骤: 第一步:在ucjsMouseGestures对象的配置部分添加轨迹绘制的配置选项。 第二步:在ucjsMouseGestures的init方法中创建画布。 第三步:修改_startGesture,同时记录client坐标。 第四步:修改_progressGesture,同时记录client坐标,并添加轨迹点(使用client坐标)。 第五步:在_stopGesture中清除轨迹。 第六步:在uninit中移除画布。 第七步:实现轨迹绘制的相关方法。 由于原始代码很长,我将只展示需要添加和修改的代码部分。 注意:由于我们是在浏览器环境中,需要确保画布的样式不会干扰页面操作(pointer-events: none)。 下面是代码修改的具体内容: 您指出了一个重要的问题。原始脚本中有多个 init 函数,属于不同的对象。让我重新组织代码,确保正确地添加鼠标轨迹功能,而不会与其他部分的初始化冲突。 以下是修改后的代码,我将在 ucjsMouseGestures 对象的适当位置添加鼠标轨迹功能:  | 
	|
| 
			 3楼# 
								发布于:2025-09-09 18:14				
			// 在 ucjsMouseGestures 对象中添加以下配置选项(放在 commands 数组之前)
// == config ==
showMouseTrail: true,        // 显示鼠标轨迹
trailColor: "rgba(255,165,0,0.7)", // 轨迹颜色 (橙色半透明)
trailWidth: 3,               // 轨迹线宽
trailLength: 20,             // 轨迹长度(点数)
// == /config ==
 
// 在 ucjsMouseGestures 对象中添加以下属性和方法
_trailCanvas: null,
_trailCtx: null,
_trailPoints: [],
 
// 修改 ucjsMouseGestures 的 init 方法
init: function() {
  if (AppConstants.platform == "linux")
    Services.prefs.setBoolPref("ui.context_menus.after_mouseup", true);
  this._version = Services.appinfo.version.split(".")[0];
  this._isMac = navigator.platform.indexOf("Mac") == 0;
  gBrowser.tabpanels.addEventListener("mousedown", this, false);
  document.addEventListener("mouseup", this, false);
  gBrowser.tabpanels.addEventListener("contextmenu", this, true);
  if (this.enableWheelGestures)
    window.addEventListener('wheel', this, true);
 
   messageManager.addMessageListener("ucjsMouseGestures_linkURL_isWheelCancel", this);
   messageManager.addMessageListener("ucjsMouseGestures_linkURL_start", this);
   messageManager.addMessageListener("ucjsMouseGestures_linkURLs_stop", this);
   messageManager.addMessageListener("ucjsMouseGestures_linkURL_dragstart", this);
 
   messageManager.addMessageListener("ucjsMouseGestures_executeInChrome", this);
    
   // 添加轨迹画布
   if (this.showMouseTrail) {
     this._createTrailCanvas();
   }
    
   window.addEventListener("unload", this, false);
},
 
// 修改 ucjsMouseGestures 的 uninit 方法
uninit: function() {
  gBrowser.tabpanels.removeEventListener("mousedown", this, false);
  gBrowser.tabpanels.removeEventListener("mousemove", this, false);
  document.removeEventListener("mouseup", this, false);
  gBrowser.tabpanels.removeEventListener("mouseleave", this, false);
  gBrowser.tabpanels.removeEventListener("contextmenu", this, true);
  if (this.enableWheelGestures)
    window.removeEventListener('wheel', this, true);
 
   messageManager.removeMessageListener("ucjsMouseGestures_linkURL_isWheelCancel", this);
   messageManager.removeMessageListener("ucjsMouseGestures_linkURL_start", this);
   messageManager.removeMessageListener("ucjsMouseGestures_linkURLs_stop", this);
   messageManager.removeMessageListener("ucjsMouseGestures_linkURL_dragstart", this);
 
   messageManager.removeMessageListener("ucjsMouseGestures_executeInChrome", this);
    
   // 移除轨迹画布
   if (this._trailCanvas && this._trailCanvas.parentNode) {
     this._trailCanvas.parentNode.removeChild(this._trailCanvas);
   }
    
   window.removeEventListener("unload", this, false);
},
 
// 添加轨迹相关方法
_createTrailCanvas: function() {
  this._trailCanvas = document.createElement("canvas");
  this._trailCanvas.id = "ucjs-mouse-gestures-trail";
  this._trailCanvas.style.cssText = `
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 9999;
  `;
  document.documentElement.appendChild(this._trailCanvas);
   
  this._trailCtx = this._trailCanvas.getContext("2d");
  this._trailPoints = [];
   
  // 调整画布大小以适应窗口
  this._resizeTrailCanvas();
  window.addEventListener("resize", () => this._resizeTrailCanvas());
},
 
_resizeTrailCanvas: function() {
  this._trailCanvas.width = window.innerWidth;
  this._trailCanvas.height = window.innerHeight;
},
 
_addTrailPoint: function(x, y) {
  this._trailPoints.push({x, y});
  // 保持轨迹长度
  if (this._trailPoints.length > this.trailLength) {
    this._trailPoints.shift();
  }
},
 
_drawTrail: function() {
  this._clearTrail();
   
  if (this._trailPoints.length < 2) return;
   
  this._trailCtx.strokeStyle = this.trailColor;
  this._trailCtx.lineWidth = this.trailWidth;
  this._trailCtx.lineJoin = "round";
  this._trailCtx.lineCap = "round";
  this._trailCtx.beginPath();
   
  // 绘制轨迹线
  this._trailCtx.moveTo(this._trailPoints[0].x, this._trailPoints[0].y);
  for (let i = 1; i < this._trailPoints.length; i++) {
    this._trailCtx.lineTo(this._trailPoints[i].x, this._trailPoints[i].y);
  }
   
  this._trailCtx.stroke();
},
 
_clearTrail: function() {
  this._trailCtx.clearRect(0, 0, this._trailCanvas.width, this._trailCanvas.height);
},
 
// 修改 _startGesture 方法
_startGesture: function(event) {
  this._lastX = event.screenX;
  this._lastY = event.screenY;
  this._directionChain = "";
  this._linkdocURLs = [];
  this._linkURLs = [];
  this._selLinkdocURLs = [];
  this._selLinkURLs = [];
   
  // 初始化轨迹
  if (this.showMouseTrail) {
    this._trailPoints = [];
    this._addTrailPoint(event.clientX, event.clientY);
    this._clearTrail();
  }
},
 
// 修改 _progressGesture 方法
_progressGesture: function(event) {
  var x = event.screenX;
  var y = event.screenY;
  var distanceX = Math.abs(x - this._lastX);
  var distanceY = Math.abs(y - this._lastY);
  // minimal movement where the gesture is recognized
  const tolerance = 10;
  if (distanceX < tolerance && distanceY < tolerance) {
    this.statusinfo = this._laststatusinfo;
    return;
  }
  // determine current direction
  var direction;
  if (distanceX > distanceY)
    direction = x < this._lastX ? "L" : "R";
  else
    direction = y < this._lastY ? "U" : "D";
  // compare to last direction
  var lastDirection = this._directionChain.charAt(this._directionChain.length - 1);
  if (direction != lastDirection) {
    this._directionChain += direction;
    let commandName = "";
    for (let command of this.commands) {
      if (command[0].substring(0, 1) == "*") {
        let cmd = command[0].substring(1);
        if (cmd == this._directionChain.substring(this._directionChain.length - cmd.length)) {
          commandName = command[1];
          break;
        }
      }
    }
    if (!commandName)
      for (let command of this.commands) {
        if (!!command[0] && command[0] == this._directionChain){
          commandName = command[1];
          break;
        }
      }
    this.statusinfo = "Gesture: " + this._directionChain + " " + commandName;
  }
  // save current position
  this._lastX = x;
  this._lastY = y;
   
  // 添加轨迹点
  if (this.showMouseTrail) {
    this._addTrailPoint(event.clientX, event.clientY);
    this._drawTrail();
  }
},
 
// 修改 _stopGesture 方法
_stopGesture: function(event) {
  window.messageManager.broadcastAsyncMessage("ucjsMouseGestures_mouseup");
  gBrowser.selectedBrowser.messageManager.sendAsyncMessage("ucjsMouseGestures_linkURLs_request");
  if (!document.hasFocus()) {
    // xxxx workaround
    this._isMouseDownR = false;
    this._isMouseDownL = false;
    this._directionChain = "";
    this._isWheelCanceled = false;
    return;
  }
  if (this._directionChain) {
    this._performAction(event);
    this.statusinfo =  "";
  }
   
  // 清除轨迹
  if (this.showMouseTrail) {
    setTimeout(() => this._clearTrail(), 300); // 短暂延迟后清除
  }
},				 | 
	|
| 
			 4楼# 
								发布于:2025-09-09 18:25				
			
					第一个框需要功力深厚才能修改成功。 
							第二个框测大白菜就可以修改成功。  | 
	|
| 
			 5楼# 
								发布于:2025-09-14 18:32				
			
					以上是添加鼠标轨迹功能方案 一。已知:bug在Firefox内置页面>鼠标轨迹与指针距离较远!
 
							deepseek给了方案 一外挂式的鼠标轨迹,已知:bug在Firefox内置页面>鼠标轨迹与指针距离较远! // ==UserScript==
// @name           Mouse Gestures with Trail
// @namespace      http://example.com
// @description    带轨迹显示的鼠标手势功能,支持RULDR手势添加到稍后阅读
// @version        1.2
// @include        main
// @include        chrome://browser/content/browser.xhtml
// ==/UserScript==
 
(function() {
    // 配置参数
    const config = {
        gestureTimeout: 800,
        minDistance: 20,
        trailColor: "rgba(0, 150, 255, 0.7)",
        trailWidth: 3,
        maxPoints: 300
    };
 
    // 初始化变量
    let isDrawing = false;
    let points = [];
    let canvas, ctx;
 
    // 创建轨迹画布
    function createCanvas() {
        canvas = document.createElement("canvas");
        canvas.style.position = "fixed";
        canvas.style.top = "0";
        canvas.style.left = "0";
        canvas.style.pointerEvents = "none";
        canvas.style.zIndex = "999999";
        document.documentElement.appendChild(canvas);
        resizeCanvas();
        ctx = canvas.getContext("2d");
    }
 
    // 调整画布大小
    function resizeCanvas() {
        if (canvas) {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
    }
 
    // 绘制轨迹
    function drawTrail() {
        if (!ctx || points.length < 2) return;
         
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.beginPath();
        ctx.moveTo(points[0].x, points[0].y);
         
        for (let i = 1; i < points.length; i++) {
            const alpha = i / points.length;
            ctx.strokeStyle = config.trailColor.replace("0.7", alpha.toFixed(2));
            ctx.lineWidth = config.trailWidth;
            ctx.lineTo(points[i].x, points[i].y);
            ctx.stroke();
        }
    }
 
    // 鼠标按下事件
    function onMouseDown(e) {
        if (e.button !== 2) return; // 仅响应右键
         
        isDrawing = true;
        points = [{x: e.clientX, y: e.clientY}];
        createCanvas();
    }
 
    // 鼠标移动事件
    function onMouseMove(e) {
        if (!isDrawing) return;
         
        points.push({x: e.clientX, y: e.clientY});
        if (points.length > config.maxPoints) {
            points.shift();
        }
        drawTrail();
    }
 
    // 鼠标释放事件
    function onMouseUp(e) {
        if (!isDrawing || e.button !== 2) return;
         
        isDrawing = false;
        setTimeout(() => {
            if (canvas) {
                document.documentElement.removeChild(canvas);
                canvas = null;
            }
        }, 300);
         
        // 识别RULDR手势
        if (points.length > 10) {
            const firstSegment = getSegmentDirection(points[0], points[5]);
            const lastSegment = getSegmentDirection(points[points.length-6], points[points.length-1]);
             
            if (firstSegment === "R" && lastSegment === "DR") {
                addToReadLater();
            }
        }
    }
 
    // 获取线段方向
    function getSegmentDirection(start, end) {
        const dx = end.x - start.x;
        const dy = end.y - start.y;
        const angle = Math.atan2(dy, dx) * 180 / Math.PI;
         
        if (angle > -45 && angle <= 45) return "R";
        if (angle > 45 && angle <= 135) return "D";
        if (angle > 135 || angle <= -135) return "L";
        return "U";
    }
 
    // 添加到稍后阅读
    function addToReadLater() {
        const browser = Services.wm.getMostRecentWindow("navigator:browser");
        if (browser && browser.PlacesCommandHook) {
            browser.PlacesCommandHook.bookmarkCurrentPage(false, true);
            showStatus("已添加到稍后阅读");
        }
    }
 
    // 显示状态提示
    function showStatus(message) {
        const status = document.createElement("div");
        status.textContent = message;
        status.style.position = "fixed";
        status.style.bottom = "20px";
        status.style.left = "50%";
        status.style.transform = "translateX(-50%)";
        status.style.backgroundColor = "rgba(0, 0, 0, 0.7)";
        status.style.color = "white";
        status.style.padding = "8px 16px";
        status.style.borderRadius = "4px";
        status.style.zIndex = "1000000";
        document.documentElement.appendChild(status);
         
        setTimeout(() => {
            status.remove();
        }, 1500);
    }
 
    // 初始化事件监听
    window.addEventListener("mousedown", onMouseDown, true);
    window.addEventListener("mousemove", onMouseMove, true);
    window.addEventListener("mouseup", onMouseUp, true);
    window.addEventListener("resize", resizeCanvas);
})();				 | 
	|
| 
			 6楼# 
								发布于:2025-09-14 19:22				
			
					deepseek为MouseGestures2_e10s.uc.js添加鼠标轨迹功能(方法二)
 
							方法二:更高级的轨迹实现 目前没有发现什么问题  | 
	|
| 
			 7楼# 
								发布于:2025-09-14 19:24				
			
					1.在配置部分添加了鼠标轨迹相关选项: 
							// == config == // options enableWheelGestures: true, // Wheel Gestures (Scroll wheel with holding right-click) enableRockerGestures: true, // Rocker Gestures (Left-click with holding right-click and vice versa) enableMouseTrail: true, // 新增:是否启用鼠标轨迹 trailColor: "rgba(255,0,0,0.7)", // 轨迹颜色 trailWidth: 3, // 轨迹宽度 STATUSINFO_TIMEOUT: 2000, // timeout(in millisecond) hide status info  | 
	|
| 
			 8楼# 
								发布于:2025-09-14 19:25				
			
					2.在init方法中添加canvas初始化代码: 
							init: function() { // 原有代码... // 创建canvas用于绘制轨迹 if (this.enableMouseTrail) { this._trailCanvas = document.createElement("canvas"); this._trailCanvas.style.position = "fixed"; this._trailCanvas.style.top = "0"; this._trailCanvas.style.left = "0"; this._trailCanvas.style.pointerEvents = "none"; this._trailCanvas.style.zIndex = "9999"; this._trailCanvas.width = window.innerWidth; this._trailCanvas.height = window.innerHeight; document.documentElement.appendChild(this._trailCanvas); this._trailCtx = this._trailCanvas.getContext("2d"); this._trailCtx.strokeStyle = this.trailColor; this._trailCtx.lineWidth = this.trailWidth; this._trailCtx.lineCap = "round"; this._trailCtx.lineJoin = "round"; this._lastTrailPoint = null; } // 原有代码... }  | 
	|
| 
			 9楼# 
								发布于:2025-09-14 19:25				
			
					3.修改_progressGesture方法添加轨迹绘制: 
							_progressGesture: function(event) { // 原有代码... // 绘制轨迹 if (this.enableMouseTrail) { if (!this._lastTrailPoint) { this._lastTrailPoint = {x: this._lastX, y: this._lastY}; } this._trailCtx.beginPath(); this._trailCtx.moveTo(this._lastTrailPoint.x, this._lastTrailPoint.y); this._trailCtx.lineTo(event.screenX, event.screenY); this._trailCtx.stroke(); this._lastTrailPoint = {x: event.screenX, y: event.screenY}; } // 原有代码... }  | 
	|
| 
			 10楼# 
								发布于:2025-09-14 19:26				
			
					4.修改_stopGesture方法添加轨迹清理: 
							_stopGesture: function(event) { // 清除轨迹 if (this.enableMouseTrail) { this._trailCtx.clearRect(0, 0, this._trailCanvas.width, this._trailCanvas.height); this._lastTrailPoint = null; } // 原有代码... }  | 
	|
| 
			 11楼# 
								发布于:2025-09-14 19:27				
			
					5.在uninit方法中添加canvas清理: 
							uninit: function() { // 原有代码... // 移除轨迹canvas if (this._trailCanvas && this._trailCanvas.parentNode) { this._trailCanvas.parentNode.removeChild(this._trailCanvas); } // 原有代码... }  | 
	|