2014-01-04 3 views
2

Я пытаюсь использовать четыре холста, уложенных друг на друга, но содержимое их не будет отображаться, кроме содержимого того, что находится сверху. Я помещал им значения z-index в том порядке, в котором я бы хотел их отображать, но только верхний отображает содержимое. Их позиция абсолютна, а их индексы z - 1, 2, 3 и 4. Есть ли что-то еще, что делает их не отображаемыми? Или, сколько полотенец можно было бы складывать вместе, чтобы все их содержимое отображалось?Штабелирование нескольких холстов в HTML5

У меня есть это:

<div></div> 
<canvas id="bg" width="500" height="500"></canvas> <!--z-index:1 --> 
<canvas id="lc" width="500" height="500"></canvas> <!--z-index:2 --> 
<canvas id="rc" width="500" height="500"></canvas> <!--z-index:3 --> 
<canvas id="ch" width="500" height="500"></canvas> <!--z-index:4 --> 
<!-- Script that draws image in each canvas with different x and y values --> 

Проблема заключается в том, что при запуске функции, картина, которую я рисую появляется только один раз, что означает, что только рисовал его на одном холсте ... К примеру, я будете иметь скрипт что-то вроде этого:

function drawImgs() { 
    var bg = document.getElementById('bg').getContext('2d'), 
     lc = document.getElementById('lc').getContext('2d'), 
     rc = document.getElementById('rc').getContext('2d'), 
     ch = document.getElementById('ch').getContext('2d'), 
     img = new Image(); 
    img.src = "image.png"; 
    bg.drawImage(img,0,0); 
    lc.drawImage(img,64,64); 
    rc.drawImage(img,128,128); 
    ch.drawImage(img,192,192); 
} 
drawImgs(); 

это будет только рисовать изображение на холсте ч, в X: 192, Y: 192. Почему это? Есть ли способ предотвратить это или, по крайней мере, убедиться, что все изображения нарисованы? Это потому, что я использую одно и то же изображение, или же полотна просто не прозрачны? Есть ли предел тому, сколько полотна вы можете просмотреть?

Вся информация будет оценена по достоинству. Заранее спасибо.

Редактировать: Однако, если у меня есть только две полотна, оба изображения визуализируются. Почему это? Не удалось ли, по крайней мере, сделать два изображения, если у меня есть четыре собрания, сложенные вместе?

Edit: Я был возиться с кодом, который я получил от вас, ребят (спасибо за всю информацию, все помогло), и я пытался поставить его в мой фактический проект (я тестировал код, и это было работая до того, как я включил его в свой проект), но когда я вложил его в свои файлы, он снова перестал работать. Поэтому я перепутал, и я заметил, что, когда я не добавил CSS, чтобы сделать страницу такой, что она будет работать ... Я продолжал возиться, и я узнал, что фоновый цвет холста снимает прозрачность, это было просто так все время ... Так что я просто положил его на первый холст, bg, потому что моя страница черная, и я хотел, чтобы холст был белым ... В любом случае, спасибо за помощь каждого, это очень ценится.

+0

Хотя я признаю, что у меня проблемы с jsfiddle, проблемы, с которыми я сталкиваюсь, - это не те, которые вы испытываете (http://jsfiddle.net/t5EFp/2/) (ударить снова, если ничего показывает). – Daedalus

+0

Редактируйте свою скрипку и прокомментируйте две средние полотна и drawImage-вызовы (lc, rc), и изображения будут отображаться ... – user2673553

+0

Вам не хватает моей точки. Я также просто попробовал это; он не фиксирует скрипку. Как я и сказал; он отлично работает, если вы просто нажмете пробег снова. – Daedalus

ответ

2

Первый шаг, чтобы обернуть свои холсты в контейнер:

<div id="stack"> 
    <canvas id="bg" width="500" height="500"></canvas> 
    <canvas id="lc" width="500" height="500"></canvas> 
    <canvas id="rc" width="500" height="500"></canvas> 
    <canvas id="ch" width="500" height="500"></canvas> 
<div> 

затем правильно применять правила CSS:

#stack { 
    position:relative; 
    } 
#stack > canvas { 
    position:absolute; 
    left:0; 
    top:0; 
    } 

z-index не стоит здесь, как первый холст будет на дне и т.д. .

