Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.06.2021, 14:51
Профессор
Отправить личное сообщение для Янковиц Посмотреть профиль Найти все сообщения от Янковиц
 
Регистрация: 17.11.2014
Сообщений: 403

Прозрачность слоёв canvas
Использую небольшую библиотечку для задания слоёв в canvas. Привожу полный код.
<html>
<head>
	<title>layeredCanvas Example</title>
</head>
<body>
	<canvas id="theCanvas" width="512" height="512"></canvas>

	<script>
	/*
	layeredCanvas v0.1

	by Federico Jacobi
	federicojacobi.com

	Abstraction layer on canvas to mimic the use of layers
	*/

	layeredCanvas = function ( id ) {
		this.layers = [];
		
		var extend = function ( defaults, options ) {
			var extended = {} , prop;
			for (prop in defaults) {
				if (Object.prototype.hasOwnProperty.call(defaults, prop))
					extended[prop] = defaults[prop];
			}
			for (prop in options) {
				if (Object.prototype.hasOwnProperty.call(options, prop))
					extended[prop] = options[prop];
			}
			return extended;
		};

		this.addLayer = function( obj ) {

			layer = extend( {
				id: Math.random().toString(36).substr(2, 5),
				show: true,
				render: function( canvas, ctx ) {}
			}, obj );

			if ( this.getLayer( layer.id ) !== false ) {
				console.log( 'Layer already exists' );
				console.log( obj );
				return false;
			}
			
			this.layers.push( layer );
			return this;
		};
		
		this.getLayer = function( id ) {
			var length = this.layers.length;
			for ( var i = 0; i < length; i++ ) {
				if ( this.layers[i].id === id )
					return this.layers[i];
			}
			return false;
		};
		
		this.removeLayer = function( id ) {
			var length = this.layers.length;
			for ( var i = 0; i < length; i++ ) {
				if ( this.layers[i].id === id ) {
					removed = this.layers[i];
					this.layers.splice( i, 1 );
					return removed;
				}
			}
			return false;
		};
		
		this.render = function() {
			var canvas = this.canvas;
			var ctx = this.ctx2d;
			this.layers.forEach( function( item, index, array ) {
				if ( item.show )
					item.render( canvas, ctx );
			});
		};
		
		this.canvas = document.getElementById( id );
		this.ctx2d = this.canvas.getContext( '2d' );
	};
	
	window.addEventListener( 'load', function() {
		var myCanvas = new layeredCanvas( "theCanvas" );

		myCanvas.addLayer( {
			id: 'background',
			render: function( canvas, ctx ) {
				ctx.fillStyle = "black";
				ctx.fillRect( 0, 0, canvas.width, canvas.height );
			}
		})
		.addLayer( {
			id: 'squares',
			render: function( canvas, ctx ) {
				ctx.globalAlpha = opacity;

				ctx.fillStyle = "#E5E059";
				ctx.fillRect( 50, 50, 150, 150 );

				ctx.fillStyle = "#BDD358";
				ctx.fillRect( 350, 75, 150, 150 );

				ctx.fillStyle = "#E5625E";
				ctx.fillRect( 50, 250, 100, 250 );
			}
		});

		var opacity = 1;
		var fadeEffect = setInterval( function () {
			if ( opacity > 0 ) {
				opacity -= 0.0125;
			} else {
				clearInterval( fadeEffect );
				opacity = 0;
			}
			console.log(opacity)
			myCanvas.render();
		}, 10 );
	});
	</script>
</body>
</html>


Проблема в том, что хотя параметр ctx.globalAlpha достигает 0 в функции setInterval, полной прозрачности добиться не получается, второй слой полупрозрачный. Но если, ctx.globalAlpha задать не через переменную, а напрямую, то слой получает полную прозрачность. Подскажите, как решить эту проблему?

Строки 18-84 - функция работы со слоями
строки 112-122 - плавное изменение прозрачности

Последний раз редактировалось Янковиц, 29.06.2021 в 15:12.
Ответить с цитированием
  #2 (permalink)  
Старый 29.06.2021, 16:34
Профессор
Отправить личное сообщение для Янковиц Посмотреть профиль Найти все сообщения от Янковиц
 
Регистрация: 17.11.2014
Сообщений: 403

В общем решил так:
добавил ещё один слой и стало работать:
.addLayer( {
				id: 'fullopacity',
				render: function( canvas, ctx ) {
					ctx.globalAlpha = 1;
				}
			} )
Ответить с цитированием
  #3 (permalink)  
Старый 29.06.2021, 17:48
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Янковиц, у тебя 'background' тоже прозрачный, альфа то общая, поэтому все прошлые отрисовки просвечивают, а еще в интервале opacity в минус уходит.

myCanvas.addLayer({
    id: 'background',
    render: function(canvas, ctx) {
        ctx.globalAlpha = 1;
        ctx.fillStyle = 'black';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    }
})

var opacity = 1;
var fadeEffect = setInterval(function () {
    opacity = Math.max(0, opacity - 0.0125);
    if (opacity == 0) clearInterval(fadeEffect);
    console.log(opacity);
    myCanvas.render();
}, 10);
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как изменить расположение iframe и canvas и не перерисовать? Was-Ja Общие вопросы Javascript 2 08.11.2020 23:51
Повтор фото (getUserMedia(),HTML5 Canvas) aspex Элементы интерфейса 1 27.12.2014 16:46
Добавить на canvas еще один елемент greengarlic Общие вопросы Javascript 5 22.09.2010 10:16
Прозрачность слоёв Hagrael Events/DOM/Window 10 08.07.2010 14:28
Скрипт для Фотошопа - прозрачность слоев elmaz Общие вопросы Javascript 13 10.04.2010 14:51