davestewart
6/15/2016 - 1:36 PM

Utility component create a proportionally-sized element, into which other elements can be displayed

Utility component create a proportionally-sized element, into which other elements can be displayed

Vue.component('ratio', {

	template:'<div class="ratio" :style="style"><slot></slot></div>',

	props:
	{
		width:
		{
			default		:512,
			type		:[String, Number],
			required	:true
		},
		height:
		{
			default		:288,
			type		:[String, Number],
			required	:true
		},
		size:
		{
			type		:[Number, String, Object, Array]
		},
		aspect:
		{
			default		:16/9,
			type		:[String, Number]
		}
	},

	data:function()
	{
		return {w:this.width, h:this.height, a:this.width / this.height};
	},

	computed:
	{
		width:
		{
			get:function(){ return this.w; },
			set:function(value)
			{
				value = parseFloat(value);
				this.w = value;
				this.h = value / this.a;
			}
		},
		height:
		{
			get:function(){ return this.h; },
			set:function(value)
			{
				value = parseFloat(value);
				this.h = value;
				this.w = value * this.a;
			}
		},
		size:
		{
			get:function(){ return {width:this.w, height:this.h}; },
			set:function(value)
			{
				if(typeof value == 'number' || typeof value == 'string')
				{
					this.w = this.h = parseFloat(value);
				}
				else if(value instanceof Array)
				{
					this.w = value[0];
					this.h = value[1];
				}
				else
				{
					this.w = value.width;
					this.h = value.height;
				}
				this.a = this.w / this.h;
			}
		},
		aspect:
		{
			get:function(){ return this.a; },
			set:function(value)
			{
				if(typeof value == 'number')
				{
					this.a = value;
				}
				else
				{
					var parts = value.match(/\d+/g);
					this.a = parseInt(parts[0]) / parseInt(parts[1]);
				}
				this.width = this.w;
			}
		},

		style:function()
		{
			return {width:this.w + 'px', height:this.h + 'px'};
		}
	}
});