Skip to content

Commit 328648b

Browse files
committed
fix: code styling
1 parent 234bacb commit 328648b

14 files changed

Lines changed: 172 additions & 541 deletions

File tree

docs/breakpoints.html

Lines changed: 25 additions & 362 deletions
Large diffs are not rendered by default.

docs/es-modules/breakpoints.html

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>Breakpoints - Cloudinary Video Player</title>
6+
<link
7+
href="https://res.cloudinary.com/cloudinary-marketing/image/upload/f_auto,q_auto/c_scale,w_32,e_hue:290/creative_staging/cloudinary_internal/Website/Brand%20Updates/Favicon/cloudinary_web_favicon_192x192.png"
8+
rel="icon"
9+
type="image/png"
10+
/>
11+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
12+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
13+
</head>
14+
<body>
15+
<div class="container p-4 col-12 col-md-9 col-xl-6">
16+
<nav class="nav mb-2">
17+
<a href="/index.html">&#60;&#60; Back to examples index</a>
18+
</nav>
19+
<h1>Cloudinary Video Player</h1>
20+
<h3 class="mb-4">Breakpoints - Responsive Video Resolution</h3>
21+
22+
<p>
23+
Breakpoints automatically select the optimal video resolution based on player width and device pixel ratio (DPR).
24+
</p>
25+
26+
<h4 class="mt-4">With Breakpoints (DPR 2.0)</h4>
27+
<video
28+
id="player-with-breakpoints"
29+
class="cld-video-player"
30+
controls
31+
muted
32+
width="500"
33+
></video>
34+
35+
<h4 class="mt-4">Without Breakpoints (Comparison)</h4>
36+
<video
37+
id="player-without-breakpoints"
38+
class="cld-video-player"
39+
controls
40+
muted
41+
width="500"
42+
></video>
43+
44+
<p class="mt-4">
45+
<a href="https://cloudinary.com/documentation/cloudinary_video_player"
46+
>Full documentation</a
47+
>
48+
</p>
49+
</div>
50+
51+
<script type="module">
52+
import videoPlayer from 'cloudinary-video-player/videoPlayer';
53+
import 'cloudinary-video-player/cld-video-player.min.css';
54+
55+
// With breakpoints
56+
const player1 = videoPlayer('player-with-breakpoints', {
57+
cloudName: 'demo',
58+
breakpoints: true,
59+
dpr: 2.0
60+
});
61+
player1.source('sea_turtle');
62+
63+
// Without breakpoints
64+
const player2 = videoPlayer('player-without-breakpoints', {
65+
cloudName: 'demo'
66+
});
67+
player2.source('sea_turtle');
68+
</script>
69+
70+
<!-- Bootstrap -->
71+
<link
72+
href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
73+
rel="stylesheet"
74+
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
75+
crossorigin="anonymous"
76+
/>
77+
</body>
78+
</html>

docs/es-modules/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ <h3 class="mt-4">Code examples:</h3>
4949
<li><a href="./api.html">API and Events</a></li>
5050
<li><a href="./audio.html">Audio Player</a></li>
5151
<li><a href="./autoplay-on-scroll.html">Autoplay on Scroll</a></li>
52+
<li><a href="./breakpoints.html">Breakpoints</a></li>
5253
<li><a href="./chapters.html">Chapters</a></li>
5354
<li><a href="./cloudinary-analytics.html">Cloudinary Analytics</a></li>
5455
<li><a href="./codec-formats.html">Codecs and formats</a></li>

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ <h3 class="mt-4">Some code examples:</h3>
5353
<li><a href="./api.html">API and Events</a></li>
5454
<li><a href="./audio.html">Audio Player</a></li>
5555
<li><a href="./autoplay-on-scroll.html">Autoplay on Scroll</a></li>
56-
<li><a href="./breakpoints.html">Breakpoints (Responsive Resolution)</a></li>
56+
<li><a href="./breakpoints.html">Breakpoints</a></li>
5757
<li><a href="./chapters.html">Chapters</a></li>
5858
<li><a href="./cloudinary-analytics.html">Cloudinary Analytics</a></li>
5959
<li><a href="./codec-formats.html">Codecs and formats</a></li>

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,6 @@
150150
},
151151
"overrides": {
152152
"min-document": ">=2.19.2"
153-
}
153+
},
154+
"packageManager": "pnpm@10.12.2+sha512.a32540185b964ee30bb4e979e405adc6af59226b438ee4cc19f9e8773667a66d302f5bfee60a39d3cac69e35e4b96e708a71dd002b7e9359c4112a1722ac323f"
154155
}

