mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
fix: opacity with overflow hidden (#2450)
This commit is contained in:
parent
3982df1492
commit
82b7da558c
@ -22,7 +22,7 @@ import {contentBox} from '../box-sizing';
|
|||||||
import {CanvasElementContainer} from '../../dom/replaced-elements/canvas-element-container';
|
import {CanvasElementContainer} from '../../dom/replaced-elements/canvas-element-container';
|
||||||
import {SVGElementContainer} from '../../dom/replaced-elements/svg-element-container';
|
import {SVGElementContainer} from '../../dom/replaced-elements/svg-element-container';
|
||||||
import {ReplacedElementContainer} from '../../dom/replaced-elements/index';
|
import {ReplacedElementContainer} from '../../dom/replaced-elements/index';
|
||||||
import {EffectTarget, IElementEffect, isClipEffect, isTransformEffect} from '../effects';
|
import {EffectTarget, IElementEffect, isClipEffect, isOpacityEffect, isTransformEffect} from '../effects';
|
||||||
import {contains} from '../../core/bitwise';
|
import {contains} from '../../core/bitwise';
|
||||||
import {calculateGradientDirection, calculateRadius, processColorStops} from '../../css/types/functions/gradient';
|
import {calculateGradientDirection, calculateRadius, processColorStops} from '../../css/types/functions/gradient';
|
||||||
import {FIFTY_PERCENT, getAbsoluteValue} from '../../css/types/length-percentage';
|
import {FIFTY_PERCENT, getAbsoluteValue} from '../../css/types/length-percentage';
|
||||||
@ -99,6 +99,10 @@ export class CanvasRenderer {
|
|||||||
|
|
||||||
applyEffect(effect: IElementEffect) {
|
applyEffect(effect: IElementEffect) {
|
||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
|
if (isOpacityEffect(effect)) {
|
||||||
|
this.ctx.globalAlpha = effect.opacity;
|
||||||
|
}
|
||||||
|
|
||||||
if (isTransformEffect(effect)) {
|
if (isTransformEffect(effect)) {
|
||||||
this.ctx.translate(effect.offsetX, effect.offsetY);
|
this.ctx.translate(effect.offsetX, effect.offsetY);
|
||||||
this.ctx.transform(
|
this.ctx.transform(
|
||||||
@ -128,7 +132,6 @@ export class CanvasRenderer {
|
|||||||
async renderStack(stack: StackingContext) {
|
async renderStack(stack: StackingContext) {
|
||||||
const styles = stack.element.container.styles;
|
const styles = stack.element.container.styles;
|
||||||
if (styles.isVisible()) {
|
if (styles.isVisible()) {
|
||||||
this.ctx.globalAlpha = styles.opacity;
|
|
||||||
await this.renderStackContent(stack);
|
await this.renderStackContent(stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@ import {Path} from './path';
|
|||||||
|
|
||||||
export const enum EffectType {
|
export const enum EffectType {
|
||||||
TRANSFORM = 0,
|
TRANSFORM = 0,
|
||||||
CLIP = 1
|
CLIP = 1,
|
||||||
|
OPACITY = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
export const enum EffectTarget {
|
export const enum EffectTarget {
|
||||||
@ -17,33 +18,41 @@ export interface IElementEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class TransformEffect implements IElementEffect {
|
export class TransformEffect implements IElementEffect {
|
||||||
readonly type: EffectType;
|
readonly type: EffectType = EffectType.TRANSFORM;
|
||||||
readonly target: number;
|
readonly target: number = EffectTarget.BACKGROUND_BORDERS | EffectTarget.CONTENT;
|
||||||
readonly offsetX: number;
|
readonly offsetX: number;
|
||||||
readonly offsetY: number;
|
readonly offsetY: number;
|
||||||
readonly matrix: Matrix;
|
readonly matrix: Matrix;
|
||||||
|
|
||||||
constructor(offsetX: number, offsetY: number, matrix: Matrix) {
|
constructor(offsetX: number, offsetY: number, matrix: Matrix) {
|
||||||
this.type = EffectType.TRANSFORM;
|
|
||||||
this.offsetX = offsetX;
|
this.offsetX = offsetX;
|
||||||
this.offsetY = offsetY;
|
this.offsetY = offsetY;
|
||||||
this.matrix = matrix;
|
this.matrix = matrix;
|
||||||
this.target = EffectTarget.BACKGROUND_BORDERS | EffectTarget.CONTENT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ClipEffect implements IElementEffect {
|
export class ClipEffect implements IElementEffect {
|
||||||
readonly type: EffectType;
|
readonly type: EffectType = EffectType.CLIP;
|
||||||
readonly target: number;
|
readonly target: number;
|
||||||
readonly path: Path[];
|
readonly path: Path[];
|
||||||
|
|
||||||
constructor(path: Path[], target: EffectTarget) {
|
constructor(path: Path[], target: EffectTarget) {
|
||||||
this.type = EffectType.CLIP;
|
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class OpacityEffect implements IElementEffect {
|
||||||
|
readonly type: EffectType = EffectType.OPACITY;
|
||||||
|
readonly target: number = EffectTarget.BACKGROUND_BORDERS | EffectTarget.CONTENT;
|
||||||
|
readonly opacity: number;
|
||||||
|
|
||||||
|
constructor(opacity: number) {
|
||||||
|
this.opacity = opacity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const isTransformEffect = (effect: IElementEffect): effect is TransformEffect =>
|
export const isTransformEffect = (effect: IElementEffect): effect is TransformEffect =>
|
||||||
effect.type === EffectType.TRANSFORM;
|
effect.type === EffectType.TRANSFORM;
|
||||||
export const isClipEffect = (effect: IElementEffect): effect is ClipEffect => effect.type === EffectType.CLIP;
|
export const isClipEffect = (effect: IElementEffect): effect is ClipEffect => effect.type === EffectType.CLIP;
|
||||||
|
export const isOpacityEffect = (effect: IElementEffect): effect is OpacityEffect => effect.type === EffectType.OPACITY;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {ElementContainer, FLAGS} from '../dom/element-container';
|
import {ElementContainer, FLAGS} from '../dom/element-container';
|
||||||
import {contains} from '../core/bitwise';
|
import {contains} from '../core/bitwise';
|
||||||
import {BoundCurves, calculateBorderBoxPath, calculatePaddingBoxPath} from './bound-curves';
|
import {BoundCurves, calculateBorderBoxPath, calculatePaddingBoxPath} from './bound-curves';
|
||||||
import {ClipEffect, EffectTarget, IElementEffect, TransformEffect} from './effects';
|
import {ClipEffect, EffectTarget, IElementEffect, OpacityEffect, TransformEffect} from './effects';
|
||||||
import {OVERFLOW} from '../css/property-descriptors/overflow';
|
import {OVERFLOW} from '../css/property-descriptors/overflow';
|
||||||
import {equalPath} from './path';
|
import {equalPath} from './path';
|
||||||
import {DISPLAY} from '../css/property-descriptors/display';
|
import {DISPLAY} from '../css/property-descriptors/display';
|
||||||
@ -41,6 +41,10 @@ export class ElementPaint {
|
|||||||
this.container = element;
|
this.container = element;
|
||||||
this.effects = parentStack.slice(0);
|
this.effects = parentStack.slice(0);
|
||||||
this.curves = new BoundCurves(element);
|
this.curves = new BoundCurves(element);
|
||||||
|
if (element.styles.opacity < 1) {
|
||||||
|
this.effects.push(new OpacityEffect(element.styles.opacity));
|
||||||
|
}
|
||||||
|
|
||||||
if (element.styles.transform !== null) {
|
if (element.styles.transform !== null) {
|
||||||
const offsetX = element.bounds.left + element.styles.transformOrigin[0].number;
|
const offsetX = element.bounds.left + element.styles.transformOrigin[0].number;
|
||||||
const offsetY = element.bounds.top + element.styles.transformOrigin[1].number;
|
const offsetY = element.bounds.top + element.styles.transformOrigin[1].number;
|
||||||
|
@ -128,5 +128,6 @@
|
|||||||
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="hidden">Hidden<div style="opacity: 0.5">With opacity</div></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user