#javascript #html #css #canvas
Вопрос:
Я создаю слайдер карусели с холстом. Для каждого нового слайда с фотографией я хотел бы сохранить предыдущий, пока полностью не появится новый.
Я использую requestAnimationFrame для создания эффекта скольжения. Каждый раз мне нужно очищать холст для анимации. Но я хотел бы сохранить предыдущее изображение(рисунок).
Вот пример эффекта, но я делаю это очень неэффективным способом. мой javascript
window.onload = () =gt; { let canvas = document.getElementById("myCanvas"); let ctx = canvas.getContext("2d"); let head = canvas.width; function draw1() { if (head gt; 0) { head = head - 10; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "rgba(0, 255, 255,1)"; ctx.fillRect(head, 0, canvas.width - head, canvas.height); window.requestAnimationFrame(draw1); } } function draw2() { if (head gt; 0) { head = head - 10; ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw the previous canvas again for every update ctx.fillStyle = "rgba(0, 255, 255,1)"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "rgba(255, 0, 255,1)"; ctx.fillRect(head, 0, canvas.width - head, canvas.height); window.requestAnimationFrame(draw2); } } function draw3() { if (head gt; 0) { head = head - 10; ctx.clearRect(0, 0, canvas.width, canvas.height); // Draw the previous canvas again for every update ctx.fillStyle = "rgba(255, 0, 255,1)"; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "rgba(255, 255, 0,1)"; ctx.fillRect(head, 0, canvas.width - head, canvas.height); window.requestAnimationFrame(draw3); } } head = canvas.width; draw1(); setTimeout(() =gt; { head = canvas.width; draw2(); }, 2000); setTimeout(() =gt; { head = canvas.width; draw3(); }, 4000); };
Любая помощь будет признательна. Спасибо.
Комментарии:
1. Есть ли причина для использования холста и JS, а не изображений слайдов с использованием CSS?
Ответ №1:
В вашем случае вы можете рисовать поверх предыдущего изображения, не очищая холст
window.onload = () =gt; { let canvas = document.getElementById('myCanvas') let ctx = canvas.getContext('2d') let head = canvas.width function drawImage(current) { if (head gt; 0) { head = head - 10 ctx.drawImage(current, head, 0, canvas.width, canvas.height) window.requestAnimationFrame(() =gt; drawImage(current)) } } const empty = new Image() const img1 = new Image() img1.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAegr5NqpnuNQdxthB4Ys5O_uiyEqs-CQp6wamp;usqp=CAU' const img2 = new Image() img2.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHFvenDq4nX-LgsmrRPamE9i-NMBkefW7Lzgamp;usqp=CAU' const img3 = new Image() img3.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSyiU9Jkual4WsPg38vFfxvYgDQlUdzOOecVgamp;usqp=CAU' head = canvas.width img1.onload = () =gt; { drawImage(img1) } img2.onload = () =gt; { setTimeout(() =gt; { head = canvas.width drawImage(img2) }, 2000) } img3.onload = () =gt; { setTimeout(() =gt; { head = canvas.width drawImage(img3) }, 4000) } }
body { display: flex; justify-content: center; align-items: center; } canvas { border: 1px solid #000000; }
lt;canvas id="myCanvas" width="440" height="160"gt;lt;/canvasgt;
Редактировать:
Для прозрачных изображений вы можете очистить только ту часть холста, где отображается новое прозрачное изображение. Так что что-то вроде:
ctx.clearRect(head, 0, canvas.width - head, canvas.height)
Вот пример:
window.onload = () =gt; { let canvas = document.getElementById('myCanvas') let ctx = canvas.getContext('2d') let head = canvas.width function drawImage(current) { if (head gt; 0) { head = head - 10 ctx.clearRect(head, 0, canvas.width - head, canvas.height) ctx.drawImage(current, head, 0, canvas.width, canvas.height) window.requestAnimationFrame(() =gt; drawImage(current)) } } const empty = new Image() const img1 = new Image() img1.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAegr5NqpnuNQdxthB4Ys5O_uiyEqs-CQp6wamp;usqp=CAU' const img2 = new Image() img2.src = 'https://api.iconify.design/foundation:social-github.svg' const img3 = new Image() img3.src = 'https://api.iconify.design/foundation:social-twitter.svg' head = canvas.width img1.onload = () =gt; { drawImage(img1) } img2.onload = () =gt; { setTimeout(() =gt; { head = canvas.width drawImage(img2) }, 2000) } img3.onload = () =gt; { setTimeout(() =gt; { head = canvas.width drawImage(img3) }, 4000) } }
body { display: flex; justify-content: center; align-items: center; } canvas { border: 1px solid #000000; } body { display: flex; justify-content: center; align-items: center; } canvas { border: 1px solid #000000; }
lt;canvas id="myCanvas" width="440" height="170"gt;lt;/canvasgt;
И для того, чтобы иметь прозрачное изображение поверх предыдущего изображения, вы можете сделать что-то вроде этого:
window.onload = () =gt; { let canvas = document.getElementById('myCanvas') let ctx = canvas.getContext('2d') let head = canvas.width function drawImage(prev, current) { if (head gt; 0) { head = head - 10 ctx.clearRect(head, 0, canvas.width - head, canvas.height) ctx.drawImage(prev, 0, 0, canvas.width, canvas.height) ctx.drawImage(current, head, 0, canvas.width, canvas.height) window.requestAnimationFrame(() =gt; drawImage(prev, current)) } } const empty = new Image() const img1 = new Image() img1.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQAegr5NqpnuNQdxthB4Ys5O_uiyEqs-CQp6wamp;usqp=CAU' const img2 = new Image() img2.src = 'https://api.iconify.design/foundation:social-github.svg' const img3 = new Image() img3.src = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHFvenDq4nX-LgsmrRPamE9i-NMBkefW7Lzgamp;usqp=CAU' const img4 = new Image() img4.src = 'https://api.iconify.design/foundation:social-twitter.svg' head = canvas.width img1.onload = () =gt; { drawImage(empty, img1) } img2.onload = () =gt; { setTimeout(() =gt; { head = canvas.width drawImage(img1, img2) }, 2000) } img3.onload = () =gt; { setTimeout(() =gt; { head = canvas.width drawImage(img2, img3) }, 5000); } img4.onload = () =gt; { setTimeout(() =gt; { head = canvas.width drawImage(img3, img4) }, 8000); } }
body { display: flex; justify-content: center; align-items: center; } canvas { border: 1px solid #000000; }
lt;canvas id="myCanvas" width="440" height="170"gt;lt;/canvasgt;
Комментарии:
1. некоторые из моих фотографий в формате png, и у них прозрачный фон
2. @user16971617 В этом случае вы можете очистить только часть нового изображения, используя
ctx.clearRect(head, 0, canvas.width - head, canvas.height)
вместо очистки всего холста. см. Пример в отредактированном ответе.3. Спасибо. Но есть ли способ сохранить предыдущее изображение в фоновом режиме?
4. @user16971617 Вы имеете в виду, что когда новое прозрачное изображение полностью сдвинуто, старое изображение все еще видно сзади?
5. да, потому что мне нужно увидеть старое изображение во время перехода.