Implemented layer opacity control

This commit is contained in:
Igor Zinken
2021-02-05 10:17:27 +01:00
parent b09c01d4cf
commit afb4e89052
5 changed files with 51 additions and 9 deletions

View File

@@ -31,6 +31,15 @@
name="enabled"
/>
</div>
<div class="wrapper input">
<label v-t="'opacity'"></label>
<slider
v-model="opacity"
:min="0"
:max="100"
:tooltip="'none'"
/>
</div>
<div class="wrapper input">
<label v-t="'gamma'"></label>
<slider
@@ -124,6 +133,14 @@ export default {
filters() {
return this.activeLayer.filters;
},
opacity: {
get() {
return this.internalValue.opacity * 100;
},
set( value ) {
this.internalValue.opacity = value / 100;
}
},
gamma: {
get() {
return this.internalValue.gamma * 100;
@@ -173,9 +190,13 @@ export default {
}, 250 );
},
},
activeLayer( value ) {
activeLayer( value, oldValue ) {
if ( !value ) {
this.close(); // document has been closed
} else if ( oldValue && value.id !== oldValue.id ) {
this.cancel( this.orgLayerId ); // layer has switched
} else {
this.optLayerIndex = this.activeLayerIndex;
}
}
},
@@ -211,17 +232,17 @@ export default {
this.internalValue = FiltersFactory.create();
this.update();
},
cancel() {
this.update( this.orgFilters );
cancel( optLayerIndex ) {
this.update( this.orgFilters, optLayerIndex );
this.close();
},
close() {
this.$emit( "close" );
},
update( optData ) {
update( optData, optLayerIndex ) {
const filters = optData || { ...this.internalValue };
this.updateLayer({
index: this.activeLayerIndex,
index: optLayerIndex ?? this.activeLayerIndex,
opts: { filters }
});
}

View File

@@ -2,6 +2,7 @@
"en-US": {
"filtersForLayer": "Filters for layer \"{name}\"",
"enabled": "Filters active",
"opacity": "Opacity",
"gamma": "Gamma",
"contrast": "Contrast",
"brightness": "Brightness",

View File

@@ -25,6 +25,7 @@ let defaultFilters = null;
const FiltersFactory = {
create({
enabled = true,
opacity = 1,
gamma = .5,
brightness = .5,
contrast = 0,
@@ -33,6 +34,7 @@ const FiltersFactory = {
} = {}) {
return {
enabled,
opacity,
gamma,
brightness,
contrast,
@@ -48,6 +50,7 @@ const FiltersFactory = {
serialize( filters ) {
return {
e: filters.enabled,
o: filters.opacity,
g: filters.gamma,
b: filters.brightness,
c: filters.contrast,
@@ -63,6 +66,7 @@ const FiltersFactory = {
deserialize( filters = {} ) {
return FiltersFactory.create({
enabled: filters.e,
opacity: filters.o,
gamma: filters.g,
brightness: filters.b,
contrast: filters.c,
@@ -85,6 +89,7 @@ export const hasFilters = filters => {
export const isEqual = ( filters, filtersToCompareTo = {} ) => {
return filters.enabled === filtersToCompareTo.enabled &&
filters.opacity === filtersToCompareTo.opacity &&
filters.gamma === filtersToCompareTo.gamma &&
filters.brightness === filtersToCompareTo.brightness &&
filters.contrast === filtersToCompareTo.contrast &&

View File

@@ -519,6 +519,11 @@ class LayerSprite extends ZoomableSprite {
orgBounds = this._bounds;
this._bounds = scaleRectangle( orgBounds, scale );
}
const { enabled, opacity } = this.layer.filters;
const altOpacity = enabled && opacity !== 1;
if ( altOpacity ) {
documentContext.globalAlpha = opacity;
}
// invoke base class behaviour to render bitmap
super.draw( documentContext, viewport );
@@ -535,7 +540,10 @@ class LayerSprite extends ZoomableSprite {
renderTempCanvas( this.canvas, documentContext );
documentContext.restore();
}
if ( altOpacity ) {
documentContext.globalAlpha = 1; // restore document opacity
}
if ( !omitOutlines ) {
const { zoomFactor } = this.canvas;

View File

@@ -6,6 +6,7 @@ describe( "Filters factory", () => {
const filters = FiltersFactory.create();
expect( filters ).toEqual({
enabled: true,
opacity: 1,
gamma: .5,
brightness: .5,
contrast: 0,
@@ -17,6 +18,7 @@ describe( "Filters factory", () => {
it( "should be able to create a filters list from given arguments", () => {
const filters = FiltersFactory.create({
enabled: false,
opacity: .3,
gamma: .7,
brightness: .6,
contrast: .3,
@@ -25,6 +27,7 @@ describe( "Filters factory", () => {
});
expect( filters ).toEqual({
enabled: false,
opacity: .3,
gamma: .7,
brightness: .6,
contrast: .3,
@@ -38,6 +41,7 @@ describe( "Filters factory", () => {
it( "should do so without data loss", async () => {
const filters = FiltersFactory.create({
enabled: false,
opacity: .4,
gamma: .7,
brightness: .6,
contrast: .3,
@@ -58,7 +62,10 @@ describe( "Filters factory", () => {
});
it( "should consider a configuration where one of the properties deviates from the default as active", () => {
let filter = FiltersFactory.create({ gamma: .7 });
let filter = FiltersFactory.create({ opacity: .5 });
expect( hasFilters( filter )).toBe( true );
filter = FiltersFactory.create({ gamma: .7 });
expect( hasFilters( filter )).toBe( true );
filter = FiltersFactory.create({ brightness: .3 });
@@ -77,8 +84,8 @@ describe( "Filters factory", () => {
it( "should know when two filters instances are equal", () => {
const defaultFilter = FiltersFactory.create();
[ "enabled", "gamma", "brightness", "contrast", "vibrance", "desaturate" ].forEach( property => {
const filters = FiltersFactory.create({ [ property ]: 1 });
[ "enabled", "opacity", "gamma", "brightness", "contrast", "vibrance", "desaturate" ].forEach( property => {
const filters = FiltersFactory.create({ [ property ]: .88 });
expect( isEqual( filters, defaultFilter )).toBe( false );
});
expect( isEqual( defaultFilter, FiltersFactory.create() )).toBe( true );