This repository has been archived by the owner on Apr 20, 2023. It is now read-only.
/
BorderImageRenderer.js
125 lines (111 loc) · 5.57 KB
/
BorderImageRenderer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/**
* Renderer for border-image
* @constructor
* @param {Element} el The target element
* @param {Object} styleInfos The StyleInfo objects
* @param {PIE.RootRenderer} parent
*/
PIE.BorderImageRenderer = PIE.RendererBase.newRenderer( {
shapeZIndex: 5,
needsUpdate: function() {
return this.styleInfos.borderImageInfo.changed();
},
isActive: function() {
return this.styleInfos.borderImageInfo.isActive();
},
draw: function() {
var me = this,
props = me.styleInfos.borderImageInfo.getProps(),
borderProps = me.styleInfos.borderInfo.getProps(),
bounds = me.boundsInfo.getBounds(),
el = me.targetElement;
PIE.Util.withImageSize( props.src, function( imgSize ) {
var me = this,
elW = bounds.w,
elH = bounds.h,
zero = PIE.getLength( '0' ),
widths = props.widths || ( borderProps ? borderProps.widths : { 't': zero, 'r': zero, 'b': zero, 'l': zero } ),
widthT = widths['t'].pixels( el ),
widthR = widths['r'].pixels( el ),
widthB = widths['b'].pixels( el ),
widthL = widths['l'].pixels( el ),
slices = props.slice,
sliceT = slices['t'].pixels( el ),
sliceR = slices['r'].pixels( el ),
sliceB = slices['b'].pixels( el ),
sliceL = slices['l'].pixels( el ),
src = props.src,
imgW = imgSize.w,
imgH = imgSize.h;
function setSizeAndPos( rect, rectX, rectY, rectW, rectH, sliceX, sliceY, sliceW, sliceH ) {
// Hide the piece entirely if we have zero dimensions for the image, the rect, or the slice
var max = Math.max;
if ( !imgW || !imgH || !rectW || !rectH || !sliceW || !sliceH ) {
rect.setStyles( 'display', 'none' );
} else {
rectW = max( rectW, 0 );
rectH = max( rectH, 0 );
rect.setAttrs(
'path', 'm0,0l' + rectW * 2 + ',0l' + rectW * 2 + ',' + rectH * 2 + 'l0,' + rectH * 2 + 'x'
);
rect.setFillAttrs(
'src', src,
'type', 'tile',
'position', '0,0',
'origin', ( ( sliceX - 0.5 ) / imgW ) + ',' + ( ( sliceY - 0.5 ) / imgH ),
// For some reason using px units doesn't work in VML markup so we must convert to pt.
'size', PIE.Length.pxToPt( rectW * imgW / sliceW ) + 'pt,' + PIE.Length.pxToPt( rectH * imgH / sliceH ) + 'pt'
);
rect.setSize( rectW, rectH );
rect.setStyles(
'left', rectX + 'px',
'top', rectY + 'px',
'display', ''
);
}
}
// Piece positions and sizes
// TODO right now this treats everything like 'stretch', need to support other schemes
setSizeAndPos( me.getRect( 'tl' ), 0, 0, widthL, widthT, 0, 0, sliceL, sliceT );
setSizeAndPos( me.getRect( 't' ), widthL, 0, elW - widthL - widthR, widthT, sliceL, 0, imgW - sliceL - sliceR, sliceT );
setSizeAndPos( me.getRect( 'tr' ), elW - widthR, 0, widthR, widthT, imgW - sliceR, 0, sliceR, sliceT );
setSizeAndPos( me.getRect( 'r' ), elW - widthR, widthT, widthR, elH - widthT - widthB, imgW - sliceR, sliceT, sliceR, imgH - sliceT - sliceB );
setSizeAndPos( me.getRect( 'br' ), elW - widthR, elH - widthB, widthR, widthB, imgW - sliceR, imgH - sliceB, sliceR, sliceB );
setSizeAndPos( me.getRect( 'b' ), widthL, elH - widthB, elW - widthL - widthR, widthB, sliceL, imgH - sliceB, imgW - sliceL - sliceR, sliceB );
setSizeAndPos( me.getRect( 'bl' ), 0, elH - widthB, widthL, widthB, 0, imgH - sliceB, sliceL, sliceB );
setSizeAndPos( me.getRect( 'l' ), 0, widthT, widthL, elH - widthT - widthB, 0, sliceT, sliceL, imgH - sliceT - sliceB );
setSizeAndPos( me.getRect( 'c' ), widthL, widthT, elW - widthL - widthR, elH - widthT - widthB, sliceL, sliceT, props.fill ? imgW - sliceL - sliceR : 0, imgH - sliceT - sliceB );
}, me );
},
getRect: function( name ) {
return this.getShape( 'borderImage_' + name, this.shapeZIndex );
},
prepareUpdate: function() {
if (this.isActive()) {
var me = this,
el = me.targetElement,
rs = el.runtimeStyle,
widths = me.styleInfos.borderImageInfo.getProps().widths;
// Force border-style to solid so it doesn't collapse
rs.borderStyle = 'solid';
// If widths specified in border-image shorthand, override border-width
if ( widths ) {
rs.borderTopWidth = widths['t'].pixels( el );
rs.borderRightWidth = widths['r'].pixels( el );
rs.borderBottomWidth = widths['b'].pixels( el );
rs.borderLeftWidth = widths['l'].pixels( el );
}
// Make the border transparent
me.hideBorder();
}
},
destroy: function() {
var me = this,
rs = me.targetElement.runtimeStyle;
rs.borderStyle = '';
if (me.finalized || !me.styleInfos.borderInfo.isActive()) {
rs.borderColor = rs.borderWidth = '';
}
PIE.RendererBase.destroy.call( me );
}
} );