or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

component-configuration.mdevent-handling.mdindex.mdprogrammatic-control.md

event-handling.mddocs/

0

# Event Handling

1

2

Comprehensive event system for responding to image loading, cropping interactions, and real-time preview updates in VueCropper.

3

4

## Capabilities

5

6

### Image Loading Events

7

8

Events fired during image loading and processing phases.

9

10

```javascript { .api }

11

/**

12

* Image load completion event

13

* @param status - "success" for successful load, "error" for failures, or Error object

14

*/

15

@img-load: (status: 'success' | 'error' | Error) => void;

16

17

/**

18

* Detailed error information when image loading fails

19

* @param error - Error object with failure details

20

*/

21

@img-load-error: (error: Error) => void;

22

```

23

24

**Usage Examples:**

25

26

```vue

27

<template>

28

<VueCropper

29

:img="imageUrl"

30

@img-load="handleImageLoad"

31

@img-load-error="handleImageError"

32

/>

33

</template>

34

35

<script>

36

export default {

37

methods: {

38

handleImageLoad(status) {

39

if (status === 'success') {

40

console.log('Image loaded successfully');

41

this.imageReady = true;

42

} else if (status === 'error') {

43

console.error('Failed to load image');

44

this.showErrorMessage = true;

45

} else if (status instanceof Error) {

46

console.error('Image load error:', status.message);

47

}

48

},

49

50

handleImageError(error) {

51

console.error('Detailed error:', error);

52

this.errorDetails = error.message;

53

this.showRetryOption = true;

54

}

55

}

56

};

57

</script>

58

```

59

60

### Movement and Interaction Events

61

62

Events fired during user interactions with the image and crop box.

63

64

```javascript { .api }

65

/**

66

* Image movement/dragging events

67

* @param data - Movement data with position information

68

*/

69

@img-moving: (data: MovingData) => void;

70

71

/**

72

* Crop box movement/dragging events

73

* @param data - Movement data with crop box position

74

*/

75

@crop-moving: (data: MovingData) => void;

76

77

/**

78

* Crop box size change events (modern name)

79

* @param data - Size change data with dimensions

80

*/

81

@change-crop-size: (data: CropSizeData) => void;

82

83

/**

84

* Legacy camelCase events (for compatibility)

85

*/

86

@imgLoad: (status: 'success' | 'error' | Error) => void;

87

@imgMoving: (data: MovingData) => void;

88

@realTime: (data: PreviewData) => void;

89

@changeCropSize: (data: CropSizeData) => void;

90

@cropMoving: (data: MovingData) => void;

91

92

interface MovingData {

93

moving: boolean;

94

axis: {

95

x1: number; // top-left x coordinate

96

x2: number; // top-right x coordinate

97

y1: number; // top-left y coordinate

98

y2: number; // bottom-right y coordinate

99

};

100

}

101

102

interface CropSizeData {

103

width: number; // crop box width

104

height: number; // crop box height

105

}

106

```

107

108

**Usage Examples:**

109

110

```vue

111

<template>

112

<VueCropper

113

:img="imageUrl"

114

@img-moving="handleImageMove"

115

@crop-moving="handleCropMove"

116

@change-crop-size="handleCropSizeChange"

117

/>

118

119

<div class="status-panel">

120

<p>Image Moving: {{ imageMoving ? 'Yes' : 'No' }}</p>

121

<p>Crop Position: {{ cropPosition.x }}, {{ cropPosition.y }}</p>

122

<p>Crop Size: {{ cropSize.width }} × {{ cropSize.height }}</p>

123

</div>

124

</template>

125

126

<script>

127

export default {

128

data() {

129

return {

130

imageMoving: false,

131

cropPosition: { x: 0, y: 0 },

132

cropSize: { width: 0, height: 0 }

133

};

134

},

135

methods: {

136

handleImageMove(data) {

137

this.imageMoving = data.moving;

138

if (data.moving) {

139

console.log('Image being dragged to:', data.axis);

140

// Update UI to show drag state

141

this.showDragIndicator = true;

142

} else {

143

this.showDragIndicator = false;

144

}

145

},

146

147

handleCropMove(data) {

148

if (data.moving) {

149

this.cropPosition = {

150

x: data.axis.x1,

151

y: data.axis.y1

152

};

153

// Sync with external preview or coordinates display

154

this.updateExternalPreview(data.axis);

155

}

156

},

157

158

handleCropSizeChange(data) {

159

this.cropSize = {

160

width: data.width,

161

height: data.height

162

};

163

// Validate minimum/maximum sizes

164

if (data.width < 50 || data.height < 50) {

165

this.showSizeWarning = true;

166

}

167

}

168

}

169

};

170

</script>

171

```

