javascript - 淡出文本并淡入下一个 Canvas

标签 javascript jquery css html canvas

所以我在我的游戏中有一个 Canvas ,它会显示一些文本,但如果你曾经玩过Clicker Heros,我希望它是这样的,当你点击时会显示一些损坏文本,但它会淡入并且慢慢地出来,有点向上移动,同时淡出我想在这里产生同样的效果

所以我拥有的是一个函数,当用户单击终端时我需要文本来产生类似的行为,但我对 Canvas 很陌生,不知道如何在这里这样做是我当前的代码

var canvas = document.getElementById("terminalCanvas");
var terminal = canvas.getContext("2d");

terminal.fillStyle = "#000000";
terminal.fillRect(0,0,150,200);

function WriteToCanvas(){
    if(Game.Player.HTMLSupport == 1){
        var rand = Math.floor(Math.random() * 122) + 1;
        var tag = htmltags[rand];
        terminal.font = "20px Comic Sans MS";
        terminal.fillStyle = "rgb(0,255,1)";
        terminal.textAlign = "center";
        terminal.fillText(tag, canvas.width/2, canvas.height/2);
        ClearCanvas();
    }
}

function ClearCanvas(){
    terminal.clearRect(0,0,canvas.width,canvas.height);
    terminal.fillStyle = "#000000";
    terminal.fillRect(0,0,150,200);
}

最佳答案

您需要一个粒子系统。代码顶部的波纹管是您需要做一个简单且内存高效的粒子系统。 使用粒子池。当时间到了时,死颗粒会进入池中。当需要新的粒子时,检查池中是否有死的粒子,如果有则复活它们,否则创建一个新的。这避免了可怕的 GC 滞后,粒子系统会使工作变得更加困难。

如果您不使用 fillText(因为它非常慢)来渲染粒子,而是预渲染并使用 drawImage,这可能会有所返回。由你决定。

对不起,我没有时间进行更深入的解释

/*=====================================================================================
ANSWER code start
=====================================================================================*/


const LIFETIME = 1 / 180; // 180 frames
const YDIST = -140; // number of pixels to move over the life 
const MOVE_CURVE_SHAPE = 1.5;
const FADE_CURVE_SHAPE = 1.5;
const FADE_CURVE_ADVANCE = 0.25; // Want the fade not to start early on the fade curve
var particles = []; // array to hold live particles
var particlePool = []; // to hold the dead



// this function is called once a frame
function display(){  // put code in here
    ctx.setTransform(1,0,0,1,0,0); // reset transform
    ctx.globalAlpha = 1;           // reset alpha
    ctx.clearRect(0,0,w,h);
    ctx.font = "40px Comic Sans MS";
    ctx.fillStyle = "black";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText("Click mouse to add particles",canvas.width/2, 30);
    if(mouse.buttonRaw & 1){
        var p;
        if(particlePool.length){ // check if the are any dead particles in the pool
            p = particlePool.shift(); // if so get the first on in out
        }else{ // nothing in the pool so create a new on
            p = {};
        }
        // set up the paticle    
        var text = (Math.floor(Math.random()* 10) *100) + "!"; // the text to display
        p = createParticle(mouse.x,mouse.y,text,p); // set up the particle
        particles.push(p); // push it onto the active array
        mouse.buttonRaw = 0; // clear mouse down;
    }
    
    updateParticles(); // update particles
    renderParticles(); // and draw them
    
}


// sets up a particle x,y startung pos, text the value to display, p and object to hold the data
function createParticle(x,y,text,p){
    p.life = 1;  // when this get down to zero it is dead
    p.x = x;
    p.y = y;
    p.text = text;
    return p;
}


// ease functions
var easeBell = function (x, pow) {  // x 0-1 pos > 0 
    x = x * 2;
    if( x > 1){
        x = 1 - (x - 1);
        var xx = Math.pow(x,pow);
        return xx / (xx + Math.pow(1 - x, pow));
    }else{
        var xx = Math.pow(x,pow);
        return xx / (xx + Math.pow(1 - x, pow));
    }
}
var ease = function (x, pow) {  // x 0-1 pos > 0 
    var xx = Math.pow(x,pow);
    return xx / (xx + Math.pow(1 - x, pow));
}
function updateParticles(){  // update the life and  death of the particles
    for(var i = 0; i < particles.length; i ++){
         var p = particles[i];
         p.life -= LIFETIME;
         if(p.life <= 0){ // time is up this particle is dead
                          // move it to the grave
             particlePool.push(p);
             particles.splice(i,1); // remove it from the array
             i -= 1; // adjust i so we dont skip any
         }
     } 
}

function renderParticles(){
    ctx.font = "20px Comic Sans MS"
    ctx.fillStyle = "#F00";
    for(var i = 0; i < particles.length; i ++){ // for each active particle
         var p = particles[i];
         var fadeCurveVal = 1- p.life;
         fadeCurveVal *= (1 - FADE_CURVE_ADVANCE); // scale it down
         fadeCurveVal += FADE_CURVE_ADVANCE; // move it forward
         
         ctx.globalAlpha = easeBell(fadeCurveVal,FADE_CURVE_SHAPE); // get the fade fx
         var y = p.y + ease((1-p.life)/2,MOVE_CURVE_SHAPE) * YDIST * 2;
         ctx.fillText(p.text,p.x,y);
    }
}

         
/*=====================================================================================
ANSWER code End
=====================================================================================*/















