Skip to content

Support touch events #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 2, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
<head>
<style>
.wrapper {
width: 500px;
margin: 30px auto;
}
.loading {
Expand All @@ -13,6 +12,7 @@
}
</style>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="../src/index.css" rel="stylesheet">
<!-- <script type="module" src="../dist/index.js"></script> -->
<script type="module" src="https://unpkg.com/@github/image-crop-element@latest/dist/index.js"></script>
Expand Down
5 changes: 4 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
image-crop { display: block; }
image-crop {
touch-action: none;
display: block;
}
image-crop.nesw { cursor: nesw-resize; }
image-crop.nwse { cursor: nwse-resize; }
image-crop.nesw .crop-box,
Expand Down
36 changes: 30 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const startPositions: WeakMap<ImageCropElement, {startX: number; startY: number}
const dragStartPositions: WeakMap<ImageCropElement, {dragStartX: number; dragStartY: number}> = new WeakMap()
const constructedElements: WeakMap<ImageCropElement, {image: HTMLImageElement; box: HTMLElement}> = new WeakMap()

function moveCropArea(event: MouseEvent | KeyboardEvent) {
function moveCropArea(event: TouchEvent | MouseEvent | KeyboardEvent) {
const el = event.currentTarget
if (!(el instanceof ImageCropElement)) return
const {box, image} = constructedElements.get(el) || {}
Expand All @@ -37,10 +37,16 @@ function moveCropArea(event: MouseEvent | KeyboardEvent) {
deltaX = 1
}
} else if (dragStartPositions.has(el) && event instanceof MouseEvent) {
const pos = dragStartPositions.get(el)
if (!pos) return
const pos = dragStartPositions.get(el)!
deltaX = event.pageX - pos.dragStartX
deltaY = event.pageY - pos.dragStartY
} else if (dragStartPositions.has(el) && event instanceof TouchEvent) {
// Only support a single touch at a time
const {pageX, pageY} = event.changedTouches[0]

const {dragStartX, dragStartY} = dragStartPositions.get(el)!
deltaX = pageX - dragStartX
deltaY = pageY - dragStartY
}

if (deltaX !== 0 || deltaY !== 0) {
Expand All @@ -57,10 +63,17 @@ function moveCropArea(event: MouseEvent | KeyboardEvent) {
dragStartX: event.pageX,
dragStartY: event.pageY
})
} else if (event instanceof TouchEvent) {
// Only support a single touch at a time
const {pageX, pageY} = event.changedTouches[0]
dragStartPositions.set(el, {
dragStartX: pageX,
dragStartY: pageY
})
}
}

function updateCropArea(event: MouseEvent | KeyboardEvent) {
function updateCropArea(event: TouchEvent | MouseEvent | KeyboardEvent) {
const target = event.target
if (!(target instanceof HTMLElement)) return

Expand All @@ -84,12 +97,17 @@ function updateCropArea(event: MouseEvent | KeyboardEvent) {
if (!pos) return
deltaX = event.pageX - pos.startX - rect.left - window.pageXOffset
deltaY = event.pageY - pos.startY - rect.top - window.pageYOffset
} else if (event instanceof TouchEvent) {
const pos = startPositions.get(el)
if (!pos) return
deltaX = event.changedTouches[0].pageX - pos.startX - rect.left - window.pageXOffset
deltaY = event.changedTouches[0].pageY - pos.startY - rect.top - window.pageYOffset
}

if (deltaX && deltaY) updateDimensions(el, deltaX, deltaY, !(event instanceof KeyboardEvent))
}

function startUpdate(event: MouseEvent) {
function startUpdate(event: TouchEvent | MouseEvent) {
const currentTarget = event.currentTarget
if (!(currentTarget instanceof HTMLElement)) return

Expand All @@ -105,6 +123,7 @@ function startUpdate(event: MouseEvent) {
const direction = target.getAttribute('data-direction') || ''
// Change crop area
el.addEventListener('mousemove', updateCropArea)
el.addEventListener('touchmove', updateCropArea)
if (['nw', 'se'].indexOf(direction) >= 0) el.classList.add('nwse')
if (['ne', 'sw'].indexOf(direction) >= 0) el.classList.add('nesw')
startPositions.set(el, {
Expand All @@ -115,6 +134,7 @@ function startUpdate(event: MouseEvent) {
} else {
// Move crop area
el.addEventListener('mousemove', moveCropArea)
el.addEventListener('touchmove', moveCropArea)
}
}

Expand Down Expand Up @@ -164,14 +184,16 @@ function setInitialPosition(el: ImageCropElement) {
updateDimensions(el, side, side)
}

function stopUpdate(event: MouseEvent) {
function stopUpdate(event: TouchEvent | MouseEvent) {
const el = event.currentTarget
if (!(el instanceof ImageCropElement)) return

dragStartPositions.delete(el)
el.classList.remove('nwse', 'nesw')
el.removeEventListener('mousemove', updateCropArea)
el.removeEventListener('mousemove', moveCropArea)
el.removeEventListener('touchmove', updateCropArea)
el.removeEventListener('touchmove', moveCropArea)
}

interface Result {
Expand Down Expand Up @@ -208,8 +230,10 @@ class ImageCropElement extends HTMLElement {

image.addEventListener('load', imageReady)
this.addEventListener('mouseleave', stopUpdate)
this.addEventListener('touchend', stopUpdate)
this.addEventListener('mouseup', stopUpdate)
box.addEventListener('mousedown', startUpdate)
box.addEventListener('touchstart', startUpdate)
this.addEventListener('keydown', moveCropArea)
this.addEventListener('keydown', updateCropArea)

Expand Down