Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a671be1

Browse filesBrowse files
committed
Merge branch 'image' into woothu
2 parents 7ffcf0d + 41da477 commit a671be1
Copy full SHA for a671be1

File tree

Expand file treeCollapse file tree

4 files changed

+264
-0
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+264
-0
lines changed

‎src/components/Image/CImage.js

Copy file name to clipboard
+105Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { mergeData } from 'vue-functional-data-merge'
2+
3+
// Blank image with fill template
4+
const BLANK_TEMPLATE = '<svg width="%{w}" height="%{h}" ' +
5+
'xmlns="http://www.w3.org/2000/svg" ' +
6+
'viewBox="0 0 %{w} %{h}" preserveAspectRatio="none">' +
7+
'<rect width="100%" height="100%" style="fill:%{f};"></rect>' +
8+
'</svg>'
9+
10+
function makeBlankImgSrc (width, height, color) {
11+
const src = encodeURIComponent(
12+
BLANK_TEMPLATE
13+
.replace('%{w}', String(width))
14+
.replace('%{h}', String(height))
15+
.replace('%{f}', color)
16+
)
17+
return `data:image/svg+xml;charset=UTF-8,${src}`
18+
}
19+
20+
export const props = {
21+
src: String,
22+
alt: String,
23+
width: [Number, String],
24+
height: [Number, String],
25+
block: Boolean,
26+
fluid: Boolean,
27+
// Gives fluid images class `w-100` to make them grow to fit container
28+
fluidGrow: Boolean,
29+
rounded: {
30+
// rounded can be:
31+
// false: no rounding of corners
32+
// true: slightly rounded corners
33+
// 'top': top corners rounded
34+
// 'right': right corners rounded
35+
// 'bottom': bottom corners rounded
36+
// 'left': left corners rounded
37+
// 'circle': circle/oval
38+
// '0': force rounding off
39+
type: [Boolean, String],
40+
default: false
41+
},
42+
thumbnail: Boolean,
43+
left: Boolean,
44+
right: Boolean,
45+
center: Boolean,
46+
blank: Boolean,
47+
blankColor: {
48+
type: String,
49+
default: 'transparent'
50+
}
51+
}
52+
53+
export default {
54+
functional: true,
55+
name: 'CImage',
56+
props,
57+
render (h, { props, data }) {
58+
let src = props.src
59+
let width = parseInt(props.width, 10) ? parseInt(props.width, 10) : null
60+
let height = parseInt(props.height, 10) ? parseInt(props.height, 10) : null
61+
let align = null
62+
let block = props.block
63+
if (props.blank) {
64+
if (!height && Boolean(width)) {
65+
height = width
66+
} else if (!width && Boolean(height)) {
67+
width = height
68+
}
69+
if (!width && !height) {
70+
width = 1
71+
height = 1
72+
}
73+
// Make a blank SVG image
74+
src = makeBlankImgSrc(width, height, props.blankColor || 'transparent')
75+
}
76+
if (props.left) {
77+
align = 'float-left'
78+
} else if (props.right) {
79+
align = 'float-right'
80+
} else if (props.center) {
81+
align = 'mx-auto'
82+
block = true
83+
}
84+
return h(
85+
'img',
86+
mergeData(data, {
87+
attrs: {
88+
'src': src,
89+
'alt': props.alt,
90+
'width': width ? String(width) : null,
91+
'height': height ? String(height) : null
92+
},
93+
class: {
94+
'img-thumbnail': props.thumbnail,
95+
'img-fluid': props.fluid || props.fluidGrow,
96+
'w-100': props.fluidGrow,
97+
'rounded': props.rounded === '' || props.rounded === true,
98+
[`rounded-${props.rounded}`]: typeof props.rounded === 'string' && props.rounded !== '',
99+
[align]: Boolean(align),
100+
'd-block': block
101+
}
102+
})
103+
)
104+
}
105+
}

‎src/components/Image/CImageLazy.js

