OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2014 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
11 * copyright notice, this list of conditions and the following disclaimer | 11 * copyright notice, this list of conditions and the following disclaimer |
12 * in the documentation and/or other materials provided with the | 12 * in the documentation and/or other materials provided with the |
(...skipping 22 matching lines...) Expand all Loading... |
35 */ | 35 */ |
36 WebInspector.Layers3DView = function(model) | 36 WebInspector.Layers3DView = function(model) |
37 { | 37 { |
38 WebInspector.View.call(this); | 38 WebInspector.View.call(this); |
39 this.element.classList.add("layers-3d-view"); | 39 this.element.classList.add("layers-3d-view"); |
40 this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("Not in t
he composited mode.\nConsider forcing composited mode in Settings.")); | 40 this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("Not in t
he composited mode.\nConsider forcing composited mode in Settings.")); |
41 this._model = model; | 41 this._model = model; |
42 this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeCha
nged, this._update, this); | 42 this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerTreeCha
nged, this._update, this); |
43 this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerPainted
, this._onLayerPainted, this); | 43 this._model.addEventListener(WebInspector.LayerTreeModel.Events.LayerPainted
, this._onLayerPainted, this); |
44 this._rotatingContainerElement = this.element.createChild("div", "fill rotat
ing-container"); | 44 this._rotatingContainerElement = this.element.createChild("div", "fill rotat
ing-container"); |
45 this.element.addEventListener("mousemove", this._onMouseMove.bind(this), fal
se); | 45 this._transformController = new WebInspector.TransformController(this.elemen
t); |
46 this.element.addEventListener("mouseout", this._onMouseMove.bind(this), fals
e); | 46 this._transformController.addEventListener(WebInspector.TransformController.
Events.TransformChanged, this._onTransformChanged, this); |
47 this.element.addEventListener("mousedown", this._onMouseDown.bind(this), fal
se); | |
48 this.element.addEventListener("mouseup", this._onMouseUp.bind(this), false); | |
49 this.element.addEventListener("contextmenu", this._onContextMenu.bind(this),
false); | |
50 this.element.addEventListener("dblclick", this._onDoubleClick.bind(this), fa
lse); | 47 this.element.addEventListener("dblclick", this._onDoubleClick.bind(this), fa
lse); |
51 this.element.addEventListener("click", this._onClick.bind(this), false); | 48 this.element.addEventListener("click", this._onClick.bind(this), false); |
| 49 this.element.addEventListener("mousemove", this._onMouseMove.bind(this), fal
se); |
| 50 this.element.addEventListener("contextmenu", this._onContextMenu.bind(this),
false); |
52 this._elementsByLayerId = {}; | 51 this._elementsByLayerId = {}; |
53 this._rotateX = 0; | |
54 this._rotateY = 0; | |
55 this._scaleAdjustmentStylesheet = this.element.ownerDocument.head.createChil
d("style"); | 52 this._scaleAdjustmentStylesheet = this.element.ownerDocument.head.createChil
d("style"); |
56 this._scaleAdjustmentStylesheet.disabled = true; | 53 this._scaleAdjustmentStylesheet.disabled = true; |
57 this._lastOutlinedElement = {}; | 54 this._lastOutlinedElement = {}; |
58 this._layerImage = document.createElement("img"); | 55 this._layerImage = document.createElement("img"); |
| 56 this._layerImage.style.width = "100%"; |
| 57 this._layerImage.style.height = "100%"; |
59 WebInspector.settings.showPaintRects.addChangeListener(this._update, this); | 58 WebInspector.settings.showPaintRects.addChangeListener(this._update, this); |
60 } | 59 } |
61 | 60 |
62 /** | 61 /** |
63 * @enum {string} | 62 * @enum {string} |
64 */ | 63 */ |
65 WebInspector.Layers3DView.OutlineType = { | 64 WebInspector.Layers3DView.OutlineType = { |
66 Hovered: "hovered", | 65 Hovered: "hovered", |
67 Selected: "selected" | 66 Selected: "selected" |
68 } | 67 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
149 if (imageURL) | 148 if (imageURL) |
150 this._layerImage.src = imageURL; | 149 this._layerImage.src = imageURL; |
151 element.appendChild(this._layerImage); | 150 element.appendChild(this._layerImage); |
152 }, | 151 }, |
153 | 152 |
154 _scaleToFit: function() | 153 _scaleToFit: function() |
155 { | 154 { |
156 var root = this._model.contentRoot(); | 155 var root = this._model.contentRoot(); |
157 if (!root) | 156 if (!root) |
158 return; | 157 return; |
| 158 |
159 const padding = 40; | 159 const padding = 40; |
160 var scaleX = this._clientWidth / (root.width() + 2 * padding); | 160 var scaleX = this._clientWidth / (root.width() + 2 * padding); |
161 var scaleY = this._clientHeight / (root.height() + 2 * padding); | 161 var scaleY = this._clientHeight / (root.height() + 2 * padding); |
162 this._scale = Math.min(scaleX, scaleY); | 162 var autoScale = Math.min(scaleX, scaleY); |
163 | 163 |
| 164 this._scale = autoScale * this._transformController.scale(); |
| 165 this._paddingX = ((this._clientWidth / autoScale - root.width()) >> 1) *
this._scale; |
| 166 this._paddingY = ((this._clientHeight / autoScale - root.height()) >> 1)
* this._scale; |
164 const screenLayerSpacing = 20; | 167 const screenLayerSpacing = 20; |
165 this._layerSpacing = Math.ceil(screenLayerSpacing / this._scale) + "px"; | 168 this._layerSpacing = screenLayerSpacing + "px"; |
166 const screenLayerThickness = 4; | 169 const screenLayerThickness = 4; |
167 var layerThickness = Math.ceil(screenLayerThickness / this._scale) + "px
"; | 170 var layerThickness = screenLayerThickness + "px"; |
| 171 |
168 var stylesheetContent = ".layer-container .side-wall { height: " + layer
Thickness + "; width: " + layerThickness + "; } " + | 172 var stylesheetContent = ".layer-container .side-wall { height: " + layer
Thickness + "; width: " + layerThickness + "; } " + |
169 ".layer-container .back-wall { -webkit-transform: translateZ(-" + la
yerThickness + "); } " + | 173 ".layer-container .back-wall { -webkit-transform: translateZ(-" + la
yerThickness + "); } " + |
170 ".layer-container { -webkit-transform: translateZ(" + this._layerSpa
cing + "); }"; | 174 ".layer-container { -webkit-transform: translateZ(" + this._layerSpa
cing + "); }"; |
171 // Workaround for double style recalculation upon assignment to style sh
eet's text content. | 175 // Workaround for double style recalculation upon assignment to style sh
eet's text content. |
172 var stylesheetTextNode = this._scaleAdjustmentStylesheet.firstChild; | 176 var stylesheetTextNode = this._scaleAdjustmentStylesheet.firstChild; |
173 if (!stylesheetTextNode || stylesheetTextNode.nodeType !== Node.TEXT_NOD
E || stylesheetTextNode.nextSibling) | 177 if (!stylesheetTextNode || stylesheetTextNode.nodeType !== Node.TEXT_NOD
E || stylesheetTextNode.nextSibling) |
174 this._scaleAdjustmentStylesheet.textContent = stylesheetContent; | 178 this._scaleAdjustmentStylesheet.textContent = stylesheetContent; |
175 else | 179 else |
176 stylesheetTextNode.nodeValue = stylesheetContent; | 180 stylesheetTextNode.nodeValue = stylesheetContent; |
177 var element = this._elementForLayer(root); | 181 |
178 element.style.webkitTransform = "scale3d(" + this._scale + "," + this._s
cale + "," + this._scale + ")"; | 182 var style = this._elementForLayer(root).style; |
179 element.style.webkitTransformOrigin = ""; | 183 style.left = this._paddingX + "px"; |
180 element.style.left = ((this._clientWidth - root.width() * this._scale) >
> 1) + "px"; | 184 style.top = this._paddingY + "px"; |
181 element.style.top = ((this._clientHeight - root.height() * this._scale)
>> 1) + "px"; | 185 style.webkitTransformOrigin = ""; |
| 186 }, |
| 187 |
| 188 /** |
| 189 * @param {!WebInspector.Event} event |
| 190 */ |
| 191 _onTransformChanged: function(event) |
| 192 { |
| 193 var changedTransforms = /** @type {number} */ (event.data); |
| 194 if (changedTransforms & WebInspector.TransformController.TransformType.S
cale) |
| 195 this._update(); |
| 196 else |
| 197 this._updateTransform(); |
| 198 }, |
| 199 |
| 200 _updateTransform: function() |
| 201 { |
| 202 var root = this._model.contentRoot(); |
| 203 if (!root) |
| 204 return; |
| 205 var offsetX = this._transformController.offsetX(); |
| 206 var offsetY = this._transformController.offsetY(); |
| 207 var style = this._rotatingContainerElement.style; |
| 208 // Translate well to front so that no matter how we turn the plane, no p
arts of it goes below parent. |
| 209 // This makes sure mouse events go to proper layers, not straight to the
parent. |
| 210 style.webkitTransform = "translateZ(10000px)" + |
| 211 " rotateX(" + this._transformController.rotateX() + "deg) rotateY("
+ this._transformController.rotateY() + "deg)" + |
| 212 " translateX(" + offsetX + "px) translateY(" + offsetY + "px)"; |
| 213 // Compute where the center of shitfted and scaled root layer would be a
nd use is as origin for rotation. |
| 214 style.webkitTransformOrigin = Math.round(this._paddingX + offsetX + root
.width() * this._scale / 2) + "px " + Math.round(this._paddingY + offsetY + root
.height() * this._scale / 2) + "px"; |
182 }, | 215 }, |
183 | 216 |
184 _update: function() | 217 _update: function() |
185 { | 218 { |
186 if (!this.isShowing()) { | 219 if (!this.isShowing()) { |
187 this._needsUpdate = true; | 220 this._needsUpdate = true; |
188 return; | 221 return; |
189 } | 222 } |
190 if (!this._model.contentRoot()) { | 223 if (!this._model.contentRoot()) { |
191 this._emptyView.show(this.element); | 224 this._emptyView.show(this.element); |
(...skipping 11 matching lines...) Expand all Loading... |
203 } | 236 } |
204 this._clientWidth = this.element.clientWidth; | 237 this._clientWidth = this.element.clientWidth; |
205 this._clientHeight = this.element.clientHeight; | 238 this._clientHeight = this.element.clientHeight; |
206 for (var layerId in this._elementsByLayerId) { | 239 for (var layerId in this._elementsByLayerId) { |
207 if (this._model.layerById(layerId)) | 240 if (this._model.layerById(layerId)) |
208 continue; | 241 continue; |
209 this._elementsByLayerId[layerId].remove(); | 242 this._elementsByLayerId[layerId].remove(); |
210 delete this._elementsByLayerId[layerId]; | 243 delete this._elementsByLayerId[layerId]; |
211 } | 244 } |
212 this._scaleToFit(); | 245 this._scaleToFit(); |
| 246 this._updateTransform(); |
213 this._model.forEachLayer(updateLayer.bind(this), this._model.contentRoot
()); | 247 this._model.forEachLayer(updateLayer.bind(this), this._model.contentRoot
()); |
214 this._needsUpdate = false; | 248 this._needsUpdate = false; |
215 }, | 249 }, |
216 | 250 |
217 /** | 251 /** |
218 * @param {!WebInspector.Event} event | 252 * @param {!WebInspector.Event} event |
219 */ | 253 */ |
220 _onLayerPainted: function(event) | 254 _onLayerPainted: function(event) |
221 { | 255 { |
222 var layer = /** @type {!WebInspector.Layer} */ (event.data); | 256 var layer = /** @type {!WebInspector.Layer} */ (event.data); |
(...skipping 29 matching lines...) Expand all Loading... |
252 var layer = element.__layerDetails.layer; | 286 var layer = element.__layerDetails.layer; |
253 var style = element.style; | 287 var style = element.style; |
254 var isContentRoot = layer === this._model.contentRoot(); | 288 var isContentRoot = layer === this._model.contentRoot(); |
255 var parentElement = isContentRoot ? this._rotatingContainerElement : thi
s._elementForLayer(layer.parent()); | 289 var parentElement = isContentRoot ? this._rotatingContainerElement : thi
s._elementForLayer(layer.parent()); |
256 element.__layerDetails.depth = parentElement.__layerDetails ? parentElem
ent.__layerDetails.depth + 1 : 0; | 290 element.__layerDetails.depth = parentElement.__layerDetails ? parentElem
ent.__layerDetails.depth + 1 : 0; |
257 element.enableStyleClass("invisible", layer.invisible()); | 291 element.enableStyleClass("invisible", layer.invisible()); |
258 this._updateElementColor(element); | 292 this._updateElementColor(element); |
259 if (parentElement !== element.parentElement) | 293 if (parentElement !== element.parentElement) |
260 parentElement.appendChild(element); | 294 parentElement.appendChild(element); |
261 | 295 |
262 style.width = layer.width() + "px"; | 296 style.width = layer.width() * this._scale + "px"; |
263 style.height = layer.height() + "px"; | 297 style.height = layer.height() * this._scale + "px"; |
264 this._updatePaintRect(element); | 298 this._updatePaintRect(element); |
265 if (isContentRoot) | 299 if (isContentRoot) |
266 return; | 300 return; |
267 | 301 style.left = layer.offsetX() * this._scale + "px"; |
268 style.left = layer.offsetX() + "px"; | 302 style.top = layer.offsetY() * this._scale + "px"; |
269 style.top = layer.offsetY() + "px"; | |
270 var transform = layer.transform(); | 303 var transform = layer.transform(); |
271 if (transform) { | 304 if (transform) { |
| 305 transform = transform.slice(); |
| 306 // Adjust offset in the transform matrix according to scale. |
| 307 for (var i = 12; i < 15; ++i) |
| 308 transform[i] *= this._scale; |
272 // Avoid exponential notation in CSS. | 309 // Avoid exponential notation in CSS. |
273 style.webkitTransform = "matrix3d(" + transform.map(toFixed5).join("
,") + ") translateZ(" + this._layerSpacing + ")"; | 310 style.webkitTransform = "matrix3d(" + transform.map(toFixed5).join("
,") + ") translateZ(" + this._layerSpacing + ")"; |
274 var anchor = layer.anchorPoint(); | 311 var anchor = layer.anchorPoint(); |
275 style.webkitTransformOrigin = Math.round(anchor[0] * 100) + "% " + M
ath.round(anchor[1] * 100) + "% " + anchor[2]; | 312 style.webkitTransformOrigin = Math.round(anchor[0] * 100) + "% " + M
ath.round(anchor[1] * 100) + "% " + anchor[2]; |
276 } else { | 313 } else { |
277 style.webkitTransform = ""; | 314 style.webkitTransform = ""; |
278 style.webkitTransformOrigin = ""; | 315 style.webkitTransformOrigin = ""; |
279 } | 316 } |
280 | 317 |
281 function toFixed5(x) | 318 function toFixed5(x) |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 else { | 355 else { |
319 const base = 144; | 356 const base = 144; |
320 var component = base + 20 * ((element.__layerDetails.depth - 1) % 5)
; | 357 var component = base + 20 * ((element.__layerDetails.depth - 1) % 5)
; |
321 color = "rgba(" + component + "," + component + "," + component + ",
0.8)"; | 358 color = "rgba(" + component + "," + component + "," + component + ",
0.8)"; |
322 } | 359 } |
323 element.style.backgroundColor = color; | 360 element.style.backgroundColor = color; |
324 }, | 361 }, |
325 | 362 |
326 /** | 363 /** |
327 * @param {?Event} event | 364 * @param {?Event} event |
328 */ | |
329 _onMouseDown: function(event) | |
330 { | |
331 if (event.which !== 1) | |
332 return; | |
333 this._setReferencePoint(event); | |
334 }, | |
335 | |
336 /** | |
337 * @param {?Event} event | |
338 */ | |
339 _setReferencePoint: function(event) | |
340 { | |
341 this._originX = event.clientX; | |
342 this._originY = event.clientY; | |
343 this._oldRotateX = this._rotateX; | |
344 this._oldRotateY = this._rotateY; | |
345 }, | |
346 | |
347 _resetReferencePoint: function() | |
348 { | |
349 delete this._originX; | |
350 delete this._originY; | |
351 delete this._oldRotateX; | |
352 delete this._oldRotateY; | |
353 }, | |
354 | |
355 /** | |
356 * @param {?Event} event | |
357 */ | |
358 _onMouseUp: function(event) | |
359 { | |
360 if (event.which !== 1) | |
361 return; | |
362 this._resetReferencePoint(); | |
363 }, | |
364 | |
365 /** | |
366 * @param {?Event} event | |
367 * @return {?WebInspector.Layer} | 365 * @return {?WebInspector.Layer} |
368 */ | 366 */ |
369 _layerFromEventPoint: function(event) | 367 _layerFromEventPoint: function(event) |
370 { | 368 { |
371 var element = this.element.ownerDocument.elementFromPoint(event.pageX, e
vent.pageY); | 369 var element = this.element.ownerDocument.elementFromPoint(event.pageX, e
vent.pageY); |
372 if (!element) | 370 if (!element) |
373 return null; | 371 return null; |
374 element = element.enclosingNodeOrSelfWithClass("layer-container"); | 372 element = element.enclosingNodeOrSelfWithClass("layer-container"); |
375 return element && element.__layerDetails && element.__layerDetails.layer
; | 373 return element && element.__layerDetails && element.__layerDetails.layer
; |
376 }, | 374 }, |
377 | 375 |
378 /** | 376 /** |
379 * @param {?Event} event | 377 * @param {?Event} event |
380 */ | 378 */ |
381 _onMouseMove: function(event) | |
382 { | |
383 if (!event.which) { | |
384 this.dispatchEventToListeners(WebInspector.Layers3DView.Events.Layer
Hovered, this._layerFromEventPoint(event)); | |
385 return; | |
386 } | |
387 if (event.which === 1) { | |
388 // Set reference point if we missed mousedown. | |
389 if (typeof this._originX !== "number") | |
390 this._setReferencePoint(event); | |
391 this._rotateX = this._oldRotateX + (this._originY - event.clientY) /
2; | |
392 this._rotateY = this._oldRotateY - (this._originX - event.clientX) /
4; | |
393 // Translate well to front so that no matter how we turn the plane,
no parts of it goes below parent. | |
394 // This makes sure mouse events go to proper layers, not straight to
the parent. | |
395 this._rotatingContainerElement.style.webkitTransform = "translateZ(1
0000px) rotateX(" + this._rotateX + "deg) rotateY(" + this._rotateY + "deg)"; | |
396 } | |
397 }, | |
398 | |
399 /** | |
400 * @param {?Event} event | |
401 */ | |
402 _onContextMenu: function(event) | 379 _onContextMenu: function(event) |
403 { | 380 { |
404 var layer = this._layerFromEventPoint(event); | 381 var layer = this._layerFromEventPoint(event); |
405 var nodeId = layer && layer.nodeId(); | 382 var nodeId = layer && layer.nodeId(); |
406 if (!nodeId) | 383 if (!nodeId) |
407 return; | 384 return; |
408 var domNode = WebInspector.domAgent.nodeForId(nodeId); | 385 var domNode = WebInspector.domAgent.nodeForId(nodeId); |
409 if (!domNode) | 386 if (!domNode) |
410 return; | 387 return; |
411 var contextMenu = new WebInspector.ContextMenu(event); | 388 var contextMenu = new WebInspector.ContextMenu(event); |
412 contextMenu.appendApplicableItems(domNode); | 389 contextMenu.appendApplicableItems(domNode); |
413 contextMenu.show(); | 390 contextMenu.show(); |
414 }, | 391 }, |
415 | 392 |
416 /** | 393 /** |
417 * @param {?Event} event | 394 * @param {?Event} event |
418 */ | 395 */ |
| 396 _onMouseMove: function(event) |
| 397 { |
| 398 if (event.which) |
| 399 return; |
| 400 this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerHove
red, this._layerFromEventPoint(event)); |
| 401 }, |
| 402 |
| 403 /** |
| 404 * @param {?Event} event |
| 405 */ |
419 _onClick: function(event) | 406 _onClick: function(event) |
420 { | 407 { |
421 this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSele
cted, this._layerFromEventPoint(event)); | 408 this.dispatchEventToListeners(WebInspector.Layers3DView.Events.LayerSele
cted, this._layerFromEventPoint(event)); |
422 }, | 409 }, |
423 | 410 |
424 /** | 411 /** |
425 * @param {?Event} event | 412 * @param {?Event} event |
426 */ | 413 */ |
427 _onDoubleClick: function(event) | 414 _onDoubleClick: function(event) |
428 { | 415 { |
(...skipping 11 matching lines...) Expand all Loading... |
440 * @param {!WebInspector.Layer} layer | 427 * @param {!WebInspector.Layer} layer |
441 * @param {!Element} paintRectElement | 428 * @param {!Element} paintRectElement |
442 */ | 429 */ |
443 WebInspector.LayerDetails = function(layer, paintRectElement) | 430 WebInspector.LayerDetails = function(layer, paintRectElement) |
444 { | 431 { |
445 this.layer = layer; | 432 this.layer = layer; |
446 this.depth = 0; | 433 this.depth = 0; |
447 this.paintRectElement = paintRectElement; | 434 this.paintRectElement = paintRectElement; |
448 this.paintCount = 0; | 435 this.paintCount = 0; |
449 } | 436 } |
OLD | NEW |