172

173

### Real-time Preview Events

174

175

Core event for implementing live preview functionality.

176

177

```javascript { .api }

178

/**

179

* Real-time preview updates during cropping operations

180

* @param data - Complete preview data for rendering external previews

181

*/

182

@real-time: (data: PreviewData) => void;

183

184

interface PreviewData {

185

url: string; // preview image URL/base64

186

img: string; // CSS transform styles for image element

187

div: string; // CSS transform styles for container element

188

w: number; // preview width in pixels

189

h: number; // preview height in pixels

190

}

191

```

192

193

**Usage Examples:**

194

195

```vue

196

<template>

197

<div class="cropper-layout">

198

<div class="main-cropper">

199

<VueCropper

200

:img="imageUrl"

201

@real-time="handleRealTimePreview"

202

/>

203

</div>

204

205

<div class="preview-panels">

206

<!-- Large Preview -->

207

<div class="preview-large">

208

<h3>Large Preview</h3>

209

<div

210

class="preview-container"

211

:style="{ width: previews.w + 'px', height: previews.h + 'px' }"

212

>

213

<div :style="previews.div">

214

<img :src="previews.url" :style="previews.img">

215

</div>

216

</div>

217

</div>

218

219

<!-- Small Preview -->

220

<div class="preview-small">

221

<h3>Small Preview (50%)</h3>

222

<div

223

class="preview-container"

224

:style="{

225

width: (previews.w * 0.5) + 'px',

226

height: (previews.h * 0.5) + 'px',

227

overflow: 'hidden'

228

}"

229

>

230

<div :style="{

231

...parseCSSTransform(previews.div),

232

zoom: 0.5

233

}">

234

<img :src="previews.url" :style="previews.img">

235

</div>

236

</div>

237

</div>

238

239

<!-- Fixed Size Preview -->

240

<div class="preview-fixed">

241

<h3>Avatar Preview (100x100)</h3>

242

<div

243

class="preview-container avatar-preview"

244

:style="{

245

width: '100px',

246

height: '100px',

247

overflow: 'hidden',

248

borderRadius: '50%'

249

}"

250

>

251

<div :style="{

252

...parseCSSTransform(previews.div),

253

zoom: 100 / previews.w

254

}">

255

<img :src="previews.url" :style="previews.img">

256

</div>

257

</div>

258

</div>

259

</div>

260

</div>

261

</template>

262

263

<script>

264

export default {

265

data() {

266

return {

267

imageUrl: '/path/to/image.jpg',

268

previews: {

269

url: '',

270

img: '',

271

div: '',

272

w: 0,

273

h: 0

274

}

275

};

276

},

277

methods: {

278

handleRealTimePreview(data) {

279

this.previews = data;

280

281

// Optional: emit to parent component

282

this.$emit('preview-updated', data);

283

284

// Optional: store for later use

285

this.lastPreviewData = data;

286

},

287

288

parseCSSTransform(cssString) {

289

// Helper to parse CSS transform string into object

290

// Implementation depends on your specific needs

291

return {

292

transform: cssString

293

};

294

}

295

}

296

};

297

</script>

298

299

<style scoped>

300

.cropper-layout {

301

display: flex;

302

gap: 20px;

303

}

304

305

.main-cropper {

306

flex: 1;

307

height: 400px;

308

}

309

310

.preview-panels {

311

width: 300px;

312

display: flex;

313

flex-direction: column;

314

gap: 15px;

315

}

316

317

.preview-container {

318

border: 1px solid #ddd;

319

margin: 5px;

320

position: relative;

321

}

322

323

.avatar-preview {

324

border: 2px solid #007bff;

325

}

326

</style>

327

```