src/config/configSchema.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,18 @@
274274
},
275275
"default": ["auto"]
276276
},
277+
"breakpoints": {
278+
"type": "boolean",
279+
"default": false,
280+
"description": "Enable responsive video resolution based on player width and device pixel ratio"
281+
},
282+
"dpr": {
283+
"type": "number",
284+
"minimum": 1.0,
285+
"maximum": 2.0,
286+
"default": 2.0,
287+
"description": "Device pixel ratio for responsive video (1.0, 1.5, or 2.0)"
288+
},
277289
"resourceType": {
278290
"type": "string",
279291
"default": "video"

src/plugins/cloudinary/index.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,7 @@ class CloudinaryContext {
305305
this.player.poster(src.poster().url());
306306
}
307307

308-
// Pass player element for breakpoint calculation (only for VideoSource)
309-
const playerElement = src.getType && src.getType() === 'video' ? this.player.el() : null;
310-
_sources = src.generateSources(playerElement).reduce((srcs, src) => {
308+
_sources = src.generateSources().reduce((srcs, src) => {
311309
if (src.isAdaptive) {
312310
let codec = src.type.split('; ')[1] || null;
313311
if (codec && 'MediaSource' in window) {
Lines changed: 23 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,39 @@
11
/**
2-
* Breakpoint utility functions for responsive video resolution selection
3-
* Based on container width and device pixel ratio (DPR)
2+
* Breakpoint utility for responsive video resolution
3+
* Passes container width and DPR to Cloudinary for optimal video delivery
44
*/
55

6+
const DEFAULT_DPR = 2.0;
7+
68
/**
7-
* Normalize DPR to allowed values (1.0, 1.5, or 2.0)
8-
* Rounds to nearest allowed value and caps at 2.0
9-
* @param {number} dpr - User-specified DPR
9+
* Validate and normalize DPR to 1.0, 1.5, or 2.0
10+
* @param {number} dpr - User-specified DPR value
1011
* @returns {number} Normalized DPR (1.0, 1.5, or 2.0)
1112
*/
12-
export const normalizeDpr = (dpr) => {
13-
// Cap at 2.0 first
14-
const capped = Math.min(dpr, 2.0);
15-
16-
// Round to nearest allowed value (1.0, 1.5, or 2.0)
17-
if (capped < 1.25) return 1.0;
18-
if (capped < 1.75) return 1.5;
19-
return 2.0;
13+
export const validateDpr = (dpr) => {
14+
const capped = (typeof dpr === 'number' && !isNaN(dpr) && dpr >= 1.0) ? Math.min(dpr, 2.0) : DEFAULT_DPR;
15+
return capped < 1.25 ? 1.0 : capped < 1.75 ? 1.5 : 2.0;
2016
};
2117

2218
/**
23-
* Calculate optimal video width based on container and DPR
19+
* Get breakpoint transformation for responsive video
2420
* @param {Object} params
25-
* @param {number} params.containerWidth - Container element width in pixels
26-
* @param {number} params.dpr - Normalized DPR (1.0, 1.5, or 2.0)
27-
* @param {number[]} params.renditions - Available rendition widths (sorted ascending)
28-
* @returns {Object} { width, height }
21+
* @param {boolean} params.breakpointsEnabled - Whether breakpoints are enabled
22+
* @param {number} params.dpr - DPR value (already validated)
23+
* @returns {Object|null} Transformation with width, dpr, and crop
2924
*/
30-
export const calculateBreakpoint = ({
31-
containerWidth,
32-
dpr,
33-
renditions
34-
}) => {
35-
// Calculate required width (DPR already normalized)
36-
const requiredWidth = Math.round(containerWidth * dpr);
25+
export const getBreakpointTransformation = ({ breakpointsEnabled, dpr }) => {
26+
if (!breakpointsEnabled) return null;
3727

38-
// Select smallest rendition >= requiredWidth, or largest if none found
39-
const selectedWidth = renditions.find(w => w >= requiredWidth) || renditions[renditions.length - 1];
28+
// Get player element from DOM
29+
const playerElement = document.querySelector('.cld-video-player, video.vjs-tech');
30+
const width = playerElement?.clientWidth;
31+
32+
if (!width) return null;
4033

4134
return {
42-
width: selectedWidth,
43-
height: null // Let Cloudinary auto-calculate
35+
width,
36+
dpr,
37+
crop: 'limit'
4438
};
4539
};
46-
47-
/**
48-
* Validate breakpoint configuration
49-
* @param {Object} config - Breakpoint config object
50-
* @returns {Object} { valid: boolean, error: string|null }
51-
*/
52-
export const validateBreakpointConfig = (config) => {
53-
if (!config || typeof config !== 'object') {
54-
return { valid: false, error: 'Breakpoint config must be an object' };
55-
}
56-
57-
if (config.dpr !== undefined) {
58-
if (typeof config.dpr !== 'number' || isNaN(config.dpr)) {
59-
return { valid: false, error: 'dpr must be a valid number' };
60-
}
61-
if (config.dpr < 1.0) {
62-
return { valid: false, error: 'dpr must be at least 1.0' };
63-
}
64-
}
65-
66-
return { valid: true, error: null };
67-
};
68-
69-
/**
70-
* Get container element for width measurement
71-
* Always uses parent element, with fallback to player element itself
72-
* @param {HTMLElement} playerElement - Video player element
73-
* @returns {HTMLElement|null} Container element or null if not found
74-
*/
75-
export const getContainerElement = (playerElement) => {
76-
if (!playerElement) {
77-
return null;
78-
}
79-
80-
// Use parent element, fallback to player element itself
81-
return playerElement.parentElement || playerElement;
82-
};

src/plugins/cloudinary/models/video-source/video-source.const.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,3 @@ export const FORMAT_MAPPINGS = {
7171
hls: 'm3u8',
7272
dash: 'mpd'
7373
};
74-
75-
// Breakpoint configuration constants
76-
export const BREAKPOINT_RENDITIONS = [640, 1280, 1920, 3840];
77-
export const BREAKPOINT_DEFAULT_MAX_DPR = 2.0; // Default maximum DPR cap

0 commit comments

Comments
 (0)