이 글은 슬라이딩 퍼즐 인증코드 기능을 구현하기 위한 js+canvas를 위주로 소개하고 있으며, 예제코드를 결합하여 단계별로 아주 자세하게 소개하고 있습니다. NetEase Cloud Shield 확인 코드의 슬라이딩 퍼즐에는 전용 이미지 라이브러리가 있어야 하며 자르기 위치는 고정되어 있습니다. 내 아이디어는 그림을 무작위로 생성하고 위치를 무작위로 생성한 다음 캔버스를 사용하여 슬라이더와 배경 이미지를 잘라내는 것입니다. 구체적인 단계는 아래에 설명되어 있습니다.
먼저 임의의 그림을 찾아 캔버스에 렌더링합니다. 여기서 #canvas는 캔버스로 사용되고 #block은 잘린 작은 슬라이더로 사용됩니다.
<canvas width="310" height="155" id="canvas"></canvas> <canvas width="310" height="155" id="block"></canvas> var canvas = document.getElementById('canvas') var block = document.getElementById('block') var canvas_ctx = canvas.getContext('2d') var block_ctx = block.getContext('2d') var img = document.createElement('img') img.onload = function() { canvas_ctx.drawImage(img, 0, 0, 310, 155) block_ctx.drawImage(img, 0, 0, 310, 155) }; img.src = 'img.jpg'
퍼즐의 모양을 자르는 방법을 고려해 보겠습니다. 먼저 사각형을 그린 다음 위의 코드를 작성합니다.
var x = 150, y = 40, w = 42, r = 10, PI = Math.PI function draw(ctx) { ctx.beginPath() ctx.moveTo(x, y) ctx.lineTo(x + w, y) ctx.lineTo(x + w, y + w) ctx.lineTo(x, y + w) ctx.clip() } draw(canvas_ctx) draw(block_ctx)
x, y는 정사각형의 왼쪽 위 모서리입니다. 이제 좌표를 기록하고 생성할 때 임의의 숫자를 사용합니다. W는 정사각형의 한 변의 길이이고, r은 정사각형에 틈을 그리는 원의 반지름입니다. 뒤쪽에. 먼저 나중에 배경과 슬라이더의 동시 작업을 용이하게 하는 기능으로 그리기 프로세스를 캡슐화합니다. 클립() 메서드를 사용하여 이미지를 자르고 정사각형을 생성합니다.
다음으로 사각형의 상단과 오른쪽에 원을 그립니다.
function draw(ctx) { ctx.beginPath() ctx.moveTo(x,y) + ctx.lineTo(x+w/2,y) + ctx.arc(x+w/2,y-r+2, r,0,2*PI) // + ctx.lineTo(x+w/2,y) ctx.lineTo(x+w,y) + ctx.lineTo(x+w,y+w/2) + ctx.arc(x+w+r-2,y+w/2,r,0,2*PI) // + ctx.lineTo(x+w,y+w/2) ctx.lineTo(x+w,y+w) ctx.lineTo(x,y+w) ctx.lineTo(x,y) ctx.clip() }
두 개의 주석은 간격 스타일을 구현하기 위해 원의 중심을 안쪽으로 2px 오프셋합니다. 그러면 왼쪽에 빈 부분이 있습니다. 클립은 클리핑 경로 내의 부분이므로 위와 같이 직접 원을 그리는 것은 불가능합니다. 그런 다음 공백을 "덮기" 위해 원을 그립니다. 여기서는 이름에서 알 수 있듯이 globalCompositeOperation 속성인 'xor'가 사용됩니다. 코드는 위에서부터 계속됩니다.
function draw(ctx) { ctx.beginPath() ... ctx.lineTo(x,y) ctx.clip() + ctx.beginPath() + ctx.arc(x,y+w/2, r,1.5*PI,0.5*PI) // 只需要画正方形内的半圆就行,方便背景图片的裁剪 + ctx.globalCompositeOperation = "xor" + ctx.fill() }
이제 기본 퍼즐 모양이 있으므로 #block의 크기를 조정하고 잘린 슬라이더를 #block에 넣습니다.
img.onload = function() { ctx.drawImage(img, 0, 0, 310, 155) block_ctx.drawImage(img, 0, 0, 310, 155) + var blockWidth = w + r * 2 + var _y = y - r * 2 + 2 // 滑块实际的y坐标 + var ImageData = block_ctx.getImageData(x, _y, blockWidth, blockWidth) + block.width = blockWidth + block_ctx.putImageData(ImageData, 0, _y) }
이제 왼쪽 캔버스에 원본 그림을 표시하고 가운데 슬라이더 부분을 잘라내야 합니다. 여기서 경로를 그리는 과정은 효과를 얻기 위해 클립()이 fill()로 변경된다는 점만 다릅니다. . 이전에 경로를 함수로 그리는 과정을 캡슐화했습니다. 약간만 변경하면 됩니다.
- function draw(ctx) { + function draw(ctx, operation) { ... - ctx.clip() + ctx.fillStyle = '#fff' + ctx[operation]() ... } + draw(canvas_ctx, 'fill') + draw(block_ctx, 'clip')
다음 단계는 스타일을 작성하고 건너뛰는 것입니다.
그런 다음 드래그 이벤트를 작성하면 마우스를 누를 때 마우스 위치를 기록한 다음 드래그할 때 슬라이더의 왼쪽 값을 설정할 수 있습니다. 마지막으로 마우스를 놓으면 이때 슬라이더의 왼쪽 값과 슬라이더가 처음 잘렸을 때의 x 값을 확인하여 특정 범위 내에 있으면 검증에 성공하고, 그렇지 않으면 검증에 실패합니다.
마지막으로 임의의 사진과 임의의 절단 위치를 추가하면 기본적으로 괜찮습니다. 게다가 마우스가 움직일 때의 y축의 변화를 판단하여 "사람"이 조작하는 것인지 판단할 수 있습니다. 물론 웹 보안은 워낙 엉망이기 때문에 자세히 설명하지 않고 그냥 만들어 보겠습니다. 간단한 판단.
슬라이스 가장자리에 추가된 테두리나 그림자가 없기 때문에 일부 사진의 슬라이더는 식별이 잘 되지 않으며 나중에 개선해야 합니다(사실 아직 파악하지 못했습니다 - -). 이것을 이해하는 사람이 도움이 될 것입니다. //
뒤에 있는 코드가 약간 지저분하므로 여기에 게시하지 않겠습니다. 전체 코드를 보려면 여기를 클릭하여 데모 주소를 확인하세요.
위 내용은 모두를 위해 제가 정리한 내용입니다. 앞으로 모든 사람에게 도움이 되기를 바랍니다.
관련 기사:SSH+Jquery+Ajax 프레임워크 통합
JQuery+Ajax+Struts2+Hibernate 프레임워크 통합으로 완전한 로그인 등록 달성
위 내용은 js+canvas는 슬라이딩 퍼즐 인증 코드 기능을 구현합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!