wip
This commit is contained in:
		| @@ -1,172 +0,0 @@ | ||||
| <mk-images> | ||||
| 	<template each={ image in images }> | ||||
| 		<mk-images-image image={ image }/> | ||||
| 	</template> | ||||
| 	<style lang="stylus" scoped> | ||||
| 		:scope | ||||
| 			display grid | ||||
| 			grid-gap 4px | ||||
| 			height 256px | ||||
| 	</style> | ||||
| 	<script lang="typescript"> | ||||
| 		this.images = this.opts.images; | ||||
|  | ||||
| 		this.on('mount', () => { | ||||
| 			if (this.images.length == 1) { | ||||
| 				this.root.style.gridTemplateRows = '1fr'; | ||||
|  | ||||
| 				this.tags['mk-images-image'].root.style.gridColumn = '1 / 2'; | ||||
| 				this.tags['mk-images-image'].root.style.gridRow = '1 / 2'; | ||||
| 			} else if (this.images.length == 2) { | ||||
| 				this.root.style.gridTemplateColumns = '1fr 1fr'; | ||||
| 				this.root.style.gridTemplateRows = '1fr'; | ||||
|  | ||||
| 				this.tags['mk-images-image'][0].root.style.gridColumn = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][0].root.style.gridRow = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][1].root.style.gridColumn = '2 / 3'; | ||||
| 				this.tags['mk-images-image'][1].root.style.gridRow = '1 / 2'; | ||||
| 			} else if (this.images.length == 3) { | ||||
| 				this.root.style.gridTemplateColumns = '1fr 0.5fr'; | ||||
| 				this.root.style.gridTemplateRows = '1fr 1fr'; | ||||
|  | ||||
| 				this.tags['mk-images-image'][0].root.style.gridColumn = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][0].root.style.gridRow = '1 / 3'; | ||||
| 				this.tags['mk-images-image'][1].root.style.gridColumn = '2 / 3'; | ||||
| 				this.tags['mk-images-image'][1].root.style.gridRow = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][2].root.style.gridColumn = '2 / 3'; | ||||
| 				this.tags['mk-images-image'][2].root.style.gridRow = '2 / 3'; | ||||
| 			} else if (this.images.length == 4) { | ||||
| 				this.root.style.gridTemplateColumns = '1fr 1fr'; | ||||
| 				this.root.style.gridTemplateRows = '1fr 1fr'; | ||||
|  | ||||
| 				this.tags['mk-images-image'][0].root.style.gridColumn = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][0].root.style.gridRow = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][1].root.style.gridColumn = '2 / 3'; | ||||
| 				this.tags['mk-images-image'][1].root.style.gridRow = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][2].root.style.gridColumn = '1 / 2'; | ||||
| 				this.tags['mk-images-image'][2].root.style.gridRow = '2 / 3'; | ||||
| 				this.tags['mk-images-image'][3].root.style.gridColumn = '2 / 3'; | ||||
| 				this.tags['mk-images-image'][3].root.style.gridRow = '2 / 3'; | ||||
| 			} | ||||
| 		}); | ||||
| 	</script> | ||||
| </mk-images> | ||||
|  | ||||
| <mk-images-image> | ||||
| 	<a ref="view" | ||||
| 		href={ image.url } | ||||
| 		onmousemove={ mousemove } | ||||
| 		onmouseleave={ mouseleave } | ||||
| 		style={ styles } | ||||
| 		@click="click" | ||||
| 		title={ image.name }></a> | ||||
| 	<style lang="stylus" scoped> | ||||
| 		:scope | ||||
| 			display block | ||||
| 			overflow hidden | ||||
| 			border-radius 4px | ||||
|  | ||||
| 			> a | ||||
| 				display block | ||||
| 				cursor zoom-in | ||||
| 				overflow hidden | ||||
| 				width 100% | ||||
| 				height 100% | ||||
| 				background-position center | ||||
|  | ||||
| 				&:not(:hover) | ||||
| 					background-size cover | ||||
|  | ||||
| 	</style> | ||||
| 	<script lang="typescript"> | ||||
| 		this.image = this.opts.image; | ||||
| 		this.styles = { | ||||
| 			'background-color': this.image.properties.average_color ? `rgb(${this.image.properties.average_color.join(',')})` : 'transparent', | ||||
| 			'background-image': `url(${this.image.url}?thumbnail&size=512)` | ||||
| 		}; | ||||
|  | ||||
| 		this.mousemove = e => { | ||||
| 			const rect = this.$refs.view.getBoundingClientRect(); | ||||
| 			const mouseX = e.clientX - rect.left; | ||||
| 			const mouseY = e.clientY - rect.top; | ||||
| 			const xp = mouseX / this.$refs.view.offsetWidth * 100; | ||||
| 			const yp = mouseY / this.$refs.view.offsetHeight * 100; | ||||
| 			this.$refs.view.style.backgroundPosition = xp + '% ' + yp + '%'; | ||||
| 			this.$refs.view.style.backgroundImage = 'url("' + this.image.url + '?thumbnail")'; | ||||
| 		}; | ||||
|  | ||||
| 		this.mouseleave = () => { | ||||
| 			this.$refs.view.style.backgroundPosition = ''; | ||||
| 		}; | ||||
|  | ||||
| 		this.click = ev => { | ||||
| 			ev.preventDefault(); | ||||
| 			riot.mount(document.body.appendChild(document.createElement('mk-image-dialog')), { | ||||
| 				image: this.image | ||||
| 			}); | ||||
| 			return false; | ||||
| 		}; | ||||
| 	</script> | ||||
| </mk-images-image> | ||||
|  | ||||
| <mk-image-dialog> | ||||
| 	<div class="bg" ref="bg" @click="close"></div><img ref="img" src={ image.url } alt={ image.name } title={ image.name } @click="close"/> | ||||
| 	<style lang="stylus" scoped> | ||||
| 		:scope | ||||
| 			display block | ||||
| 			position fixed | ||||
| 			z-index 2048 | ||||
| 			top 0 | ||||
| 			left 0 | ||||
| 			width 100% | ||||
| 			height 100% | ||||
| 			opacity 0 | ||||
|  | ||||
| 			> .bg | ||||
| 				display block | ||||
| 				position fixed | ||||
| 				z-index 1 | ||||
| 				top 0 | ||||
| 				left 0 | ||||
| 				width 100% | ||||
| 				height 100% | ||||
| 				background rgba(0, 0, 0, 0.7) | ||||
|  | ||||
| 			> img | ||||
| 				position fixed | ||||
| 				z-index 2 | ||||
| 				top 0 | ||||
| 				right 0 | ||||
| 				bottom 0 | ||||
| 				left 0 | ||||
| 				max-width 100% | ||||
| 				max-height 100% | ||||
| 				margin auto | ||||
| 				cursor zoom-out | ||||
|  | ||||
| 	</style> | ||||
| 	<script lang="typescript"> | ||||
| 		import anime from 'animejs'; | ||||
|  | ||||
| 		this.image = this.opts.image; | ||||
|  | ||||
| 		this.on('mount', () => { | ||||
| 			anime({ | ||||
| 				targets: this.root, | ||||
| 				opacity: 1, | ||||
| 				duration: 100, | ||||
| 				easing: 'linear' | ||||
| 			}); | ||||
| 		}); | ||||
|  | ||||
| 		this.close = () => { | ||||
| 			anime({ | ||||
| 				targets: this.root, | ||||
| 				opacity: 0, | ||||
| 				duration: 100, | ||||
| 				easing: 'linear', | ||||
| 				complete: () => this.$destroy() | ||||
| 			}); | ||||
| 		}; | ||||
| 	</script> | ||||
| </mk-image-dialog> | ||||
							
								
								
									
										69
									
								
								src/web/app/desktop/views/components/images-image-dialog.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/web/app/desktop/views/components/images-image-dialog.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| <template> | ||||
