Skip to content

Commit

Permalink
zoom coordinates stable against screen size
Browse files Browse the repository at this point in the history
  • Loading branch information
e3rd committed Oct 27, 2023
1 parent f8bbe08 commit 9fc50bd
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 22 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,18 @@ In this example, the image starts at `[100, 10, 2]`, then zooms out `[]`, then g
</article>
```

Position `0,0` is at the image centre. Its real dimension is taken into account so the value remains stable while changing the browser size (different displays). We recommend to use the property panel (<kbd>Alt+P</kbd>) to determine the coordinates.

Every image in the sections slowly zooms out from the center. (Images in header and footer are ignored.)

```html
<section data-step-points="[[0,0,15,5], [0,0,1,5]]">
<article><img src="..."/></article>
<article><img src="..."/></article>
<article><img src="..."/></article>
</section>
```

#### Panoramatic images

When an image is much longer than the screen, we show it slowly first before resizing it to fit the screen. This will delay the `<article>`'s `data-duration`. It starts when the image proportion width / height > `data-panorama-threshold=2`.
Expand Down
41 changes: 27 additions & 14 deletions slidershow/frame.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,19 @@ class Frame {
.filter((_, el) => this.prop("step-li", $(el))))
// [data-step-points] affects all <img>
.add($("img", this.$frame)
.filter((_, el) => this.prop("step-points", $(el)))
.filter((_, el) => !$(el).closest("header, footer").length) // filter out images in header/footer
.map((_, el) => {
// generate multiple steps (dummy <img-temp-animation-step>) for points
const $el = $(el)
const points = $el.data("step-points")
if(!points.length) {
const points = this.prop("step-points", $(el))
if (!points?.length) {
return
}

// what is the first zoom position we see
// XX When multiple zoomed images at frame (or zooming steps along with classic data-step) are tested,
// this will pose a problem. Because this.step_index points to the frame step,
// not to the image animation step.
const init_point = Array.from(points[this.step_index])
if (init_point) {
// init point has no transition duration, it's straight there when we come to the frame
Expand Down Expand Up @@ -737,11 +741,11 @@ class Frame {
rescale: wzoom => { // the function seems to be called unintuitively with grab moving
const scale = wzoom.content.currentScale
wzoom.content.maxScale = Math.max(maxScale_default, scale + 3)
$el.trigger("wzoomed", [wzoom, last_scale===scale])
$el.trigger("wzoomed", [last_scale === scale])
last_scale = scale
},
dragScrollableOptions: {
onDrop: (_, wzoom) => $el.trigger("wzoomed", wzoom)
onDrop: () => $el.trigger("wzoomed")
}
})
// Why correcting viewport? When having data-step-points and calling `zoom_set` from `prepare`,
Expand All @@ -751,13 +755,16 @@ class Frame {
// this simulates the parent.
wzoom.viewport.originalLeft = $el.position().left
wzoom.viewport.originalTop = $el.position().top
wzoom.viewport.originalWidth = $el.width()
wzoom.viewport.originalHeight = $el.height()

console.log("753: wzoom.viewport", wzoom.viewport) // TODO

const refresh_viewport = () => {
wzoom.viewport.originalWidth = $el.width()
wzoom.viewport.originalHeight = $el.height()
}
refresh_viewport()
$(window).on("resize.wzoom", refresh_viewport)

$el
.data("wzoom_get_ratio", () => $el.width() / $el.prop("naturalWidth"))
.data("wzoom_resize_off", () => $(window).off("resize.wzoom", refresh_viewport)) // DOC
// we have zoomed in, do not playback further
.off("click wheel")
.on("click wheel", () => this.playback.moving = false)
Expand All @@ -773,15 +780,20 @@ class Frame {
const $el = $(el)
setTimeout(() => { // we have to timeout - wzoom bug, has to finish before it can be destroyed
$el.data("wzoom").destroy()
$el.data("wzoom", null)
$el.attr("data-wzoom", null)
$el.data("wzoom_resize_off")()
$el
.data("wzoom", null)
.data("wzoom_get_ratio", null)
.data("wzoom_resize_off", null)
.attr("data-wzoom", null)
})
})
}

zoom_get($el) {
const { currentLeft, currentTop, currentScale } = this.zoom_init($el).content
return [currentLeft, currentTop, currentScale]
const ratio = $el.data("wzoom_get_ratio")()
return [currentLeft / ratio, currentTop / ratio, currentScale]
}

/**
Expand All @@ -796,9 +808,10 @@ class Frame {
zoom_set($el, left = 0, top = 0, scale = 1, transition_duration = null, duration = null) {
const wzoom = this.zoom_init($el)
transition_duration ??= prop("step-transition-duration", $el, null, "transition-duration")
const ratio = $el.data("wzoom_get_ratio")()
const orig = wzoom.options.smoothTime
wzoom.options.smoothTime = transition_duration
wzoom.transform(top, left, scale)
wzoom.transform(top * ratio, left * ratio, scale)
wzoom.options.smoothTime = orig
this.add_effect(resolve => $el.on("transitionend", () => resolve()))
return duration ?? prop("step-duration", $el, null, "duration")
Expand Down
2 changes: 2 additions & 0 deletions slidershow/launch.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ Private attributes that are not documented in the README because the user should
* .step-not-yet-visible Auxiliary window highlights not-yet-seen elements.
* <img-temp-animation-step> Tags that help distinguish image zoom step from the image step.
* trigger("wzoomed") Img with wzoom action.
* data("wzoom_get_ratio") Img with wzoom screen aware ratio.
* data("wzoom_resize_off") Img with wzoom event destructor.
*/

// var variables that a hacky user might wish to change. Might become data-attributes in the future.
Expand Down
11 changes: 6 additions & 5 deletions slidershow/property_panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ class PropertyPanel {
const cc = this.playback.change_controller
const $actor = frame.$actor
const points = JSON.parse($input.val() || '[]') // load set of points from the given <input>

$wrap.append(points.map(p => new_point(p)))
if (points.length) {
$wrap.append(points.map(p => new_point(p)))
}
$input // refresh from either: user editing <input>, user did undo, not from us having edited <input>
.off("change.step-points undo-performed")
.on("change.step-points undo-performed", () => {
Expand All @@ -32,7 +33,7 @@ class PropertyPanel {
const $new_point = new_point(frame.zoom_get($actor), true).trigger("click").appendTo($wrap)
cc.change(() => $new_point.trigger("dblclick"))
})
.insertAfter($wrap)
.insertBefore($wrap)

function new_point(point, push = false) {
if (push) {
Expand All @@ -50,8 +51,8 @@ class PropertyPanel {
$(this).addClass("active")
$actor
.off("wzoomed")
.on("wzoomed", (_, wzoom, minor_move) => {
const { currentLeft, currentTop, currentScale } = wzoom.content
.on("wzoomed", (_, minor_move) => {
const [currentLeft, currentTop, currentScale] = frame.zoom_get($actor)
point[0] = Math.round(currentLeft)
point[1] = Math.round(currentTop)
point[2] = Math.round(currentScale)
Expand Down
2 changes: 1 addition & 1 deletion slidershow/slidershow.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ loadjQuery(() => {
crossOrigin: "anonymous"
},
{ src: "https://cdn.jsdelivr.net/npm/js-circle-progress@0.2.4/dist/jquery.circle-progress.min.js" },
{ src: "https://cdn.jsdelivr.net/gh/e3rd/WebHotkeys@0.8.1/WebHotkeys.js" },
{ src: "https://cdn.jsdelivr.net/gh/e3rd/WebHotkeys@f198e3f82c841e12c8bbdda6326e676d332c9714/WebHotkeys.js" }, // put proper version TODO
{ src: "https://cdn.jsdelivr.net/npm/exif-js" },
{ src: "https://cdn.jsdelivr.net/npm/showdown@2.1.0/dist/showdown.min.js" },
MAP_ENABLE ? { src: "https://api.mapy.cz/loader.js" } : null,
Expand Down
3 changes: 2 additions & 1 deletion style.css
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,15 @@ frame-preview > article-map [data-step].step-not-yet-visible {
cursor: pointer;
display: inline-block;
background-color: lightyellow;
border: 1px solid gray;
border-radius: 5px;
padding: 3px;
}
#hud #hud-properties .hud-point.active > span {
background-color: yellow;
}
#hud #hud-properties > .hud-point {
padding: 5px;
margin-bottom: 0px;
display: inline-block;
}
#map-hud {
Expand Down
3 changes: 2 additions & 1 deletion style.less
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ frame-preview {
cursor: pointer;
display: inline-block;
background-color: lightyellow;
border: 1px solid gray;
border-radius: 5px;
padding: 3px;
}
Expand All @@ -234,7 +235,7 @@ frame-preview {
}

>.hud-point {
padding: 5px;
margin-bottom: 0px;
display: inline-block;
}
}
Expand Down

0 comments on commit 9fc50bd

Please sign in to comment.