/** SimpleFullCanvasMouse.js begin **/
const CANVAS_ELEMENT_ID = "canv";
const U = undefined;
var w, h, cw, ch; // short cut vars 
var canvas, ctx, mouse;
var globalTime = 0; 
var createCanvas, resizeCanvas, setGlobals;
var L = typeof log === "function" ? log : function(d){ console.log(d); }
createCanvas = function () {
    var c,cs;
    cs = (c = document.createElement("canvas")).style; 
    c.id = CANVAS_ELEMENT_ID;    
    cs.position = "absolute";
    cs.top = cs.left = "0px";
    cs.zIndex = 1000;
    document.body.appendChild(c); 
    return c;
}
resizeCanvas = function () {
    if (canvas === U) { canvas = createCanvas(); }
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight; 
    ctx = canvas.getContext("2d"); 
    if (typeof setGlobals === "function") { setGlobals(); }
}
setGlobals = function(){ cw = (w = canvas.width) / 2; ch = (h = canvas.height) / 2; }
mouse = (function(){
    function preventDefault(e) { e.preventDefault(); }
    var mouse = {
        x : 0, y : 0, w : 0, alt : false, shift : false, ctrl : false, buttonRaw : 0,
        over : false,  // mouse is over the element
        bm : [1, 2, 4, 6, 5, 3], // masks for setting and clearing button raw bits;
        mouseEvents : "mousemove,mousedown,mouseup,mouseout,mouseover,mousewheel,DOMMouseScroll".split(",")
    };
    var m = mouse;
    function mouseMove(e) {
        var t = e.type;
        m.x = e.offsetX; m.y = e.offsetY;
        if (m.x === U) { m.x = e.clientX; m.y = e.clientY; }
        m.alt = e.altKey; m.shift = e.shiftKey; m.ctrl = e.ctrlKey;
        if (t === "mousedown") { m.buttonRaw |= m.bm[e.which-1]; }  
        else if (t === "mouseup") { m.buttonRaw &= m.bm[e.which + 2]; }
        else if (t === "mouseout") { m.buttonRaw = 0; m.over = false; }
        else if (t === "mouseover") { m.over = true; }
        else if (t === "mousewheel") { m.w = e.wheelDelta; }
        else if (t === "DOMMouseScroll") { m.w = -e.detail; }
        if (m.callbacks) { m.callbacks.forEach(c => c(e)); }
        e.preventDefault();
    }
    m.addCallback = function (callback) {
        if (typeof callback === "function") {
            if (m.callbacks === U) { m.callbacks = [callback]; }
            else { m.callbacks.push(callback); }
        } else { throw new TypeError("mouse.addCallback argument must be a function"); }
    }
    m.start = function (element, blockContextMenu) {
        if (m.element !== U) { m.removeMouse(); }        
        m.element = element === U ? document : element;
        m.blockContextMenu = blockContextMenu === U ? false : blockContextMenu;
        m.mouseEvents.forEach( n => { m.element.addEventListener(n, mouseMove); } );
        if (m.blockContextMenu === true) { m.element.addEventListener("contextmenu", preventDefault, false); }
    }
    m.remove = function () {
        if (m.element !== U) {
            m.mouseEvents.forEach(n => { m.element.removeEventListener(n, mouseMove); } );
            if (m.contextMenuBlocked === true) { m.element.removeEventListener("contextmenu", preventDefault);}
            m.element = m.callbacks = m.contextMenuBlocked = U;
        }
    }
    return mouse;
})();
var done = function(){
    window.removeEventListener("resize",resizeCanvas)
    mouse.remove();
    document.body.removeChild(canvas);    
    canvas = ctx = mouse = U;
    L("All done!")
}

resizeCanvas(); // create and size canvas
mouse.start(canvas,true); // start mouse on canvas and block context menu
window.addEventListener("resize",resizeCanvas); // add resize event


function update(timer){ // Main update loop
    globalTime = timer;
    display();  // call demo code
    // continue until mouse right down
    if (!(mouse.buttonRaw & 4)) { requestAnimationFrame(update); } else { done(); }
}
requestAnimationFrame(update);

/** SimpleFullCanvasMouse.js end **/

关于javascript - 淡出文本并淡入下一个 Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38257201/

相关文章:

modal-dialog - bootstrap jquery show.bs.modal 事件不会触发

css - 非分类元素中断分类元素子元素的目标样式

html - 如何根据子元素的宽度高效分配列宽?

javascript - 在远程站点 iFrame 中嵌入 Reactjs

javascript - 换行 XUL 元素

javascript - 如何使 Jquery 表单验证函数在其他函数之前执行/触发?

javascript - 首次单击后禁用单选按钮或分数增量

html - CSS:Safari/Firefox 中的文本颜色略有偏移

javascript - 在这种情况下还有更漂亮的解决方案吗?

javascript - 使用 Node.js 选择哪个数据库(NoSQL 或常规 SQL)最好?