Add a lot of basic utility stuff to resizer.
Chris Pressey
10 years ago
5 | 5 | if (window.yoob === undefined) yoob = {}; |
6 | 6 | |
7 | 7 | /* |
8 | * This class is provided to help craft solutions to resizing problems, | |
8 | * These classes are provided to help craft solutions to resizing problems, | |
9 | 9 | * which (in my experience, anyway) are always rather nasty and ugly. |
10 | 10 | * |
11 | * So, what we have is: a rectangle of a desired size (width and height). | |
12 | * We call this the _source_ size. This might be the size of an image we | |
11 | * First, we have a class which is an abstraction of a size. It may be | |
12 | * used explicitly to specify a desired size, or it may be used to determine | |
13 | * the size of some object (perhaps an Image, or a DOM element, or the | |
14 | * visible portion of a proposed DOM element.) | |
15 | */ | |
16 | ||
17 | yoob.Size = function() { | |
18 | this.init = function(cfg) { | |
19 | this.width = cfg.width; | |
20 | this.height = cfg.height; | |
21 | return this; | |
22 | }; | |
23 | ||
24 | this.setFromImage = function(img) { | |
25 | this.width = img.width; | |
26 | this.height = img.height; | |
27 | return this; | |
28 | }; | |
29 | ||
30 | this.setFromElement = function(elem) { | |
31 | this.width = elem.clientWidth; | |
32 | this.height = elem.clientHeight; | |
33 | return this; | |
34 | }; | |
35 | ||
36 | this.applyToElement = function(elem) { | |
37 | elem.width = this.width; | |
38 | elem.height = this.height; | |
39 | return this; | |
40 | }; | |
41 | ||
42 | this.applyAsStyle = function(elem) { | |
43 | elem.style.width = this.width + "px"; | |
44 | elem.style.height = this.height + "px"; | |
45 | return this; | |
46 | }; | |
47 | ||
48 | this.getAspectRatio = function() { | |
49 | return this.width / this.height; | |
50 | }; | |
51 | ||
52 | this.scale = function(factor) { | |
53 | this.width *= factor; | |
54 | this.height *= factor; | |
55 | return this; | |
56 | }; | |
57 | ||
58 | /* | |
59 | * Return the factor that would be required to scale this size by | |
60 | * in order to make it fit inside the given size, while preserving | |
61 | * the aspect ratio. | |
62 | */ | |
63 | this.getFitScale = function(destSize) { | |
64 | var widthFactor = this.width / destSize.width; | |
65 | var heightFactor = this.height / destSize.height; | |
66 | // say this is twice as wide, but 1.5 as high as dest. | |
67 | // then wf will be 2, and hf will be 1.5. | |
68 | // max of these is 2 | |
69 | // so fitscale will be 0.5 | |
70 | return 1 / Math.max(widthFactor, heightFactor); | |
71 | }; | |
72 | ||
73 | this.fit = function(destSize) { | |
74 | return this.scale(this.getFitScale(destSize)); | |
75 | }; | |
76 | ||
77 | /* | |
78 | * Assume this size is placed at (left, top) inside the given size. | |
79 | * Truncate this size so that it fits entirely within the given size. | |
80 | * For example, the given size might be window.client{Width,Height} | |
81 | * and the (left, top) might be the position of a div. | |
82 | */ | |
83 | this.clip = function(outerSize, left, top) { | |
84 | if (left + this.width > outerSize.width) { | |
85 | this.width = outerSize.width - left; | |
86 | } | |
87 | if (top + this.height > outerSize.height) { | |
88 | this.height = outerSize.height - top; | |
89 | } | |
90 | return this; | |
91 | }; | |
92 | }; | |
93 | ||
94 | /* | |
95 | * Now that we have Sizes, what we want to do is reconcile them | |
96 | * | |
97 | * So, what we have is a _source size_, which might be the size of an image we | |
13 | 98 | * wish to display, or the extents of a playfield we wish to consider. |
14 | 99 | * |
15 | * We also have a _destination_ size. This might be the available screen | |
100 | * We also have a _destination size_, which might be the available screen | |
16 | 101 | * real estate for displaying the source image. Or, more precisely, it |
17 | 102 | * might be the available size, in a given DOM element, taking account of |
18 | 103 | * any number of factors, like visibility on the screen. |
19 | 104 | * |
20 | * In general, we want to reconcile these two vectors. | |
21 | * | |
22 | * ... | |
105 | * From these, and various jiggery-pokery, we compute a _result size_. | |
23 | 106 | */ |
24 | 107 | yoob.Resizer = function() { |
25 | 108 | this.init = function(cfg) { |
26 | this.sourceWidth = cfg.sourceWidth; | |
27 | this.sourceHeight = cfg.sourceHeight; | |
109 | this.src = cfg.src; // assumed to be a Size | |
110 | this.dest = cfg.dest; // assumed to be a Size | |
28 | 111 | return this; |
29 | 112 | }; |
113 | ||
114 | this.setSource = function(src) { this.src = src; return this; } | |
115 | this.setDestination = function(dest) { this.dest = dest; return this; } | |
116 | ||
117 | /* ??? */ | |
118 | /* 3. Profit! */ | |
119 | ||
120 | /* Things to handle: | |
121 | onload | |
122 | onresize | |
123 | onorientationchange | |
124 | if style.width/height expressed in %, re-get clientW/H after such | |
125 | */ | |
30 | 126 | }; |