index : pan-zoom | |
SVG pan/zoom library. |
aboutsummaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'public')
-rw-r--r-- | public/assets/css/style.css | 40 | ||||
-rw-r--r-- | public/assets/images/41156165560-4438592e93-o.webp | bin | 0 -> 585068 bytes | |||
-rw-r--r-- | public/assets/images/image.svg | 108 | ||||
-rw-r--r-- | public/image.svg | 82 | ||||
-rw-r--r-- | public/index.html | 31 |
5 files changed, 162 insertions, 99 deletions
diff --git a/public/assets/css/style.css b/public/assets/css/style.css new file mode 100644 index 0000000..db47790 --- /dev/null +++ b/public/assets/css/style.css @@ -0,0 +1,40 @@ +body { + text-align: center; + max-width: 100vw; +} + +.container { + padding: 0; + max-width: 586.033px; + max-height: 586.033px; + margin: 0 auto; + overflow: hidden; + border: 1px solid steelblue; + background-color: gray; +} + +img, object { + touch-action: none; +} + +img { + max-width: 100%; + border: 1px solid silver; + transform: scale(0.9); +} + +.container object, .container.switch img { + display: block; +} + +.container img, .container.switch object { + display: none; +} + +button .button-text.raster, button.switch .button-text.svg { + display: none; +} + +button.switch .button-text.raster { + display: inline; +} diff --git a/public/assets/images/41156165560-4438592e93-o.webp b/public/assets/images/41156165560-4438592e93-o.webp Binary files differnew file mode 100644 index 0000000..2ad3fa4 --- /dev/null +++ b/public/assets/images/41156165560-4438592e93-o.webp diff --git a/public/assets/images/image.svg b/public/assets/images/image.svg new file mode 100644 index 0000000..29f9306 --- /dev/null +++ b/public/assets/images/image.svg @@ -0,0 +1,108 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" + "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg viewBox="-200 -150 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <style> + svg { + overflow: hidden; + border: 1px solid silver; + transform: scale(0.9); + } + + circle, rect { + fill-opacity: 0.9; + filter: drop-shadow(5px 5px 2px rgba(0, 0, 0, .5)); + } + </style> + <script type="text/javascript">//<![CDATA[ + const svgns = 'http://www.w3.org/2000/svg', + svg = document.querySelector('svg'), + { x: vbX, y: vbY, width: vbWidth, height: vbHeight } = svg.viewBox.baseVal, + + shapeCount = 100, + circleRadius = { min: 5, max: 45 }, + rectSideLength = { min: 5, max: 95 }, + colorValRange = { min: 0, max: 255 }, + shadeFactorRange = { min: 0.3, max: 0.7 }; + + // source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_integer_between_two_values_inclusive + function getRandomIntInclusive(min, max) { + const minCeiled = Math.ceil(min), + maxFloored = Math.floor(max); + + return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled); + } + + // source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#getting_a_random_number_between_two_values + function getRandomArbitrary(min, max) { + return Math.random() * (max - min) + min; + } + + function getRandomColorValue() { + return getRandomIntInclusive(colorValRange.min, colorValRange.max); + } + + function getRandomShadeFactor() { + return getRandomArbitrary(shadeFactorRange.min, shadeFactorRange.max); + } + + function getRandomOrigin() { + return { + x: getRandomIntInclusive(vbX, vbX + vbWidth), + y: getRandomIntInclusive(vbY, vbY + vbHeight) + } + } + + function getRandomFillAndStrokeVals() { + const fill = ['r', 'g', 'b'].map(() => getRandomColorValue()), + stroke = fill.map(v => Math.floor(v * getRandomShadeFactor())); + + return { + fill: fill, + stroke: stroke + }; + } + + function getRandomCircle(fill, stroke) { + const el = document.createElementNS(svgns, 'circle'), + r = getRandomIntInclusive(circleRadius.max, circleRadius.min), + origin = getRandomOrigin(); + + el.setAttributeNS(null, 'cx', origin.x); + el.setAttributeNS(null, 'cy', origin.y); + el.setAttributeNS(null, 'r', r); + el.setAttributeNS(null, 'fill', fill); + el.setAttributeNS(null, 'stroke', stroke); + + return el; + } + + function getRandomRect(fill, stroke) { + const el = document.createElementNS(svgns, 'rect'), + [width, height] = ['w', 'h'].map(() => + getRandomIntInclusive(rectSideLength.max, rectSideLength.min) + ), + origin = getRandomOrigin(); + + el.setAttributeNS(null, 'x', origin.x); + el.setAttributeNS(null, 'y', origin.y); + el.setAttributeNS(null, 'width', width); + el.setAttributeNS(null, 'height', height); + el.setAttributeNS(null, 'fill', fill); + el.setAttributeNS(null, 'stroke', stroke); + + return el; + } + + function getRandomShape({ fill: fillVals, stroke: strokeVals }) { + const shape = [getRandomCircle, getRandomRect][Math.round(Math.random())], + [fill, stroke] = [fillVals, strokeVals].map(v => `rgb(${v.join(', ')})`); + + return shape(fill, stroke); + } + + [...Array(shapeCount)] + .map(() => getRandomFillAndStrokeVals()) + .forEach(fillAndStrokeVal => svg.appendChild(getRandomShape(fillAndStrokeVal))); + //]]></script> +</svg> diff --git a/public/image.svg b/public/image.svg deleted file mode 100644 index 5a5c3d9..0000000 --- a/public/image.svg +++ /dev/null @@ -1,82 +0,0 @@ -<?xml version="1.0" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" - "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> -<svg viewBox="0 0 400 300" version="1.1" xmlns="http://www.w3.org/2000/svg"> - <style> - svg { - overflow: hidden; - } - - circle, rect { - fill-opacity: 0.9; - } - </style> - <script type="text/javascript">//<![CDATA[ - const svgns = 'http://www.w3.org/2000/svg', - svg = document.querySelector('svg'), - { width: vbWidth, height: vbHeight } = svg.viewBox.baseVal, - shapeCount = 100, - maxColorValue = 256, - circleRadius = { max: 45, min: 5 }, - rectSideLength = { max: 95, min: 5 }; - - function getRandomInt(max) { - return Math.floor(Math.random() * max); - } - - function getRandomPositiveInt(max) { - return getRandomInt(max) + 1; - } - - function getRandomFillAndStrokeVals() { - const shadeFactor = Math.random(), - fill = ['r', 'g', 'b'].map(() => getRandomInt(maxColorValue)), - stroke = fill.map(v => Math.floor(v * shadeFactor)); - - return { - fill: fill, - stroke: stroke - }; - } - - function getRandomCircle(fill, stroke) { - const el = document.createElementNS(svgns, 'circle'), - r = getRandomPositiveInt(circleRadius.max) + circleRadius.min; - - el.setAttributeNS(null, 'cx', getRandomInt(vbWidth)); - el.setAttributeNS(null, 'cy', getRandomInt(vbHeight)); - el.setAttributeNS(null, 'r', r); - el.setAttributeNS(null, 'fill', fill); - el.setAttributeNS(null, 'stroke', stroke); - - return el; - } - - function getRandomRect(fill, stroke) { - const el = document.createElementNS(svgns, 'rect'), - [width, height] = ['w', 'h'].map(() => - getRandomPositiveInt(rectSideLength.max) + rectSideLength.min - ); - - el.setAttributeNS(null, 'x', getRandomInt(vbWidth)); - el.setAttributeNS(null, 'y', getRandomInt(vbHeight)); - el.setAttributeNS(null, 'width', width); - el.setAttributeNS(null, 'height', height); - el.setAttributeNS(null, 'fill', fill); - el.setAttributeNS(null, 'stroke', stroke); - - return el; - } - - function getRandomShape({ fill: fillVals, stroke: strokeVals }) { - const shapes = [getRandomCircle, getRandomRect], - [fill, stroke] = [fillVals, strokeVals].map(v => `rgb(${v.join(', ')})`); - - return shapes[getRandomInt(shapes.length)](fill, stroke); - } - - [...Array(shapeCount)] - .map(() => getRandomFillAndStrokeVals()) - .forEach(fillAndStrokeVal => svg.appendChild(getRandomShape(fillAndStrokeVal))); - //]]></script> -</svg> diff --git a/public/index.html b/public/index.html index 8040421..35a3030 100644 --- a/public/index.html +++ b/public/index.html @@ -3,31 +3,28 @@ <head> <meta charset="utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> - <title>SVG Pan & Zoom Example</title> - <style> - body { - text-align: center; - max-width: 100vw; - } - - object { - max-height: 400px; - max-width: 100%; - background-color: lightsteelblue; - border: 1px solid steelblue; - touch-action: none; - } - </style> + <title>JavaScript/CSS Pan & Zoom Demo</title> + <link rel="stylesheet" href="assets/css/style.css"> </head> <body> - <h1>Pan & Zoom an SVG Image with JavaScript</h1> + <h1>Pan & Zoom an Element with CSS/JavaScript</h1> <p> Click and drag on the image to pan. Use the mouse wheel to zoom in and out. </p> - <object type="image/svg+xml" data="image.svg"></object> + <p> + <button> + <span class="button-text svg">Raster image</span> + <span class="button-text raster">SVG image</span> + </button> + </p> + + <div class="container"> + <object type="image/svg+xml" data="assets/images/image.svg"></object> + <img src="assets/images/41156165560-4438592e93-o.webp"/> + </div> <script src="app.js"></script> </body> </html> |