canvas新年快乐烟花绽放形成文字动画效果代码
代码语言:html
所属分类:动画
代码描述:canvas新年快乐烟花绽放形成文字动画效果代码
代码标签: canvas 新年 快乐 烟花 绽放 形成 文字 动画
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> </head> <body> <script> function GameCanvas(settings) { let top = this; this.functions = []; this.keys = []; this.ctrlPressed = false; this.shiftSPressed = false; this.altPressed = false; this.images = []; this.spheres = []; this.font = "Arial"; this.imageData = undefined; this.imageDataData = undefined; this.lastLoop = performance.now(); this.calculateFPS = true; this.fps = -1; this.deltaTime = 1; let mouseLookupTable = [ "left", "middle", "right" ]; this.contextMenuDisabled = false; this.disableScrollOnMobile = false; this.eventFunctions = { "mousedown": typeof OnMouseDown !== "undefined", "mouseup": typeof OnMouseUp !== "undefined", "mousemove": typeof OnMouseMove !== "undefined", "contextmenu": typeof OnContextMenu !== "undefined", "touchstart": typeof OnTouchStart !== "undefined", "touchend": typeof OnTouchEnd !== "undefined", "touchmove": typeof OnTouchMove !== "undefined", "keydown": typeof OnKeyDown !== "undefined", "keyup": typeof OnKeyUp !== "undefined" }; this.audioContext = new (window.AudioContext || window.webkitAudioContext)(); this.createCanvas = function() { let canvas = document.createElement("canvas"); document.body.appendChild(canvas); return canvas; } this.setSize = function(width, height) { if (top.canvas) { top.canvas.width = top.width = width; top.canvas.height = top.height = height; window.width = this.width; window.height = this.height; } else { console.error("There is no canvas!"); } } this.fillPageWithCanvas = function() { top.canvas.style.position = "fixed"; top.canvas.style.top = "0px"; top.canvas.style.left = "0px"; top.setSize(window.innerWidth, window.innerHeight); top.disableScrollOnMobile = true; top.contextMenuDisabled = true; this.updateSizeOnResize = true; } this.requestFullscreen = function() { if (top.canvas.requestFullscreen) top.canvas.requestFullscreen(); else if (top.canvas.mozRequestFullScreen) top.canvas.mozRequestFullScreen(); else if (top.canvas.webkitRequestFullscreen) top.canvas.webkitRequestFullscreen(); else if (top.canvas.msRequestFullscreen) top.canvas.msRequestFullscreen(); } this.exitFullscreen = function() { if(document.exitFullscreen) document.exitFullscreen(); else if(document.mozCancelFullScreen) document.mozCancelFullScreen(); else if(document.webkitExitFullscreen) document.webkitExitFullscreen(); else if(document.msExitFullscreen) document.msExitFullscreen(); } this.lockPointer = function() { top.canvas.requestPointerLock = top.canvas.requestPointerLock || top.canvas.mozRequestPointerLock; top.canvas.requestPointerLock(); } this.unlockPointer = function() { document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock; document.exitPointerLock(); } this.disableContextMenu = function() { top.contextMenuDisabled = true; } this.enableContextMenu = function() { top.contextMenuDisabled = false; } this.key = function(key) { return top.keys[key]; } this.isCtrlPressed = function() { return top.ctrlPressed; } this.isShiftPressed = function() { return top.shiftPressed; } this.isAltPressed = function() { return top.altPressed; } this.update = function() { if (top.calculateFPS) { var thisLoop = performance.now(); var delta = (thisLoop - top.lastLoop); top.fps = 1000 / delta; top.deltaTime = delta / 1000; top.lastLoop = thisLoop; if (top.globalFunctions) { window.fps = top.fps; window.deltaTime = top.deltaTime; } } top.mouse.movementX = 0; top.mouse.movementY = 0; top.mouse.lastX = top.mouse.x; top.mouse.lastY = top.mouse.y; } /****************** Rendering ******************/ this.clearScreen = function() { top.ctx.clearRect(0, 0, top.width, top.height); } this.background = function(color) { top.ctx.fillStyle = color; top.ctx.fillRect(0, 0, top.width, top.height); } this.circle = function(x, y, radius, color, strokeColor, lineWidth) { top.ctx.beginPath(); top.ctx.arc(x, y, radius, 0, Math.PI * 2); top.ctx.fillStyle = color; if (strokeColor) top.ctx.strokeStyle = strokeColor; if (lineWidth) top.ctx.lineWidth = lineWidth; top.ctx.fill(); if (strokeColor) top.ctx.stroke(); } this.ring = function(x, y, radius, color, lineWidth) { top.ctx.beginPath(); top.ctx.arc(x, y, radius, 0, Math.PI * 2); top.ctx.strokeStyle = color; if (lineWidth) top.ctx.lineWidth = lineWidth; top.ctx.stroke(); } this.ellipse = function(x, y, radiusX, radiusY, color, rotation = 0, strokeColor, lineWidth) { top.ctx.beginPath(); top.ctx.ellipse(x, y, radiusX, radiusY, rotation, 0, Math.PI * 2); top.ctx.fillStyle = color; if (strokeColor) top.ctx.strokeStyle = strokeColor; if (lineWidth) top.ctx.lineWidth = lineWidth; top.ctx.fill(); if (strokeColor) top.ctx.stroke(); } this.rectangle = function(x, y, width, height, color, strokeColor, lineWidth) { top.ctx.fillStyle = color; if (lineWidth) top.ctx.lineWidth = lineWidth; if (strokeColor) { top.ctx.beginPath(); top.ctx.strokeStyle = strokeColor; top.ctx.rect(x, y, width, height); top.ctx.fill(); top.ctx.stroke(); } else top.ctx.fillRect(x, y, width, height); } this.roundedRectangle = function(x, y, w, h, color, cornerRadii, strokeColor, lineWidth) { top.ctx.beginPath(); top.ctx.arc(x + cornerRadii[0], y + cornerRadii[0], cornerRadii[0], Math.PI, Math.PI * 1.5); top.ctx.lineTo(x + w - cornerRadii[1], y); top.ctx.arc(x + w - cornerRadii[1], y + cornerRadii[1], cornerRadii[1], Math.PI * 1.5, Math.PI * 2); top.ctx.lineTo(x + w, y + h - cornerRadii[2]); top.ctx.arc(x + w - cornerRadii[2], y + h - cornerRadii[2], cornerRadii[2], 0, Math.PI * 0.5); top.ctx.lineTo(x + cornerRadii[3], y + h); top.ctx.arc(x + cornerRadii[3], y + h - cornerRadii[3], cornerRadii[3], Math.PI * 0.5, Math.PI); top.ctx.closePath(); if (strokeColor) { if (lineWidth) top.ctx.lineWidth = lineWidth; top.ctx.strokeStyle = strokeColor; top.ctx.stroke(); } top.ctx.fillStyle = color; top.ctx.fill(); } this.triangle = function(x1, y1, x2, y2, x3, y3, color, strokeColor, lineWidth) { top.ctx.beginPath(); top.ctx.moveTo(x1, y1); top.ctx.lineTo(x2, y2); top.ctx.lineTo(x3, y3); top.ctx.closePath(); top.ctx.fillStyle = color; if (lineWidth) top.ctx.lineWidth = lineWidth; top.ctx.fill(); if (strokeColor) { top.ctx.strokeStyle = strokeColor; top.ctx.stroke(); } } this.setLineCap = function(lineCap) { top.ctx.lineCap = lineCap; } this.resetLineCap = function() { top.ctx.lineCap = "butt"; } this.line = function(x1, y1, x2, y2, strokeWeight, color) { top.ctx.beginPath(); top.ctx.moveTo(x1, y1); top.ctx.lineTo(x2, y2); if (color) top.ctx.strokeStyle = color; if (strokeWeight) top.ctx.lineWidth = strokeWeight; top.ctx.stroke(); } this.picture = function(url, x, y, width, height) { var imageElement = top.images[url]; if (!imageElement) { var img = new Image(); img.src = url; img.onload = function() { top.ctx.drawImage(img, x, y, width, height); } top.images[url] = img; } else if (imageElement.complete) { top.ctx.drawImage(imageElement, x, y, width, height); } } this.setFont = function(font) { top.font = font; } this.setTextAlign = function(align) { top.ctx.textAlign = align; } this.setTextXAlign = function(align) { top.ctx.textAlign = align; } this.setTextYAlign = function(align) { top.ctx.textBaseline = align; } this.resetTextXAlign = function() { top.ctx.textAlign = "left"; } this.resetTextYAlign = function() { top.ctx.textBaseline = "alphabetic"; } this.text = function(textString, x, y, fontSize, color, strokeColor, lineWidth) { top.ctx.beginPath(); top.ctx.font = fontSize + "px " + top.font; top.ctx.fillStyle = color; if (lineWidth) top.ctx.lineWidth = lineWidth; top.ctx.fillText(textString, x, y); if (strokeColor) { top.ctx.strokeStyle = strokeColor; top.ctx.strokeText(textString, x, y); } } this.drawVector = function(x, y, v, scale = 1, color = "black") { var triangleScale = 7; var normalizedVector = top.normalizeVector(v); var rotatedNormVector = { x: -normalizedVector.y, y: normalizedVector.x } var endX = x + v.x * scale; var endY = y + v.y * scale; top.line(x, y, endX, endY, 3, color); top.triangle(endX, endY, endX - normalizedVector.x * triangleScale + rotatedNormVector.x * triangleScale, endY - normalizedVector.y * triangleScale + rotatedNormVector.y * triangleScale, endX - normalizedVector.x * triangleScale - rotatedNormVector.x * triangleScale, endY - normalizedVector.y * triangleScale - rotatedNormVector.y * triangleScale, color); } // Pixel manipulation this.getPixelData = function() { top.imageData = top.ctx.getImageData(0, 0, top.width, top.height); top.imageDataData = top.imageData.data; } this.updatePixel = function(x, y, r, g, b, a = 255) { let i = (x + y * top.width) * 4; top.imageDataData[i] = r; top.imageDataData[i + 1] = g; top.imageDataData[i + 2] = b; top.imageDataData[i + 3] = a; } this.updatePixelIndex = function(index, r, g, b, a = 255) { var i = index * 4; top.imageDataData[i] = r; top.imageDataData[i + 1] = g; top.imageDataData[i + 2] = b; top.imageDataData[i + 3] = a; } this.getPixel = function(x, y) { let i = (x + y * top.width) * 4; return [ top.imageDataData[i], top.imageDataData[i + 1], top.imageDataData[i + 2], top.imageDataData[i + 3] ]; } this.getPixelIndex = function(index) { let i = index * 4; return [ top.imageDataData[i], top.imageDataData[i + 1], top.imageDataData[i + 2], top.imageDataData[i + 3] ]; } this.renderPixelData = function() { /*createImageBitmap(top.imageData).then(function(imgBitmap) { top.ctx.drawImage(imgBitmap, 0, 0); });*/ top.ctx.putImageData(top.imageData, 0, 0); } // this.save = function() { top.ctx.save(); } this.restore = function() { top.ctx.restore(); } this.rotate = function(angle) { top.ctx.rotate(angle); } this.translate = function(x, y) { top.ctx.translate(x, y); } this.beginPath = function() { top.ctx.beginPath(); } this.closePath = function() { top.ctx.closePath(); } this.moveTo = function(x, y) { top.ctx.moveTo(x, y); } this.lineTo = function(x, y) { top.ctx.lineTo(x, y); } this.fill = function() { top.ctx.fill(); } this.stroke = function() { top.ctx.stroke(); } this.fillStyle = function(color) { top.ctx.fillStyle = color; } this.strokeStyle = function(color) { top.ctx.strokeStyle = color; } this.setLineWidth = function(lineWidth) { top.ctx.lineWidth = lineWidth; } this.lineWidth = function(lineWidth) { top.ctx.lineWidth = lineWidth; } this.strokeWeight = function(lineWidth) { top.ctx.lineWidth = lineWidth; } /****************** 3D ******************/ this.drawSphere = function(screenX, screenY, radius, color, lightDir = {x: 0, y: 0, z: 1}) { var id = (screenX + screenY) * radius * (color[0] + 1) * (color[1] + 1) * (color[2] + 1) * (lightDir.x + 1) * (lightDir.y + 1) * (lightDir.z + 1); if (top.spheres[id]) { if (top.spheres[id].imageData) top.ctx.putImageData(top.spheres[id].imageData, screenX - radius, screenY - radius); else if (top.spheres[id].image) top.ctx.drawImage(top.spheres[id].image, screenX - radius, screenY - radius); } else { var imageData = top.ctx.createImageData(radius * 2, radius * 2); for (var y = 0; y < radius * 2; y++) { for (var x = 0; x < radius * 2; x++) { var line = { origin: {x: x, y: y, z: 0}, direction: {x: 0, y: 0, z: 1} }; var o = { position: {x: radius, y: radius, z: radius * 2} } var oc = { x: line.origin.x - o.position.x, y: line.origin.y - o.position.y, z: line.origin.z - o.position.z }; var loc = top.dot3D(line.direction, oc); var ocLength = top.getLength(oc.x, oc.y, oc.z); var underSqrt = loc * loc - (ocLength * ocLength - radius * radius); if (underSqrt >= 0) { var d = -loc - Math.sqrt(underSqrt); if (d > 0) { // Circle is not behind player and is closest to player var hitPoint = { x: line.origin.x + line.direction.x * d, y: line.origin.y + line.direction.y * d, z: line.origin.z + line.direction.z * d }; var surfaceNormal = top.normalize3DVector({ x: o.position.x - hitPoint.x, y: o.position.y - hitPoint.y, z: o.position.z - hitPoint.z }); var diffuse = top.dot3D(lightDir, surfaceNormal); var index = (x + y * radius * 2) * 4; imageData.data[index] = color[0] * diffuse; imageData.data[index + 1] = color[1] * diffuse; imageData.data[index + 2] = color[2] * diffuse; imageData.data[index + 3] = 255; } } } } if (window.createImageBitmap) { top.spheres[id] = {imageData: undefined, image: undefined}; createImageBitmap(imageData).then(function(imgBitmap) { top.ctx.drawImage(imgBitmap, screenX - radius, screenY - radius); top.spheres[id] = {imageData: undefined, image: imgBitmap}; }); } else { top.ctx.putImageData(imageData, screenX - radius, screenY - radius); top.spheres[id] = {imageData, image: undefined}; } } } /****************** Audio ******************/ this.createSound = function(url, volume = 1, startTime = 0, looping = false) { var audio = new Audio(url); audio.loop = looping; audio.currentTime = startTime; audio.volume = volume; return { volume, startTime, audio }; } this.playSound = function(sound) { sound.audio.currentTime = sound.startTime; sound.audio.volume = sound.volume; sound.audio.play(); } this.stopSound = function(sound) { sound.audio.stop(); } this.pauseSound = function(sound) { sound.audio.pause(); } this.backgroundMusic = function(url) { var audio = new Audio(url); audio.loop = true; audio.play(); return audio; } this.fadeOutSound = function(sound, time = 1) { var startVolume = sound.volume; var count = 0; var interv = setInterval(() => { sound.audio.volume = (startVolume / (time * 20)) * (time * 20 - count); count++; if (count > time * 20) { sound.audio.pause(); clearInterval(interv); } }, 50); } this.playTone = function(freq = 440, time = 1, volume = 1, type = "sine") { var oscillator = top.audioContext.createOscillator(); var gainNode = top.audioContext.createGain() gainNode.gain.value = volume; gainNode.connect(top.audioContext.destination); oscillator.type = type; oscillator.frequency.value = freq; oscillator.connect(gainNode); oscillator.start(); setTimeout(() => { oscillator.stop(); }, time * 1000); } /****************** Math ******************/ this.DegToRad = Math.PI / 180; this.RadToDeg = 180 / Math.PI; this.PI = Math.PI; this.TWO_PI = Math.PI * 2; this.TAU = this.TWO_PI; this.getDistanceSqr = function(x1, y1, x2, y2) { var a = x1 - x2; var b = y1 - y2; return a * a + b * b; } this.getDistanceSqr3D = function(x1, y1, x2, y2, z1, z2) { var a = x1 - x2; var b = y1 - y2; var c = z1 - z2; return a * a + b * b + c * c; } this.getDistance = function(x1, y1, x2, y2) { return Math.sqrt(top.getDistanceSqr(x1, y1, x2, y2)); } this.getDistance3D = function(x1, y1, x2, y2, z1, z2) { return Math.sqrt(top.getDistanceSqr3D(x1, y1, x2, y2, z1, z2)); } this.getAngle = function(x1, y1, x2, y2) { return Math.atan2(y2 - y1, x2 - x1); } this.normalize = function(x, y) { var len = Math.sqrt(x * x + y * y); return { x: x / len, y: y / len }; } this.normalizeVector = function(v) { var len = Math.sqrt(v.x * v.x + v.y * v.y); return { x: v.x / len, y: v.y / len }; } this.normalize3D = function(x, y, z) { var len = Math.sqrt(x * x + y * y + z * z); return { x: x / len, y: y / len, z: z / len }; } this.normalize3DVector = function(x) { var len = Math.sqrt(x.x * x.x + x.y * x.y + x.z * x.z); return { x: x.x / len, y: x.y / len, z: x.z / len }; } this.lengthVector = function(v) { return Math.sqrt(v.x * v.x + v.y * v.y); } this.length3DVector = function(v) { return Math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z); } this.getLength = function() { var sum = 0; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; sum += arg * arg; } return Math.sqrt(sum); } this.dot = function(a, b) { return a.x * b.x + a.y * b.y; } this.dot3D = function(a, b) { return a.x * b.x + a.y * b.y + a.z * b.z; } this.crossProduct3D = function(v1, v2) { return { x: v1.y * v2.z - v1.z * v2.y, y: v1.z * v2.x - v1.x * v2.z, z: v1.x * v2.y - v1.y * v2.x } } //Intersection this.rectanglesIntersect = function(x1, y1, w1, h1, x2, y2, w2, h2) { return x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2; } this.circlesIntersect = function(x1, y1, r1, x2, y2, r2) { return top.getDistance(x1, y1, x2, y2) < r1 + r2; } this.circleRectangleIntersect = function(x1, y1, r1, x2, y2, w2, h2) { var circleDistanceX = Math.abs(x1 - (x2 + w2 / 2)); var circleDistanceY = Math.abs(y1 - (y2 + h2 / 2)); if (circleDistanceX > (w2 / 2 + r1)) return false; if (circleDistanceY > (h2 / 2 + r1)) return false; if (circleDistanceX <= (w2 / 2)) return true; if (circleDistanceY <= (h2 / 2)) return true; var a = circleDistanceX - w2 / 2; var b = circleDistanceY - h2 / 2; var cornerDistance_sq = a * a + b * b; return cornerDistance_sq <= (r1 * r1); } //Random this.random = function(max) { return Math.random() * max; } this.randomInt = function(max) { return Math.random() * max >> 0; } this.randomArray = function(array) { return array[Math.random() * array.length >> 0]; } this..........完整代码请登录后点击上方下载按钮下载查看
网友评论0