Canvas is used to draw images and animations on web pages. It can be understood as a canvas, and the desired effect is built on this canvas.
Canvas can draw dynamic effects. In addition to commonly used regular animations, the concept of particles can also be used to achieve more complex dynamic effects. This article uses ordinary dynamic effects and particle special effects to implement a simple clock.
Ordinary clockOrdinary animation uses the canvas API to achieve regular patterns and animations.
Effect
The effect is relatively simple to achieve. We mainly analyze the implementation of the angle offset between the scale and the pointer.
draw ticksThis example is the drawing of hour scale: there are 12 hours on the dial, Math.PI is 180°, and each hour occupies 30°.
.save() means to save the state of the current canvas environment and draw on this basis. After drawing is completed, the previously saved path status and attributes are returned.
The same goes for the minute scale, just change the angle and style.
// Hourly time scale offscreenCanvasCtx.save(); for (var i = 0; i < 12; i++) { offscreenCanvasCtx.beginPath(); // Scale color offscreenCanvasCtx.strokeStyle = '#fff'; // Scale width offscreenCanvasCtx. lineWidth = 3; // Occupy 30° every hour offscreenCanvasCtx.rotate(Math.PI / 6); // The starting position of drawing offscreenCanvasCtx.lineTo(140, 0) // The ending position of drawing; offscreenCanvasCtx.lineTo(120, 0); // The drawing path offscreenCanvasCtx.stroke(); } offscreenCanvasCtx.restore() ; Pointer points toTake the second hand as an example: get the seconds of the current time and calculate the corresponding offset angle
var now = new Date(), sec = now.getSeconds(), min = now.getMinutes(), hr = now.getHours(); hr = hr > 12 ? hr - 12 : hr; //Second hand offscreenCanvasCtx.save (); offscreenCanvasCtx.rotate(sec * (Math.PI / 30)); ...... offscreenCanvasCtx.stroke();Particle animation
Canvas can be used to draw complex, irregular animations. Particle effects can be used to achieve complex, random dynamic effects.
Particles refer to each pixel in the image data imageData . After obtaining each pixel, add attributes or events to interact with the particles in the area to achieve dynamic effects.
Effect
particle acquisitionTake the image conversion in the figure below as an example. The effect is to first render the image on the canvas, and then obtain each pixel in the area where the text is located.
let image = new Image(); image.src='../image/logo.png'; let pixels=[]; //Storage pixel data let imageData; image.width = 300; image.height = 300 // Render the image and obtain the pixel information in the area 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); //Get chart pixel information //Draw image}; Pixel informationThe size of the picture is 300*300, with a total of 90,000 pixels. Each pixel occupies 4 bits and stores rgba data.
Particle drawing function getPixels(){ var pos=0; var data=imageData.data; //RGBA one-dimensional array data //The height and width of the source image are 300px for(var i=1;i<=image.width;i++ ){ for(var j=1;j<=image.height;j++){ pos=[(i-1)*image.width+(j-1)]*4; //Get the pixel position if(data[pos]>=0){ var pixel={ x:(canvas.width-image.width)/2+j+Math.random()*20, //Reset each Pixel position information y: (canvas.height-image.height)/2+i+Math.random()*20, //Reset the position information of each pixel 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 < len; i++) { curr_pixel = pixels[i]; ctx.fillStyle = curr_pixel.fillStyle; ctx.fillRect(curr_pixel.x, curr_pixel.y, 1, 1); } } particle clockRender text clock
function time() { ctx.clearRect(0,0,canvas.width,canvas.height) ctx.font = 150px bold; 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); }Effect
Get particlesThe concept of text conversion particles is the same as above. The pixels in the selected area are obtained, selected according to the filter conditions and stored in the array. Redraw after traversal.
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<=textHeight;i++){ for(let j=1;j<=textWidth;j++){ pos=[(i-1)*textWidth+(j-1)]*4; //Get the pixel position if(data[pos]>=0){ var pixel={ x:j+Math.random()*20 , //Reset the position information of each pixel y:i+Math.random()*20, //Reset the position information of each pixel fillStyle:'rgba('+data[pos]+','+(data[pos+1])+','+(data[pos+2])+', '+(data[pos+3])+')' }; pixelsArr.push(pixel); } } } } imgData saves the pixel information in the selected area, each pixel occupies 4 bits, and saves the RGBA four-bit information. Filtering the fourth bit of each pixel, this code saves all pixels with a transparency that is not 0 to the array pixelsArr .
x and y record the position information of the particle. In order to produce the motion effect in the rendering, an offset position of 0-20 pixels is added to each particle. Each time it is redrawn, the offset position is randomly generated to generate movement. Effect.
After obtaining the particles, you need to clear the original text in the canvas and redraw the obtained particles onto the canvas.
function drawPixels() { // Clear the canvas content and redraw 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); } }The style of particle redrawing is the original color and transparency when filtering pixels, and when each particle is drawn on the canvas, the size parameter r is defined, and the value of r is a random number from 0 to 4. The resulting particles are randomly sized.
Real time refresh After obtaining the particles and redrawing successfully, the page needs to be refreshed in real time. The window.requestAnimationFrame(callback) method is used here.
function time() { ...... getpixels(); //Get particles drawPixels(); // Redraw particles requestAnimationFrame(time); } The window.requestAnimationFrame(callback) method tells the browser that you want to perform animation and requests the browser to call the specified function to update the animation before the next redraw. This method takes a callback function as parameter, which will be called before the browser redraws.
This method does not require setting a time interval, and the calling frequency adopts the system time interval (1s).
Document explanation click here
Effect
SummarizeThis article mainly achieves the dynamic effect of the clock in two different ways, among which the particle clock has more operability. In the future canvas series, more dynamic effects will be implemented for the particle system.
The above is the entire content of this article. I hope it will be helpful to everyone’s study. I also hope everyone will support VeVb Wulin Network.