chore: box shadow updates (#9220)

This commit is contained in:
William Tjondrosuharto
2021-02-20 13:39:06 +07:00
committed by Nathan Walker
parent 726ef9fd8f
commit 207edb94f4
6 changed files with 51 additions and 15 deletions

View File

@@ -105,11 +105,6 @@ export class BoxShadowModel extends Observable {
} }
this.appliedBoxShadow = this._boxShadow; this.appliedBoxShadow = this._boxShadow;
this.notifyPropertyChange('appliedBoxShadow', this.appliedBoxShadow); this.notifyPropertyChange('appliedBoxShadow', this.appliedBoxShadow);
// TODO: this is a workaround to apply shadow immediately,
// since the box-shadow logic is currently inside background.ts
this.notifyPropertyChange('background', '');
this.notifyPropertyChange('background', this.background);
} }
textChange(args): void { textChange(args): void {

View File

@@ -4,6 +4,7 @@ import { BackgroundRepeat } from '../styling/style-properties';
import { LinearGradient } from './linear-gradient'; import { LinearGradient } from './linear-gradient';
// Types. // Types.
import { Color } from '../../color'; import { Color } from '../../color';
import { BoxShadow } from './box-shadow';
export class Background implements BackgroundDefinition { export class Background implements BackgroundDefinition {
public static default = new Background(); public static default = new Background();
@@ -26,6 +27,7 @@ export class Background implements BackgroundDefinition {
public borderBottomLeftRadius = 0; public borderBottomLeftRadius = 0;
public borderBottomRightRadius = 0; public borderBottomRightRadius = 0;
public clipPath: string; public clipPath: string;
public boxShadow: BoxShadow;
private clone(): Background { private clone(): Background {
const clone = new Background(); const clone = new Background();
@@ -48,6 +50,7 @@ export class Background implements BackgroundDefinition {
clone.borderBottomRightRadius = this.borderBottomRightRadius; clone.borderBottomRightRadius = this.borderBottomRightRadius;
clone.borderBottomLeftRadius = this.borderBottomLeftRadius; clone.borderBottomLeftRadius = this.borderBottomLeftRadius;
clone.clipPath = this.clipPath; clone.clipPath = this.clipPath;
clone.boxShadow = this.boxShadow;
return clone; return clone;
} }
@@ -178,6 +181,13 @@ export class Background implements BackgroundDefinition {
return clone; return clone;
} }
public withBoxShadow(value: BoxShadow): Background {
const clone = this.clone();
clone.boxShadow = value;
return clone;
}
public isEmpty(): boolean { public isEmpty(): boolean {
return !this.color && !this.image && !this.hasBorderWidth() && !this.hasBorderRadius() && !this.clipPath; return !this.color && !this.image && !this.hasBorderWidth() && !this.hasBorderRadius() && !this.clipPath;
} }
@@ -274,6 +284,14 @@ export class Background implements BackgroundDefinition {
return 0; return 0;
} }
public hasBoxShadow(): boolean {
return !!this.boxShadow;
}
public getBoxShadow(): BoxShadow {
return this.boxShadow;
}
public toString(): string { public toString(): string {
return `isEmpty: ${this.isEmpty()}; color: ${this.color}; image: ${this.image}; repeat: ${this.repeat}; position: ${this.position}; size: ${this.size}; borderTopColor: ${this.borderTopColor}; borderRightColor: ${this.borderRightColor}; borderBottomColor: ${this.borderBottomColor}; borderLeftColor: ${this.borderLeftColor}; borderTopWidth: ${this.borderTopWidth}; borderRightWidth: ${this.borderRightWidth}; borderBottomWidth: ${this.borderBottomWidth}; borderLeftWidth: ${this.borderLeftWidth}; borderTopLeftRadius: ${this.borderTopLeftRadius}; borderTopRightRadius: ${ return `isEmpty: ${this.isEmpty()}; color: ${this.color}; image: ${this.image}; repeat: ${this.repeat}; position: ${this.position}; size: ${this.size}; borderTopColor: ${this.borderTopColor}; borderRightColor: ${this.borderRightColor}; borderBottomColor: ${this.borderBottomColor}; borderLeftColor: ${this.borderLeftColor}; borderTopWidth: ${this.borderTopWidth}; borderRightWidth: ${this.borderRightWidth}; borderBottomWidth: ${this.borderBottomWidth}; borderLeftWidth: ${this.borderLeftWidth}; borderTopLeftRadius: ${this.borderTopLeftRadius}; borderTopRightRadius: ${
this.borderTopRightRadius this.borderTopRightRadius

View File

@@ -93,9 +93,10 @@ export namespace ad {
nativeView.setBackground(defaultDrawable); nativeView.setBackground(defaultDrawable);
} }
const boxShadow = view.style.boxShadow; if (background.hasBoxShadow()) {
if (boxShadow) { drawBoxShadow(nativeView, view, background.getBoxShadow());
drawBoxShadow(nativeView, view, boxShadow); } else {
clearBoxShadow(nativeView);
} }
// TODO: Can we move BorderWidths as separate native setter? // TODO: Can we move BorderWidths as separate native setter?
@@ -243,6 +244,10 @@ function drawBoxShadow(nativeView: android.view.View, view: View, boxShadow: Box
org.nativescript.widgets.Utils.drawBoxShadow(nativeView, JSON.stringify(config)); org.nativescript.widgets.Utils.drawBoxShadow(nativeView, JSON.stringify(config));
} }
function clearBoxShadow(nativeView: android.view.View) {
// org.nativescript.widgets.Utils.clearBoxShadow(nativeView);
}
export enum CacheMode { export enum CacheMode {
none, none,
memory, memory,

View File

@@ -50,6 +50,7 @@ export declare class Background {
public withBorderBottomRightRadius(value: number): Background; public withBorderBottomRightRadius(value: number): Background;
public withBorderBottomLeftRadius(value: number): Background; public withBorderBottomLeftRadius(value: number): Background;
public withClipPath(value: string): Background; public withClipPath(value: string): Background;
public withBoxShadow(value: BoxShadow): Background;
public isEmpty(): boolean; public isEmpty(): boolean;
@@ -65,6 +66,8 @@ export declare class Background {
public getUniformBorderColor(): Color; public getUniformBorderColor(): Color;
public getUniformBorderWidth(): number; public getUniformBorderWidth(): number;
public getUniformBorderRadius(): number; public getUniformBorderRadius(): number;
public hasBoxShadow(): boolean;
public getBoxShadow(): BoxShadow;
} }
export namespace ios { export namespace ios {

View File

@@ -88,12 +88,11 @@ export namespace ios {
setUIColorFromImage(view, nativeView, callback, flip); setUIColorFromImage(view, nativeView, callback, flip);
} }
const boxShadow = view.style.boxShadow; if (background.hasBoxShadow()) {
if (boxShadow) { drawBoxShadow(nativeView, view, background.getBoxShadow(), background);
// this is required (if not, shadow will get cutoff at parent's dimensions) } else {
// nativeView.clipsToBounds doesn't work view.setProperty('clipToBounds', true);
view.setProperty('clipToBounds', false); clearBoxShadow(nativeView);
drawBoxShadow(nativeView, view, boxShadow, background);
} }
} }
} }
@@ -722,6 +721,10 @@ function drawBoxShadow(nativeView: NativeView, view: View, boxShadow: CSSShadow,
layer.masksToBounds = false; layer.masksToBounds = false;
nativeView.clipsToBounds = false; nativeView.clipsToBounds = false;
// this is required (if not, shadow will get cutoff at parent's dimensions)
// nativeView.clipsToBounds doesn't work
view.setProperty('clipToBounds', false);
if (!background.color?.a) { if (!background.color?.a) {
// add white background if view has a transparent background // add white background if view has a transparent background
@@ -745,6 +748,17 @@ function drawBoxShadow(nativeView: NativeView, view: View, boxShadow: CSSShadow,
layer.shadowPath = UIBezierPath.bezierPathWithRoundedRectCornerRadius(nativeView.bounds, cornerRadius).CGPath; layer.shadowPath = UIBezierPath.bezierPathWithRoundedRectCornerRadius(nativeView.bounds, cornerRadius).CGPath;
} }
function clearBoxShadow(nativeView: NativeView) {
nativeView.clipsToBounds = true;
const layer: CALayer = nativeView.layer;
layer.masksToBounds = true;
layer.shadowOffset = CGSizeMake(0, 0);
layer.shadowColor = UIColor.clearColor.CGColor;
layer.cornerRadius = 0.0;
layer.shadowRadius = 0.0;
layer.shadowOpacity = 0.0;
}
function drawGradient(nativeView: NativeView, gradient: LinearGradient) { function drawGradient(nativeView: NativeView, gradient: LinearGradient) {
const gradientLayer = CAGradientLayer.layer(); const gradientLayer = CAGradientLayer.layer();
gradientLayer.frame = nativeView.bounds; gradientLayer.frame = nativeView.bounds;

View File

@@ -1280,7 +1280,8 @@ const boxShadowProperty = new CssProperty<Style, CSSShadow>({
name: 'boxShadow', name: 'boxShadow',
cssName: 'box-shadow', cssName: 'box-shadow',
valueChanged: (target, oldValue, newValue) => { valueChanged: (target, oldValue, newValue) => {
target.boxShadow = newValue; const background = target.backgroundInternal.withBoxShadow(newValue);
target.backgroundInternal = background;
}, },
valueConverter: (value) => { valueConverter: (value) => {
return parseCSSShadow(value); return parseCSSShadow(value);