2014-10-28 3 views
0

Попытка обернуть голову вокруг холста HTML5, я подумал, что создаю карусель изображений, где изображения будут изменены с помощью градиента прозрачности, то есть то же самое, что и в моей скрипке here, только с холстом. Мне удалось найти this fiddle, но я не могу понять, что происходит, точнее, почему ничего нет.Анимированный переход изображения с холстом HTML5

Вот код:

var outputCanvas = document.getElementById('output'), 
    ctx = outputCanvas.getContext('2d'), 
    eWidth = 50, 
    speed = 5, 
    cWidth = 480, 
    img = document.getElementById('newimg'), 
    x = 0, y = 0, 
    reqAnimFrame = window.mozRequestAnimationFrame || 
     window.webkitRequestAnimationFrame || 
     window.msRequestAnimationFrame  || 
     window.oRequestAnimationFrame; 

ctx.drawImage(img, 0, 0, img.width, img.height); 
ctx.globalCompositeOperation = "destination-out"; 

function draw() { 
    console.log(x); 
    gradient = ctx.createLinearGradient(x, 0, x+eWidth, 0); 
    gradient.addColorStop(0, "rgba(255, 255, 255, 0)"); 
    gradient.addColorStop(1, "rgba(255, 255, 255, 1)"); 
    ctx.fillStyle = gradient; 
    ctx.fillRect(0, 0, img.width, img.height); 
} 

function animate() { 
    if (x < 480) { 
     x += Math.floor((cWidth/1000) * speed); 
     console.log(x); 
     draw(); 
     reqAnimFrame(animate); 
    } 
} 

reqAnimFrame(animate); 

Вызов функции draw сама по себе она, кажется, работает, но как только я начинаю стрелять из него с RequestAnimationFrame он просто перестает работать. Градиент рисуется один раз, но хотя x обновляется в цикле анимации, градиент остается помещенным.

Я думаю, что есть что-то, что я просто не понимаю, как работают холсты и RequestAnimationFrame.

Обратите внимание, что я не ищу скрипт или библиотеку, которая делает то же самое, но я надеюсь, что на самом деле пойму, как работает холст, и, в частности, почему мой сценарий не работает.

+0

С одной стороны, 'reqAnimFrame (живой),' должен быть 'requestAnimationFrame (одушевленные);' – markE

+0

@markE К сожалению , Я забыл вставить бит, где определен 'reqAnimFrame'. Я не думаю, что в этом проблема. – Schlaus

+0

Что именно делает 'console.log (x)' output? – soktinpk

ответ

3

Вот один из способов сделать протирать переход между 2 изображений с использованием Canvas композитинг:

оригинальных изображений (перед тем & после):

enter image description hereenter image description here

Холст во градиент протереть-переход между изображения:

enter image description here

  • создать прозрачный непрозрачный градиент, который является шириной шириной eWidth.

  • очистить холст

  • рисовать градиент

  • заполнить все пиксели справа от градиента с непрозрачной

  • нарисовать первое изображение с source-in композиции. Это отобразит первое изображение только там, где градиент имеет непрозрачные пиксели.

  • нарисовать второе изображение с композицией «назначение». Это отобразит второе изображение под «существующим первым изображением».

Вот пример кода и демо:

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

 
var cw,ch; 
 
var x=0; 
 
var eWidth=100; 
 

 
var img1=new Image(); 
 
var img=new Image(); 
 
img.onload=start; 
 
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sailboat.png"; 
 
function start(){ 
 

 
    cw=canvas.width=img.width; 
 
    ch=canvas.height=img.height; 
 

 
    img1.onload=function(){ 
 
    requestAnimationFrame(animate); 
 
    }; 
 
    img1.src="https://dl.dropboxusercontent.com/u/139992952/multple/sailboat1.png"; 
 

 
} 
 

 

 
function draw() { 
 

 
    // create gradient 
 
    gradient = ctx.createLinearGradient(x-eWidth,0, x,0); 
 
    gradient.addColorStop(0, "rgba(0,0,0, 0)"); 
 
    gradient.addColorStop(1, "rgba(0,0,0, 1)"); 
 

 
    // save the unaltered canvas context 
 
    ctx.save(); 
 

 
    // clear the canvas 
 
    ctx.clearRect(0,0,cw,ch); 
 

 
    // gradient zone 
 
    ctx.fillStyle = gradient; 
 
    ctx.fillRect(x-eWidth,0,eWidth,ch); 
 

 
    // fully original right of x 
 
    ctx.fillStyle='black'; 
 
    ctx.fillRect(x,0,cw,ch); 
 

 
    // original image with gradient "dissolve" on left 
 

 
    // set compositing to source-in 
 
    ctx.globalCompositeOperation='source-in'; 
 
    ctx.drawImage(img,0,0); 
 

 
    // revealed image 
 
    ctx.globalCompositeOperation='destination-over'; 
 
    ctx.drawImage(img1,0,0); 
 

 
    // restore the context to its unaltered state 
 
    ctx.restore(); 
 
} 
 

 

 
function animate() { 
 
    if (x<cw+eWidth){ requestAnimationFrame(animate); } 
 
    x+=5; 
 
    draw(); 
 
} 
 

 
$('#again').click(function(){ 
 
    x=0; 
 
    requestAnimationFrame(animate);  
 
});
body{ background-color: ivory; padding:10px; } 
 
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<h4>Wipe transition between images using canvas</h4> 
 
<button id=again>Again</button><br><br> 
 
<canvas id="canvas" width=300 height=300></canvas>

+0

Очень тщательный ответ, спасибо! Мой исходный код не работал, потому что я использовал 'globalCompositeOperation' неправильно. – Schlaus