JavaScript实现图片横向移动(转载)

本文介绍了一种使用JavaScript实现的图片滚动效果,通过修改div元素的宽度和位置来达到图片连续滚动的效果。该方法适用于网页设计中需要展示多个图片的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<script type="text/javascript" defer>
var marquee_spd = 25// 滚动速度,数值越小越快
var repeat = null;
var obj_marquee = document.getElementById("ImgList");//本例中的<div id=ImgList>
function marquee_init()
ExpandedBlockStart.gifContractedBlock.gif
{
    
var obj_unit = obj_marquee.firstChild;
    
var marquee_high = parseInt(obj_marquee.style.height);
    
var marquee_wide = parseInt(obj_marquee.style.width);
    
var unit_high = obj_unit.offsetHeight;
    
var unit_wide = obj_unit.offsetWidth;
    
var m = 0, n = 0, i = 0;
    
var tmp = null;

    m 
= Math.ceil(marquee_wide / unit_wide);
    n 
= Math.ceil(marquee_high / unit_high);

    obj_unit.style.width 
= marquee_wide * (m + 1);
    obj_unit.rows[
0].cells[0].style.width = obj_marquee.style.width;

ExpandedSubBlockStart.gifContractedSubBlock.gif    
for(i = 0; i < m; i++{
        tmp 
= obj_unit.rows[0].insertCell(-1);
        tmp.innerHTML 
= obj_unit.rows[0].cells[0].innerHTML;
        tmp.style.width 
= marquee_wide;
        tmp 
= null;
    }


ExpandedSubBlockStart.gifContractedSubBlock.gif    
for(i = 0; i < n; i++{
        obj_marquee.appendChild(obj_unit.cloneNode(
true));
    }


    
return;
}


function marquee_show(direction)
ExpandedBlockStart.gifContractedBlock.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gif    
switch(direction) {
        
case "up":
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if(obj_marquee.scrollTop >= obj_marquee.children[1].offsetTop) {
                obj_marquee.scrollTop 
-= obj_marquee.firstChild.offsetHeight;
ExpandedSubBlockStart.gifContractedSubBlock.gif            }
 else {
                obj_marquee.scrollTop
++;
            }

            
break;
        
case "down":
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if(obj_marquee.scrollTop <= 0{
                obj_marquee.scrollTop 
+= obj_marquee.firstChild.offsetHeight;
ExpandedSubBlockStart.gifContractedSubBlock.gif            }
 else {
                obj_marquee.scrollTop
--;
            }

            
break;
        
case "left":
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if(obj_marquee.scrollLeft >= obj_marquee.firstChild.rows[0].cells[0].offsetWidth) {
                obj_marquee.scrollLeft 
-= obj_marquee.firstChild.rows[0].cells[0].offsetWidth;
ExpandedSubBlockStart.gifContractedSubBlock.gif            }
 else {
                obj_marquee.scrollLeft
++;
            }

            
break;
        
case "right":
ExpandedSubBlockStart.gifContractedSubBlock.gif            
if(obj_marquee.scrollLeft <= 0{
                obj_marquee.scrollLeft 
+= obj_marquee.firstChild.rows[0].cells[0].offsetWidth;
ExpandedSubBlockStart.gifContractedSubBlock.gif            }
 else {
                obj_marquee.scrollLeft
--;
            }

            
break;
        
default:
            
break;
    }

    
return;
}


function marquee_doit()
ExpandedBlockStart.gifContractedBlock.gif
{
    
var direction = "";
    direction 
= obj_marquee.getAttribute("direction");
    
if(direction != null) marquee_show(direction);
    direction 
= obj_marquee.getAttribute("direction2");
    
if(direction != null) marquee_show(direction);
    
return;
}


function startMove()
ExpandedBlockStart.gifContractedBlock.gif
{
marquee_init();
repeat 
= setInterval("marquee_doit()", marquee_spd);

ExpandedSubBlockStart.gifContractedSubBlock.gifobj_marquee.onmouseover 
= function() { clearInterval(repeat); }
ExpandedSubBlockStart.gifContractedSubBlock.gifobj_marquee.onmouseout 
= function() { repeat = setInterval("marquee_doit()", marquee_spd); }
}


startMove();
</script>

DIV代码:

ContractedBlock.gifExpandedBlockStart.gif图片列表
<div id="ImgList" direction="left" style="overflow:hidden;height:100px;width:700px"> 
    
<table width="1728" border="0" cellspacing="0" cellpadding="0" ID="Table1">
        
<tr>
        
<td>
            
<table cellspacing=0 cellpadding=0 border=0 align="center" ID="Table2">
            
<tbody> 
            
<tr>  
                
                
<td bordercolor=#ffffff width="102" height="108"> 
                
<div align="center"><a href="#" target="_blank"><img src="1.jpg" width=86 border="0" hspace=8></a><br>
                    
<img src="space.gif" width="3" height="3"><br>
                    
<font color="#0000CC" >图片1</font></div>
                
</td>
                
                
                
<td bordercolor=#ffffff width="102" height="108"> 
                
<div align="center"><a href="#" target="_blank"><img src="2.jpg" width=86 border="0" hspace=8></a><br>
                    
<img src="space.gif" width="3" height="3"><br>
                    
<font color="#0000CC" >图片2</font></div>
                
</td>
                
</tr>
            
</tbody> 
            
</table>
        
</td>
        
</tr>
    
</table>
 
</div>

转载于:https://www.cnblogs.com/juan/archive/2009/05/07/1451355.html

<think>嗯,用户想知道如何在Vue中实现手势解锁功能,或者有没有相关的组件教程。我需要根据提供的引用资料来整理一个步骤指南。首先,用户提到的引用有三个,都是关于使用Vue和Canvas实现手势锁的。我得先回顾一下这些引用的内容,看看有没有共同点或者可以提取的关键步骤。 引用1提到用Vue封装图案手势锁组件,开发步骤和效果展示。引用2讲的是用Canvas实现H5的手势密码设置和解锁,用户遇到了需求,参考了一些案例并做了改动。引用3是一个转载的博客,关于用Canvas实现Vue手势解锁组件。看来这三个引用都涉及到Vue和Canvas的结合使用,所以核心应该是在Vue组件中使用Canvas来绘制手势路径。 接下来,我需要将这些信息结构化。首先,创建Vue组件的基本结构,然后处理Canvas的绘制逻辑,包括触摸事件的处理,点的连接,以及密码的验证和存储。可能需要分步骤讲解:组件结构、Canvas初始化、事件绑定、绘制逻辑、密码验证、样式优化等。 还要考虑用户的交互,比如触摸开始、移动、结束的事件处理。在移动端需要注意触摸事件,比如touchstart、touchmove、touchend。同时,需要存储用户选择的点,并实时绘制连线。密码的存储可能需要使用本地存储,比如localStorage。 另外,用户可能需要知道如何将各个点坐标化,判断触摸点是否在某个圆的范围内。这部分涉及到数学计算,比如两点之间的距离是否小于半径。在Vue中,可以通过ref来获取Canvas的DOM元素,然后获取上下文进行绘制。 样式方面,可能需要设置圆的样式,连线的颜色,以及激活状态的颜色变化。引用中提到的效果图可能包括这些视觉反馈,所以在步骤中需要提到如何动态更新Canvas的绘制状态。 还要考虑组件的可复用性,比如通过props传入配置参数,如点的数量、颜色、大小等。事件处理完成后,通过emit触发父组件的事件,比如密码设置完成或验证结果。 可能遇到的问题包括:Canvas的适配不同屏幕尺寸,触摸事件的兼容性处理,以及性能优化。不过根据引用中的案例,这些已经有了一些解决方案,可以简要提及。 最后,生成相关问题,帮助用户深入理解,比如性能优化、样式自定义、手势密码的安全性等。这些问题可以引导用户进一步学习或解决实际开发中的问题。 总结一下,回答的结构应该是分步骤讲解实现过程,结合代码示例,并引用提供的资料作为参考。同时,确保使用正确的中文表达,遵循LaTeX格式的要求,行内公式用$...$,独立公式用$$...$$,虽然这个问题可能不涉及太多数学公式,但如果有变量或方程的话需要注意格式。</think>### Vue实现手势解锁功能的分步教程 在Vue中实现手势解锁功能,可通过以下步骤完成: --- #### **1. 组件结构与Canvas初始化** - **创建Vue组件模板**:定义画布容器和提示区域。 ```html <template> <div class="gesture-lock"> <canvas ref="canvas" @touchstart="handleStart" @touchmove.prevent="handleMove" @touchend="handleEnd"></canvas> <div class="tips">{{ statusText }}</div> </div> </template> ``` - **初始化Canvas**:根据屏幕分辨率调整画布尺寸。 ```javascript mounted() { const canvas = this.$refs.canvas; const ctx = canvas.getContext('2d'); const ratio = window.devicePixelRatio || 1; canvas.width = 300 * ratio; canvas.height = 300 * ratio; ctx.scale(ratio, ratio); this.initPoints(); // 初始化手势点坐标 } ``` --- #### **2. 手势点坐标计算** - **九宫格布局**:将画布划分为3×3的均匀区域。 ```javascript initPoints() { const points = []; const radius = 10; // 圆点半径 for (let i = 0; i < 3; i++) { for (let j = 0; j < 3; j++) { points.push({ x: 50 + j * 100, // 横向间距100px y: 50 + i * 100, // 纵向间距100px id: i * 3 + j + 1, active: false }); } } this.points = points; } ``` --- #### **3. 触摸事件处理** - **触摸开始**:检测触摸点是否在某个圆内。 ```javascript handleStart(e) { const touch = e.touches[0]; const { x, y } = this.getTouchPos(touch); this.selectedPoints = []; // 重置已选点 this.checkPointHit(x, y); // 检测首个触点 } ``` - **触摸移动**:实时绘制连线和更新选中点。 ```javascript handleMove(e) { const touch = e.touches[0]; const { x, y } = this.getTouchPos(touch); this.checkPointHit(x, y); // 持续检测触点 this.drawCanvas(); // 重绘画布 } ``` - **触摸结束**:验证密码或保存设置。 ```javascript handleEnd() { if (this.selectedPoints.length >= 4) { // 至少连接4个点 const password = this.selectedPoints.map(p => p.id).join(''); if (this.mode === 'setup') { localStorage.setItem('gesturePassword', password); this.$emit('setup-complete'); } else { const storedPassword = localStorage.getItem('gesturePassword'); this.$emit('verify-result', password === storedPassword); } } this.resetCanvas(); // 重置画布状态 } ``` --- #### **4. Canvas绘制逻辑** - **绘制圆点与连线**: ```javascript drawCanvas() { const ctx = this.$refs.canvas.getContext('2d'); ctx.clearRect(0, 0, 300, 300); // 绘制圆点 this.points.forEach(point => { ctx.beginPath(); ctx.arc(point.x, point.y, 10, 0, Math.PI * 2); ctx.fillStyle = point.active ? '#3a7afe' : '#ddd'; ctx.fill(); }); // 绘制连线 if (this.selectedPoints.length > 0) { ctx.beginPath(); ctx.moveTo(this.selectedPoints[0].x, this.selectedPoints[0].y); this.selectedPoints.forEach(point => { ctx.lineTo(point.x, point.y); }); ctx.strokeStyle = '#3a7afe'; ctx.lineWidth = 3; ctx.stroke(); } } ``` --- #### **5. 功能扩展与优化** - **Props配置**:支持传入模式(设置/验证)、颜色、点数量等参数。 ```javascript props: { mode: { type: String, default: 'setup' // 或 'verify' } } ``` - **事件反馈**:通过`$emit`向父组件传递结果。 ```javascript this.$emit('verify-result', isValid); ``` --- ### 示例代码整合 完整组件代码可参考引用中的实现[^1][^2][^3],核心逻辑包括: 1. Canvas坐标计算与绘制 2. 触摸事件与手势路径追踪 3. 密码存储与验证 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值