2015-05-05 5 views
0

Мне нужна помощь экспертов. Когда я делаю прозрачный холст прозрачным, линия окрашивает весь холст (показано в коде ниже).Как остановить окраску линии над прозрачным холстом?

Как остановить/исправить это? Я хочу, чтобы строка оставалась одной строкой, которая не окрашивает холст.

Math.clamp = function(x, min, max) { 
    return x < min ? min : (x > max ? max : x); 
}; 

// canvas settings 
var viewWidth = window.innerWidth, 
    viewHeight = window.innerHeight, 
    drawingCanvas = document.getElementById("drawing_canvas"), 
    ctx, 
    timeStep = (10/100), 
    time = 0; 

var lineTension = 0.067, 
    lineDamping = 0.068, 
    waveSpreadFactor = 0.1; 

var previousMousePosition = { 
    x: 0, 
    y: 0 
    }, 
    currentMousePosition = { 
    x: 0, 
    y: 0 
    }, 
    actualMousePosition = { 
    x: 0, 
    y: 0 
    }; 

var line, 
    lineSegmentCount = 64, 
    lineMaxForce = 32, 
    lineStrokeGradient; 

var audioCtx, 
    nodeCount = 64, 
    oscillatorNodes = [], 
    gainNodes = []; 

var segmentsPerNode = lineSegmentCount/nodeCount; 

function initGui() { 

} 

function goBananas() { 
    lineTension = 0.2; 
    line.anchors[Math.floor(Math.random() * line.anchors.length)]. 
    vel = lineMaxForce; 
} 

function resetLine() { 
    line.reset(); 

    for (var i = 0; i < nodeCount; i++) { 
    oscillatorNodes[i].detune.value = 100; 
    gainNodes[i].gain.value = 0; 
    } 

    lineTension = 0.0025; 
    lineDamping = 0.05; 
    waveSpreadFactor = 0.1; 
} 

function initDrawingCanvas() { 
    drawingCanvas.width = viewWidth; 
    drawingCanvas.height = viewHeight; 

    window.addEventListener('resize', resizeHandler); 
    window.addEventListener('mousemove', mouseMoveHandler); 
    setInterval(updateMousePosition, (1000/30)); 

    ctx = drawingCanvas.getContext('2d'); 
    ctx.lineWidth = 5; 

    line = new Line(0, viewHeight * 0.5, viewWidth, lineSegmentCount); 
    // line.anchors[0].vel = viewHeight * 0.25; 

    lineStrokeGradient = ctx.createLinearGradient(0, 0, 0, viewHeight); 
    lineStrokeGradient.addColorStop(0, '#0ff'); 
} 

function initWebAudio() { 
    audioCtx = new(window.AudioContext || window.webkitAudioContext)(); 

    for (var i = 0; i < nodeCount; i++) { 
    var oscillatorNode = audioCtx.createOscillator(); 
    var gainNode = audioCtx.createGain(); 

    oscillatorNode.connect(gainNode); 
    gainNode.connect(audioCtx.destination); 

    gainNode.gain.value = 0; 

    oscillatorNode.type = 'saw'; 
    oscillatorNode.detune.value = 200; 
    oscillatorNode.frequency.value = 1200 * (i/60); 
    oscillatorNode.start(); 

    oscillatorNodes[i] = oscillatorNode; 
    gainNodes[i] = gainNode; 
    } 
} 

function resizeHandler() { 
    drawingCanvas.width = viewWidth = window.innerWidth; 
    drawingCanvas.height = viewHeight = window.innerHeight; 

    if (ctx) { 
    ctx.lineWidth = 4; 
    line.resize(viewWidth, viewHeight * 0.5); 
    } 
} 

function mouseMoveHandler(event) { 
    actualMousePosition.x = Math.floor(event.clientX); 
    actualMousePosition.y = Math.floor(event.clientY); 
} 

function updateMousePosition() { 
    previousMousePosition.x = currentMousePosition.x; 
    previousMousePosition.y = currentMousePosition.y; 
    currentMousePosition.x = actualMousePosition.x; 
    currentMousePosition.y = actualMousePosition.y; 
} 