| <div class="mk-images-image-dialog"> | ||||
| 	<div class="bg" @click="close"></div> | ||||
| 	<img :src="image.url" :alt="image.name" :title="image.name" @click="close"/> | ||||
| </div> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import anime from 'animejs'; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	props: ['image'], | ||||
| 	mounted() { | ||||
| 		anime({ | ||||
| 			targets: this.$el, | ||||
| 			opacity: 1, | ||||
| 			duration: 100, | ||||
| 			easing: 'linear' | ||||
| 		}); | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		close() { | ||||
| 			anime({ | ||||
| 				targets: this.$el, | ||||
| 				opacity: 0, | ||||
| 				duration: 100, | ||||
| 				easing: 'linear', | ||||
| 				complete: () => this.$destroy() | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style lang="stylus" scoped> | ||||
| .mk-images-image-dialog | ||||
| 	display block | ||||
| 	position fixed | ||||
| 	z-index 2048 | ||||
| 	top 0 | ||||
| 	left 0 | ||||
| 	width 100% | ||||
| 	height 100% | ||||
| 	opacity 0 | ||||
|  | ||||
| 	> .bg | ||||
| 		display block | ||||
| 		position fixed | ||||
| 		z-index 1 | ||||
| 		top 0 | ||||
| 		left 0 | ||||
| 		width 100% | ||||
| 		height 100% | ||||
| 		background rgba(0, 0, 0, 0.7) | ||||
|  | ||||
| 	> img | ||||
| 		position fixed | ||||
| 		z-index 2 | ||||
| 		top 0 | ||||
| 		right 0 | ||||
| 		bottom 0 | ||||
| 		left 0 | ||||
| 		max-width 100% | ||||
| 		max-height 100% | ||||
| 		margin auto | ||||
| 		cursor zoom-out | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										66
									
								
								src/web/app/desktop/views/components/images-image.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/web/app/desktop/views/components/images-image.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| <template> | ||||
| <a class="mk-images-image" | ||||
| 	:href="image.url" | ||||
| 	@mousemove="onMousemove" | ||||
| 	@mouseleave="onMouseleave" | ||||
| 	@click.prevent="onClick" | ||||
| 	:style="styles" | ||||
| 	:title="image.name"></a> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	props: ['image'], | ||||
| 	computed: { | ||||
| 		style(): any { | ||||
| 			return { | ||||
| 				'background-color': this.image.properties.average_color ? `rgb(${this.image.properties.average_color.join(',')})` : 'transparent', | ||||
| 				'background-image': `url(${this.image.url}?thumbnail&size=512)` | ||||
| 			}; | ||||
| 		} | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		onMousemove(e) { | ||||
| 			const rect = this.$refs.view.getBoundingClientRect(); | ||||
| 			const mouseX = e.clientX - rect.left; | ||||
| 			const mouseY = e.clientY - rect.top; | ||||
| 			const xp = mouseX / this.$el.offsetWidth * 100; | ||||
| 			const yp = mouseY / this.$el.offsetHeight * 100; | ||||
| 			this.$el.style.backgroundPosition = xp + '% ' + yp + '%'; | ||||
| 			this.$el.style.backgroundImage = 'url("' + this.image.url + '?thumbnail")'; | ||||
| 		}, | ||||
|  | ||||
| 		onMouseleave() { | ||||
| 			this.$el.style.backgroundPosition = ''; | ||||
| 		}, | ||||
|  | ||||
| 		onClick(ev) { | ||||
| 			riot.mount(document.body.appendChild(document.createElement('mk-image-dialog')), { | ||||
| 				image: this.image | ||||
| 			}); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style lang="stylus" scoped> | ||||
| .mk-images-image | ||||
| 	display block | ||||
| 	overflow hidden | ||||
| 	border-radius 4px | ||||
|  | ||||
| 	> a | ||||
| 		display block | ||||
| 		cursor zoom-in | ||||
| 		overflow hidden | ||||
| 		width 100% | ||||
| 		height 100% | ||||
| 		background-position center | ||||
|  | ||||
| 		&:not(:hover) | ||||
| 			background-size cover | ||||
|  | ||||
| </style> | ||||
							
								
								
									
										60
									
								
								src/web/app/desktop/views/components/images.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/web/app/desktop/views/components/images.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| <template> | ||||
| <div class="mk-images"> | ||||
| 	<mk-images-image v-for="image in images" ref="image" :image="image" :key="image.id"/> | ||||
| </div> | ||||
| </template> | ||||
|  | ||||
| <style lang="stylus" scoped> | ||||
| .mk-images | ||||
| 	display grid | ||||
| 	grid-gap 4px | ||||
| 	height 256px | ||||
| </style> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
|  | ||||
| export default Vue.extend({ | ||||
| 	props: ['images'], | ||||
| 	mounted() { | ||||
| 		const tags = this.$refs.image as Vue[]; | ||||
|  | ||||
| 		if (this.images.length == 1) { | ||||
| 			this.$el.style.gridTemplateRows = '1fr'; | ||||
|  | ||||
| 			tags[0].$el.style.gridColumn = '1 / 2'; | ||||
| 			tags[0].$el.style.gridRow = '1 / 2'; | ||||
| 		} else if (this.images.length == 2) { | ||||
| 			this.$el.style.gridTemplateColumns = '1fr 1fr'; | ||||
| 			this.$el.style.gridTemplateRows = '1fr'; | ||||
|  | ||||
| 			tags[0].$el.style.gridColumn = '1 / 2'; | ||||
| 			tags[0].$el.style.gridRow = '1 / 2'; | ||||
| 			tags[1].$el.style.gridColumn = '2 / 3'; | ||||
| 			tags[1].$el.style.gridRow = '1 / 2'; | ||||
| 		} else if (this.images.length == 3) { | ||||
| 			this.$el.style.gridTemplateColumns = '1fr 0.5fr'; | ||||
| 			this.$el.style.gridTemplateRows = '1fr 1fr'; | ||||
|  | ||||
| 			tags[0].$el.style.gridColumn = '1 / 2'; | ||||
| 			tags[0].$el.style.gridRow = '1 / 3'; | ||||
| 			tags[1].$el.style.gridColumn = '2 / 3'; | ||||
| 			tags[1].$el.style.gridRow = '1 / 2'; | ||||
| 			tags[2].$el.style.gridColumn = '2 / 3'; | ||||
| 			tags[2].$el.style.gridRow = '2 / 3'; | ||||
| 		} else if (this.images.length == 4) { | ||||
| 			this.$el.style.gridTemplateColumns = '1fr 1fr'; | ||||
| 			this.$el.style.gridTemplateRows = '1fr 1fr'; | ||||
|  | ||||
| 			tags[0].$el.style.gridColumn = '1 / 2'; | ||||
| 			tags[0].$el.style.gridRow = '1 / 2'; | ||||
| 			tags[1].$el.style.gridColumn = '2 / 3'; | ||||
| 			tags[1].$el.style.gridRow = '1 / 2'; | ||||
| 			tags[2].$el.style.gridColumn = '1 / 2'; | ||||
| 			tags[2].$el.style.gridRow = '2 / 3'; | ||||
| 			tags[3].$el.style.gridColumn = '2 / 3'; | ||||
| 			tags[3].$el.style.gridRow = '2 / 3'; | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
		Reference in New Issue
	
	Block a user
	 こぴなたみぽ
					こぴなたみぽ