이 글은 캔버스에서 일반적인 모션 효과와 파티클 모션 효과를 구현하는 방법에 대한 소개입니다(코드 예제). 도움이 필요한 친구들이 참고할 수 있기를 바랍니다. 도움이 되었습니다.
캔버스는 웹 페이지에 이미지와 애니메이션을 그리는 데 사용되며, 캔버스로 이해하면 이 캔버스에 원하는 효과가 구현됩니다.
캔버스는 일반적으로 사용되는 동적 효과 외에도 입자의 개념을 사용하여 보다 복잡한 동적 효과를 구현할 수도 있습니다. 이 기사에서는 간단한 시계를 구현하기 위해 일반적인 동적 효과와 입자 특수 효과를 사용합니다.
일반 시계
일반 애니메이션은 캔버스 API를 사용하여 일반 패턴과 애니메이션을 구현합니다.
Effect
이 효과는 구현하기가 비교적 간단합니다. 스케일과 포인터의 각도 오프셋 구현을 주로 분석합니다.
눈금 그리기
이 예는 시간 눈금 그리기입니다. 다이얼에는 12시간이 있고 Math.PI는 180°이며 각 시간은 30°를 차지합니다.
.save()는 현재 캔버스 환경의 상태를 저장하고 이를 기반으로 그리는 것을 의미합니다. 그리기가 완료된 후 이전에 저장한 경로 상태 및 속성을 반환합니다.
분 단위는 동일하며 각도와 스타일만 변경하면 됩니다.
// 小时时间刻度 offscreenCanvasCtx.save(); for (var i = 0; i <p><strong>포인터는</strong></p><p>초침을 예로 들어 보겠습니다. 현재 시간의 초를 가져와 해당 오프셋 각도를 계산합니다.</p><pre class="brush:php;toolbar:false"> var now = new Date(), sec = now.getSeconds(), min = now.getMinutes(), hr = now.getHours(); hr = hr > 12 ? hr - 12 : hr; //秒针 offscreenCanvasCtx.save(); offscreenCanvasCtx.rotate(sec * (Math.PI / 30)); ...... offscreenCanvasCtx.stroke();
파티클 애니메이션
캔버스는 복잡하고 불규칙한 그림을 그리는 데 사용할 수 있습니다. 애니메이션. 입자 효과를 사용하면 복잡하고 무작위적인 동적 효과를 얻을 수 있습니다.
입자는 이미지 데이터의 각 픽셀을 참조합니다imageData
각 픽셀을 얻은 후 해당 영역의 입자와 상호 작용하는 속성이나 이벤트를 추가하여 동적 효과를 얻습니다.
아래 그림의 이미지 변환을 예로 들면, 이 효과는 먼저 캔버스에 이미지를 렌더링한 후 텍스트가 있는 영역의 각 픽셀을 얻는 것입니다. 위치하고 있습니다.
let image = new Image(); image.src='../image/logo.png'; let pixels=[]; //存储像素数据 let imageData; image.width = 300; image.height = 300 // 渲染图片,并获取该区域内像素信息 image.onload=function(){ ctx.drawImage(image,(canvas.width-image.width)/2,(canvas.height-image.height)/2,image.width,image.height); imageData=ctx.getImageData((canvas.width-image.width)/2,(canvas.height-image.height)/2,image.width,image.height); //获取图表像素信息 //绘制图像 };
사진 크기는 300*300으로 총 90,000픽셀을 차지하며, 각 픽셀은 4비트를 차지하며 rgba 데이터를 저장합니다.
function getPixels(){ var pos=0; var data=imageData.data; //RGBA的一维数组数据 //源图像的高度和宽度为300px for(var i=1;i=0){ var pixel={ x:(canvas.width-image.width)/2+j+Math.random()*20, //重新设置每个像素的位置信息 y:(canvas.height-image.height)/2+i+Math.random()*20, //重新设置每个像素的位置信息 fillStyle:'rgba('+data[pos]+','+(data[pos+1])+','+(data[pos+2])+','+(data[pos+3])+')' } pixels.push(pixel); } } } } function drawPixels() { var canvas = document.getElementById("myCanvas"); var ctx = canvas.getContext("2d"); ctx.clearRect(0,0,canvas.width,canvas.height); var len = pixels.length, curr_pixel = null; for (var i = 0; i <h1>입자 시계</h1><h2>렌더 텍스트 시계</h2><pre class="brush:php;toolbar:false"> function time() { ctx.clearRect(0,0,canvas.width,canvas.height) ctx.font = "150px 黑体"; ctx.textBaseline='top'; ctx.fillStyle = "rgba(245,245,245,0.2)"; ctx.fillText(new Date().format('hh:mm:ss'),(canvas.width-textWidth)/2,(canvas.height-textHeight)/2,textWidth,textHeight); }
文字转换粒子概念同上,获取选定区域的像素,根据筛选条件进行选择并存入数组。经过遍历后重新绘制。
function getPixels(){ let imgData = ctx.getImageData((canvas.width-textWidth)/2,(canvas.height-textHeight)/2,textWidth,textHeight); let data = imgData.data pixelsArr = [] for(let i=1;i=0){ var pixel={ x:j+Math.random()*20, //重新设置每个像素的位置信息 y:i+Math.random()*20, //重新设置每个像素的位置信息 fillStyle:'rgba('+data[pos]+','+(data[pos+1])+','+(data[pos+2])+','+(data[pos+3])+')' }; pixelsArr.push(pixel); } } } }
imgData
保存了所选区域内的像素信息,每个像素点占据4位,保存了RGBA四位信息。筛选每个像素的第四位,这段代码中将所有透明度不为0的像素都保存到了数组pixelsArr
中。
x
、y
记载了该粒子的位置信息,为了产生效果图中的运动效果,给每个粒子添加了0-20个像素的偏移位置,每次重绘时,偏移位置随机生成,产生运动效果。
获取粒子之后,需要清除画布中原有的文字,将获取到的粒子重新绘制到画布上去。
function drawPixels() { // 清除画布内容,进行重绘 ctx.clearRect(0,0,canvas.width,canvas.height); for (let i in pixelsArr) { ctx.fillStyle = pixelsArr[i].fillStyle; let r = Math.random()*4 ctx.fillRect(pixelsArr[i].x, pixelsArr[i].y, r, r); } }
粒子重绘时的样式为筛选像素时原本的颜色与透明度,并且每个在画布上绘制每个粒子时,定义大小参数r,r取值为0-4中随机的数字。最终生成的粒子大小随机。
获取粒子并成功重绘之后,需要页面实时刷新时间。这里采用window.requestAnimationFrame(callback)
方法。
function time() { ...... getpixels(); //获取粒子 drawPixels(); // 重绘粒子 requestAnimationFrame(time); }
window.requestAnimationFrame(callback)
方法告诉浏览器您希望执行动画并请求浏览器在下一次重绘之前调用指定的函数来更新动画。该方法使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。
该方法不需要设置时间间隔,调用频率采用系统时间间隔(1s)。
效果
总结
本文主要通过两种不同的方式实现了时钟的动态效果,其中粒子时钟具有更多的可操作性。在以后的canvas系列中会针对粒子系统实现更多的动态效果。
위 내용은 일반 모션 효과와 파티클 모션 효과를 캔버스에 구현 방법 소개(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!