Далее следует реализовать обработчик загрузчика изображений, так как загрузка изображения является асинхронной. По этой причине ваше изображение не отображается, так как изображение не закончило загрузку до вызова drawImage() (ко времени, когда код попадает в «четвертый» элемент, изображение может быть загружено в зависимости от различных факторов, таких как кеш, производительность системы и т.д., - но это в категории «случайный результат»:

var bg = document.getElementById('bg').getContext('2d'), 
    lc = document.getElementById('lc').getContext('2d'), 
    rc = document.getElementById('rc').getContext('2d'), 
    ch = document.getElementById('ch').getContext('2d'), 
    img = new Image(); 

img.onload = drawImgs; /// set handler 
img.src = "image.png"; /// set url 

function drawImgs() { 
    /// 'this' is the loaded image 
    bg.drawImage(this, 0,0); 
    lc.drawImage(this, 64,64); 
    rc.drawImage(this, 128,128); 
    ch.drawImage(this, 192,192); 

    /// continue rest of code here... 
} 

Если поместить скрипт в нижней части страницы то это его Если в заголовке обернуть сценарий:

window.onload = function() { 

    ... code above here... 
} 
.

Другие соображения состоят в том, что изображение загружается должным образом. Для этого вы можете использовать onerror и onabort Обработчики на объекте изображения:

img.onerror = functionToHandleError; 
img.onabort = functionToHandleAbort; 

также они определены перед установкой src свойства.

0

Холсты могут быть прозрачными; Раньше я использовал этот метод. Я выставил JSFiddle, который вы можете проверить, чтобы убедиться, что ваш браузер не прошел дурацкий; Я использую тот же метод, который вы используете в вашем примере кода, просто рисуя квадрат вместо изображения. Я думаю, что проблема в другом.

<canvas id="top" height=100 width=100></canvas> 
<canvas id="tall" height=100 width=100></canvas> 
<canvas id="short" height=100 width=100></canvas> 
<canvas id="bottom" height=100 width=100></canvas> 

и JS

var top = document.getElementById("top").getContext("2d"); 
var tall = document.getElementById("tall").getContext("2d"); 
var short = document.getElementById("short").getContext("2d"); 
var bottom = document.getElementById("bottom").getContext("2d"); 

top.fillRect(0,0,10,10); 
tall.fillRect(20,20,10,10); 
short.fillRect(40,40,10,10); 
bottom.fillRect(60,60,10,10); 

Для отладки, я бы просто попробовать рисунок в каждом полотне человека, удаляя остальные из вашего HTML, чтобы убедиться, что у вас есть все ваши ссылки право (его похоже, что вы это делаете.) Затем дважды проверьте свой CSS и z-index, чтобы убедиться, что вы каким-то образом не скрываете элемент, либо не показываете его, либо помещаете свой z-индекс за другой объект. Наконец, убедитесь, что ни один другой код не очищает ваши холсты или, возможно, рисует ваш образ (если он рисовал того же цвета, что и ваш фон, казалось бы, что холст был пустым, когда он был действительно заполнен фоном цвет.)

+0

Я посмотрел ваш код, и полотна не кажутся перекрывающимися друг с другом. Мне нужно, чтобы они были, хотя я заменил fillRect() на drawImage(), и он сделал то же самое, что и всегда. Даже с fillRects() – user2673553

+0

Извините, обновленный Fiddle. Однако у Дедала есть подобный и лучший. Вы видите все четыре квадрата в наших? – Hylianpuffball

+0

Я вижу все квадраты ПОСЛЕ того, как я снова нажимаю клавишу пробега, до этого он не покажется – user2673553

1

Убедитесь, что вы используете CSS, чтобы стек каждый холст на верхней части друг друга

canvas{position:absolute;border:1px solid red;} 

Убедитесь, что вы даете свое время изображения для загрузки

var img=new Image(); 
img.onload=function(){ 
    bg.drawImage(img,0,0); 
    lc.drawImage(img,64,64); 
    rc.drawImage(img,128,128); 
    ch.drawImage(img,192,192); 
} 
img.src="img.png"; 

Вот пример:

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; } 
    #wrapper{position:relative;} 
    canvas{position:absolute;border:1px solid red;} 
</style> 

<script> 
window.onload=function(){ 


    var ctxs=[]; 
    for(var i=0;i<5;i++){ 
     ctxs.push(document.getElementById("canvas"+i).getContext("2d")); 
     ctxs[i].fillStyle="black"; 
     ctxs[i].font="12px verdana"; 
     ctxs[i].fillRect(50,i*30+20,100,20); 
     ctxs[i].fillStyle="white"; 
     ctxs[i].fillText("canvas#"+i,60,i*30+35); 
    }; 

} 
</script> 

</head> 

<body> 
    <div id="wrapper"> 
     <canvas id="canvas0" width=300 height=300></canvas> 
     <canvas id="canvas1" width=300 height=300></canvas> 
     <canvas id="canvas2" width=300 height=300></canvas> 
     <canvas id="canvas3" width=300 height=300></canvas> 
     <canvas id="canvas4" width=300 height=300></canvas> 
    </div> 
</body> 
</html> 

Последняя мысль: вы можете быстро взглянуть на jQuery. Это отличная утилитная библиотека, которая отлично справляется с решением кросс-браузерных несоответствий. Он хорошо протестирован и широко используется, поэтому ваш пользователь уже может его кэшировать на своей машине.

+0

Этот ответ был бы лучше, если бы он не зависел от jQuery, которого нет в списке, кроме этого вопроса. – Daedalus

+0

@Daedalus Я так думаю. jQuery существует только для функции onload - никакой существенной зависимости от кода. Вы можете заменить функцию window.onload javascript, если это вас беспокоит. Помимо этого, как вам нравится ответ - добавляет ли он к обсуждению? – markE

+0

Когда вы измените его, я дам вам верх. В противном случае мне не нравится зависимость jQuery, как уже отмечалось. – Daedalus

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