Copy file name to clipboard
+147Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import CImage from './CImage'
2+
import { isVisible, getBCR, eventOn, eventOff } from '../../utils/dom'
3+
const THROTTLE = 100
4+
5+
// @vue/component
6+
export default {
7+
components: { CImage },
8+
name: 'CImageLazy',
9+
props: {
10+
src: {
11+
type: String,
12+
required: true
13+
},
14+
alt: String,
15+
width: [Number, String],
16+
height: [Number, String],
17+
// If null, a blank image is generated
18+
blankSrc: String,
19+
blankColor: {
20+
type: String,
21+
default: 'transparent'
22+
},
23+
blankWidth: [Number, String],
24+
blankHeight: [Number, String],
25+
fluid: Boolean,
26+
fluidGrow: Boolean,
27+
block: Boolean,
28+
thumbnail: Boolean,
29+
rounded: {
30+
type: [Boolean, String],
31+
default: false
32+
},
33+
left: Boolean,
34+
right: Boolean,
35+
center: Boolean,
36+
offset: {
37+
type: [Number, String],
38+
default: 360
39+
},
40+
throttle: {
41+
type: [Number, String],
42+
default: THROTTLE
43+
}
44+
},
45+
data () {
46+
return {
47+
isShown: false,
48+
scrollTimeout: null
49+
}
50+
},
51+
computed: {
52+
computedSrc () {
53+
return (!this.blankSrc || this.isShown) ? this.src : this.blankSrc
54+
},
55+
computedBlank () {
56+
return !((this.isShown || this.blankSrc))
57+
},
58+
computedWidth () {
59+
return this.isShown ? this.width : (this.blankWidth || this.width)
60+
},
61+
computedHeight () {
62+
return this.isShown ? this.height : (this.blankHeight || this.height)
63+
}
64+
},
65+
mounted () {
66+
this.setListeners(true)
67+
this.checkView()
68+
},
69+
activated () {
70+
this.setListeners(true)
71+
this.checkView()
72+
},
73+
deactivated () {
74+
this.setListeners(false)
75+
},
76+
methods: {
77+
setListeners (on) {
78+
clearTimeout(this.scrollTimer)
79+
this.scrollTimeout = null
80+
const root = window
81+
if (on) {
82+
eventOn(root, 'scroll', this.onScroll)
83+
eventOn(root, 'resize', this.onScroll)
84+
eventOn(root, 'orientationchange', this.onScroll)
85+
} else {
86+
eventOff(root, 'scroll', this.onScroll)
87+
eventOff(root, 'resize', this.onScroll)
88+
eventOff(root, 'orientationchange', this.onScroll)
89+
}
90+
},
91+
checkView () {
92+
// check bounding box + offset to see if we should show
93+
if (!isVisible(this.$el)) {
94+
// Element is hidden, so skip for now
95+
return
96+
}
97+
const offset = parseInt(this.offset, 10) || 0
98+
const docElement = document.documentElement
99+
const view = {
100+
l: 0 - offset,
101+
t: 0 - offset,
102+
b: docElement.clientHeight + offset,
103+
r: docElement.clientWidth + offset
104+
}
105+
const box = getBCR(this.$el)
106+
if (box.right >= view.l && box.bottom >= view.t && box.left <= view.r && box.top <= view.b) {
107+
// image is in view (or about to be in view)
108+
this.isShown = true
109+
this.setListeners(false)
110+
}
111+
},
112+
onScroll () {
113+
if (this.isShown) {
114+
this.setListeners(false)
115+
} else {
116+
clearTimeout(this.scrollTimeout)
117+
this.scrollTimeout = setTimeout(this.checkView, parseInt(this.throttle, 10) || THROTTLE)
118+
}
119+
}
120+
},
121+
render (h) {
122+
return h(
123+
'CImage',
124+
{
125+
props: {
126+
src: this.computedSrc,
127+
alt: this.alt,
128+
blank: this.computedBlank,
129+
blankColor: this.blankColor,
130+
width: this.computedWidth,
131+
height: this.computedHeight,
132+
fluid: this.fluid,
133+
fluidGrow: this.fluidGrow,
134+
block: this.block,
135+
thumbnail: this.thumbnail,
136+
rounded: this.rounded,
137+
left: this.left,
138+
right: this.right,
139+
center: this.center
140+
}
141+
}
142+
)
143+
},
144+
beforeDdestroy () {
145+
this.setListeners(false)
146+
}
147+
}

‎src/components/Image/index.js

Copy file name to clipboard
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import CImage from './CImage'
2+
import CImageLazy from './CImageLazy'
3+
4+
5+
export {
6+
CImage,
7+
CImageLazy
8+
}

‎src/components/index.js

Copy file name to clipboardExpand all lines: src/components/index.js
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export * from './Alert'
1515
export * from './Button'
1616
export * from './Card'
1717
export * from './Dropdown'
18+
<<<<<<< HEAD
1819
export * from './ListGroup'
1920
<<<<<<< HEAD
2021
<<<<<<< HEAD
@@ -33,3 +34,6 @@ export * from './Media'
3334
=======
3435
export * from './Jumbotron'
3536
>>>>>>> jumbotron
37+
=======
38+
export * from './Image'
39+
>>>>>>> image

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.