function update() { 
    var px = Math.min(previousMousePosition.x, currentMousePosition.x), 
    py = Math.min(previousMousePosition.y, currentMousePosition.y), 
    pw = Math.max(1, Math.abs(previousMousePosition.x - currentMousePosition.x)), 
    ph = Math.max(1, Math.abs(previousMousePosition.y - currentMousePosition.y)), 
    force = Math.clamp(currentMousePosition.y - 
     previousMousePosition.y, -lineMaxForce, lineMaxForce); 

    var pixels = ctx.getImageData(px, py, pw, ph), 
    data = pixels.data; 

    for (var i = 0; i < data.length; i += 3) { 
    var r = data[i + 0], 
     g = data[i + 1], 
     b = data[i + 2], 
     x = (i % ph) + px; 

    if (r + g + b > 0) { 
     line.ripple(x, force); 
    } 
    } 

    line.update(); 

    for (var j = 0; j < gainNodes.length; j++) { 
    var anchor = line.anchors[j * segmentsPerNode], 
     gain = Math.clamp(Math.abs(anchor.vel)/viewHeight * 0.5, 0, 3), 
     detune = Math.clamp(anchor.pos/viewHeight * 100, 0, 300); 

    gainNodes[j].gain.value = gain; 
    oscillatorNodes[j].detune.value = detune; 
    } 
} 

function draw() { 

    ctx.strokeStyle = lineStrokeGradient; 
    line.draw(); 
} 

window.onload = function() { 
    initDrawingCanvas(); 
    initWebAudio(); 
    initGui(); 

    requestAnimationFrame(loop); 
}; 

function loop() { 
    update(); 
    draw(); 
    time += timeStep; 
    requestAnimationFrame(loop); 
} 



Line = function(x, y, length, segments) { 
    this.x = x; 
    this.y = y; 
    this.length = length; 
    this.segments = segments; 

    this.segmentLength = this.length/this.segments; 
    this.anchors = []; 

    for (var i = 0; i <= this.segments; i++) { 
    this.anchors[i] = { 
     target: this.y, 
     pos: this.y, 
     vel: 0, 
     update: function() { 
     var dy = this.pos - this.target, 
      acc = -lineTension * dy - lineDamping * this.vel; 

     this.pos += this.vel; 
     this.vel += acc; 
     }, 
     reset: function() { 
     this.pos = this.target; 
     this.vel = 0; 
     } 
    }; 
    } 
}; 

Line.prototype = { 
    resize: function(length, targetY) { 
    this.length = length; 
    this.segmentLength = this.length/this.segments; 

    for (var i = 0; i <= this.segments; i++) { 
     this.anchors[i].target = targetY; 
    } 
    }, 
    reset: function() { 
    for (var i = 0; i <= this.segments; i++) { 
     this.anchors[i].reset(); 
    } 
    }, 
    ripple: function(origin, amplitude) { 
    var i = Math.floor((origin - this.x)/this.segmentLength); 

    if (i >= 0 && i <= this.segments) { 
     this.anchors[i].vel = amplitude; 
    } 
    }, 
    update: function() { 
    var lDeltas = [], 
     rDeltas = [], 
     i; 

    for (i = 0; i <= this.segments; i++) { 
     this.anchors[i].update(); 
    } 

    for (i = 0; i <= this.segments; i++) { 
     if (i > 0) { 
     lDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i - 1].pos); 
     this.anchors[i - 1].vel += lDeltas[i]; 
     } 
     if (i < this.segments) { 
     rDeltas[i] = waveSpreadFactor * (this.anchors[i].pos - this.anchors[i + 1].pos); 
     this.anchors[i + 1].vel += rDeltas[i]; 
     } 
    } 

    for (i = 0; i <= this.segments; i++) { 
     if (i > 0) { 
     this.anchors[i - 1].pos += lDeltas[i]; 
     } 
     if (i < this.segments) { 
     this.anchors[i + 1].pos += rDeltas[i]; 
     } 
    } 
    }, 
    draw: function() { 
    ctx.beginPath(); 

    for (var i = 0; i <= this.segments; i++) { 
     ctx.lineTo(
     this.x + this.segmentLength * i, 
     this.anchors[i].pos 
    ); 
    } 
    ctx.stroke(); 
    } 
}; 

ответ

0

Из кода вы в курсе, проблема, кажется, отсутствует

ctx.clearRect(0, 0, viewWidth, viewHeight) 

в начале вашей функции «рисовать».

See a working example here

Смежные вопросы