88

DrawingArea

Objective
  • Responder
    • View
      • DrawingArea

In the console of the browser, display the values of all the options:

canvas.getOptions()
Object { size: (2) […], hflip: false, vflip: false, grayscale: false, sepia: false, blur: false, invert: 0, contrast: 1, saturate: 1, brightness: 1, … }

Change some filter values of the canvas:

canvas.sepia=true
canvas.sepia=false
canvas.hflip=true
canvas.opacity=0.5
canvas.opacity=1

Change the size of the canvas:

canvas.size=[640,360]

Edit the file testDrawingArea.phtml in the folder tests:

  1. <?php $tagname='img'; ?>

Set the PHP variable $tagname to the value 'video'. Reload the page.

Try the value 'canvas'.

  1. function DrawingArea() {
  2.     View.call(this);
  3.  
  4.     this._width = this._height = 0;
  5.  
  6.     this._hflip = this._vflip = false;
  7.  
  8.     this._grayscale = this._sepia = this._blur = false;
  9.  
  10.     this._contrast = this._saturate = this._brightness = 1;
  11.  
  12.     this._invert = 0;
  13.  
  14.     this._opacity = 1;
  15.  
  16.     this._ctx = null;
  17.  
  18.     this._image = null;
  19. }
  20.  
  21. DrawingArea.prototype = Object.create(View.prototype);
  22.  
  23. Object.defineProperty(DrawingArea.prototype, 'constructor', { value: DrawingArea, enumerable: false, writable: true });
  24.  
  25. Object.defineProperty(DrawingArea.prototype, 'size', {
  26.     get:    function() {
  27.         return [this._width, this._height];
  28.     },
  29.     set:    function(size) {
  30.         if (! (Array.isArray(size) && size.length == 2))
  31.             throw new TypeError();
  32.  
  33.         const [width, height] = size;
  34.  
  35.         if (! (Number.isInteger(width) && Number.isInteger(height)))
  36.             throw new TypeError();
  37.  
  38.         if (width < 0 || height < 0)
  39.             throw new RangeError();
  40.  
  41.         if (this._width != width || this._height != height) {
  42.             this._width = width;
  43.             this._height = height;
  44.  
  45.             if (this.interfaced()) {
  46.                 this._ctxTransform();
  47.                 this._drawImage();
  48.             }
  49.         }
  50.     }
  51. });
  52.  
  53. Object.defineProperty(DrawingArea.prototype, 'hflip', {
  54.     get:    function() {
  55.         return this._hflip;
  56.     },
  57.     set:    function(hflip) {
  58.         if (this._hflip != hflip) {
  59.             this._hflip = hflip ? true : false;
  60.  
  61.             if (this.interfaced()) {
  62.                 this._ctxTransform();
  63.                 this._drawImage();
  64.             }
  65.         }
  66.     }
  67. });
  68.  
  69. Object.defineProperty(DrawingArea.prototype, 'vflip', {
  70.     get:    function() {
  71.         return this._vflip;
  72.     },
  73.     set:    function(vflip) {
  74.         if (this._vflip != vflip) {
  75.             this._vflip = vflip ? true : false;
  76.  
  77.             if (this.interfaced()) {
  78.                 this._ctxTransform();
  79.                 this._drawImage();
  80.             }
  81.         }
  82.     }
  83. });
  84.  
  85. Object.defineProperty(DrawingArea.prototype, 'grayscale', {
  86.     get:    function() {
  87.         return this._grayscale;
  88.     },
  89.     set:    function(grayscale) {
  90.         if (this._grayscale != grayscale) {
  91.             this._grayscale = grayscale ? true : false;
  92.  
  93.             if (this.interfaced()) {
  94.                 this._ctxFilter();
  95.                 this._drawImage();
  96.             }
  97.         }
  98.     }
  99. });
  100.  
  101. Object.defineProperty(DrawingArea.prototype, 'sepia', {
  102.     get:    function() {
  103.         return this._sepia;
  104.     },
  105.     set:    function(sepia) {
  106.         if (this._sepia != sepia) {
  107.             this._sepia = sepia ? true : false;
  108.  
  109.             if (this.interfaced()) {
  110.                 this._ctxFilter();
  111.                 this._drawImage();
  112.             }
  113.         }
  114.     }
  115. });
  116.  
  117. Object.defineProperty(DrawingArea.prototype, 'blur', {
  118.     get:    function() {
  119.         return this._blur;
  120.     },
  121.     set:    function(blur) {
  122.         if (this._blur != blur) {
  123.             this._blur = blur ? true : false;
  124.  
  125.             if (this.interfaced()) {
  126.                 this._ctxFilter();
  127.                 this._drawImage();
  128.             }
  129.         }
  130.     }
  131. });
  132.  
  133. Object.defineProperty(DrawingArea.prototype, 'invert', {
  134.     get:    function() {
  135.         return this._invert;
  136.     },
  137.     set:    function(invert) {
  138.         if (typeof invert !== 'number')
  139.             throw new TypeError();
  140.  
  141.         if (invert < 0 || invert > 1)
  142.             throw new RangeError();
  143.  
  144.         if (this._invert != invert) {
  145.             this._invert = invert;
  146.  
  147.             if (this.interfaced()) {
  148.                 this._ctxFilter();
  149.                 this._drawImage();
  150.             }
  151.         }
  152.     }
  153. });
  154.  
  155. Object.defineProperty(DrawingArea.prototype, 'contrast', {
  156.     get:    function() {
  157.         return this._contrast;
  158.     },
  159.     set:    function(contrast) {
  160.         if (typeof contrast !== 'number')
  161.             throw new TypeError();
  162.  
  163.         if (contrast < 0)
  164.             throw new RangeError();
  165.  
  166.         if (this._contrast != contrast) {
  167.             this._contrast = contrast;
  168.  
  169.             if (this.interfaced()) {
  170.                 this._ctxFilter();
  171.                 this._drawImage();
  172.             }
  173.         }
  174.     }
  175. });
  176.  
  177. Object.defineProperty(DrawingArea.prototype, 'saturate', {
  178.     get:    function() {
  179.         return this._saturate;
  180.     },
  181.     set:    function(saturate) {
  182.         if (typeof saturate !== 'number')
  183.             throw new TypeError();
  184.  
  185.         if (saturate < 0)
  186.             throw new RangeError();
  187.  
  188.         if (this._saturate != saturate) {
  189.             this._saturate = saturate;
  190.  
  191.             if (this.interfaced()) {
  192.                 this._ctxFilter();
  193.                 this._drawImage();
  194.             }
  195.         }
  196.     }
  197. });
  198.  
  199. Object.defineProperty(DrawingArea.prototype, 'brightness', {
  200.     get:    function() {
  201.         return this._brightness;
  202.     },
  203.     set:    function(brightness) {
  204.         if (typeof brightness !== 'number')
  205.             throw new TypeError();
  206.  
  207.         if (brightness < 0)
  208.             throw new RangeError();
  209.  
  210.         if (this._brightness != brightness) {
  211.             this._brightness = brightness;
  212.  
  213.             if (this.interfaced()) {
  214.                 this._ctxFilter();
  215.                 this._drawImage();
  216.             }
  217.         }
  218.     }
  219. });
  220.  
  221. Object.defineProperty(DrawingArea.prototype, 'opacity', {
  222.     get:    function() {
  223.         return this._opacity;
  224.     },
  225.     set:    function(opacity) {
  226.         if (typeof opacity !== 'number')
  227.             throw new TypeError();
  228.  
  229.         if (opacity < 0 || opacity > 1)
  230.             throw new RangeError();
  231.  
  232.         if (this._opacity != opacity) {
  233.             this._opacity = opacity;
  234.  
  235.             if (this.interfaced()) {
  236.                 this._ctxFilter();
  237.                 this._drawImage();
  238.             }
  239.         }
  240.     }
  241. });
  242.  
  243. DrawingArea.prototype.getOptions = function() {
  244.     const options = {
  245.         size:   [this._width, this._height],
  246.         hflip:      this._hflip,
  247.         vflip:      this._vflip,
  248.         grayscale:  this._grayscale,
  249.         sepia:      this._sepia,
  250.         blur:       this._blur,
  251.         invert:     this._invert,
  252.         contrast:   this._contrast,
  253.         saturate:   this._saturate,
  254.         brightness: this._brightness,
  255.         opacity:    this._opacity
  256.     };
  257.  
  258.     return options;
  259. };
  260.  
  261. DrawingArea.prototype.setOptions = function(options) {
  262.     const {
  263.         size = [this._width, this._height],
  264.         hflip = this._hflip,
  265.         vflip = this._vflip,
  266.         grayscale = this._grayscale,
  267.         sepia = this._sepia,
  268.         blur = this._blur,
  269.         invert = this._invert,
  270.         contrast = this._contrast,
  271.         saturate = this._saturate,
  272.         brightness = this._brightness,
  273.         opacity = this._opacity
  274.     } = options || {};
  275.  
  276.     if (! (Array.isArray(size) && size.length == 2))
  277.         throw new TypeError();
  278.  
  279.     const [width, height] = size;
  280.  
  281.     if (! (Number.isInteger(width) && Number.isInteger(height)))
  282.         throw new TypeError();
  283.  
  284.     if (width < 0 || height < 0)
  285.         throw new RangeError();
  286.  
  287.     this._width = width;
  288.     this._height = height;
  289.  
  290.     this._hflip = hflip ? true : false;
  291.     this._vflip = vflip ? true : false;
  292.     this._grayscale = grayscale ? true : false;
  293.     this._sepia = sepia ? true : false;
  294.     this._blur = blur ? true : false;
  295.  
  296.     if (! (typeof invert === 'number' && typeof contrast === 'number' && typeof saturate === 'number' && typeof brightness === 'number' && typeof opacity === 'number'))
  297.         throw new TypeError();
  298.  
  299.     if (invert < 0 || contrast < 0 || saturate < 0 || brightness < 0)
  300.         throw new RangeError();
  301.  
  302.     if (opacity < 0 || opacity > 1)
  303.         throw new RangeError();
  304.  
  305.     this._invert = invert;
  306.     this._contrast = contrast;
  307.     this._saturate = saturate;
  308.     this._brightness = brightness;
  309.  
  310.     this._opacity = opacity;
  311.  
  312.     if (this.interfaced()) {
  313.         this._ctxTransform();
  314.         this._drawImage();
  315.     }
  316.  
  317.     return this;
  318. };
  319.  
  320. DrawingArea.prototype.erase = function() {
  321.     if (this._widget && this._widget.width != 0 && this._widget.height != 0) {
  322.         this._ctx.clearRect(0, 0, this._widget.width, this._widget.height);
  323.     }
  324.  
  325.     return this;
  326. };
  327.  
  328. DrawingArea.prototype.isBlank = function() {
  329.     if (!this._widget || this._widget.width == 0 || this._widget.height == 0)
  330.         return true;
  331.  
  332.     const imgdata = this._ctx.getImageData(0, 0, this._widget.width, this._widget.height);
  333.  
  334.     return imgdata ? !new Uint32Array(imgdata.data.buffer).some(color => color != 0) : true;
  335. };
  336.  
  337. DrawingArea.prototype.setImage = function(w) {
  338.     this._image = w;
  339.  
  340.     this._drawImage();
  341.  
  342.     return this;
  343. };
  344.  
  345. DrawingArea.prototype.setWidget = function(w) {
  346.     if (! (w.tagName == 'IMG' || w.tagName == 'VIDEO' || w.tagName == 'CANVAS'))
  347.         throw new TypeError();
  348.  
  349.     const canvas = document.createElement('canvas');
  350.  
  351.     this._ctx = canvas.getContext('2d');
  352.  
  353.     View.prototype.setWidget.call(this, canvas);
  354.  
  355.     w.style.display = 'none';
  356.  
  357.     w.after(canvas);
  358.  
  359.     this._image = w;
  360.  
  361.     if (this._width == 0) {
  362.         this._width = w.width;
  363.         this._height = w.height;
  364.     }
  365.  
  366.     this._ctxTransform();
  367.  
  368.     switch (w.tagName) {
  369.         case 'IMG':
  370.             w.addEventListener('load', () => this._drawImage(), { once: true });
  371.             break;
  372.         case 'VIDEO':
  373.             w.addEventListener('loadeddata', () => this._drawImage(), { once: true });
  374.             break;
  375.         case 'CANVAS':
  376.         default:
  377.             this._drawImage();
  378.     }
  379.  
  380.     return this;
  381. };
  382.  
  383. DrawingArea.prototype._ctxFilter = function() {
  384.     let filter = [];
  385.  
  386.     if (this._grayscale)
  387.         filter.push('grayscale(1)');
  388.  
  389.     if (this._sepia)
  390.         filter.push('sepia(1)');
  391.  
  392.     if (this._blur)
  393.         filter.push('blur(8px)');
  394.  
  395.     if (this._invert != 0)
  396.         filter.push(`invert(${this._invert})`);
  397.  
  398.     if (this._contrast != 1)
  399.         filter.push(`contrast(${this._contrast})`);
  400.  
  401.     if (this._saturate != 1)
  402.         filter.push(`saturate(${this._saturate})`);
  403.  
  404.     if (this._brightness != 1)
  405.         filter.push(`brightness(${this._brightness})`);
  406.  
  407.     if (this._opacity != 1)
  408.         filter.push(`opacity(${this._opacity})`);
  409.  
  410.     this._ctx.filter = filter.length ? filter.join(' ') : 'none';
  411. };
  412.  
  413. DrawingArea.prototype._ctxTransform = function() {
  414.     this._widget.width = this._width;
  415.     this._widget.height = this._height;
  416.  
  417.     this._ctx.transform(this._hflip ? -1 : 1, 0, 0, this._vflip ? -1 : 1, this._hflip ? this._widget.width : 0, this._vflip ? this._widget.height : 0);
  418.  
  419.     this._ctxFilter();
  420. };
  421.  
  422. DrawingArea.prototype._drawImage = function() {
  423.     if (this._widget.width == 0 || this._widget.height == 0)
  424.         return;
  425.  
  426.     this._ctx.clearRect(0, 0, this._widget.width, this._widget.height);
  427.  
  428.     this._ctx.drawImage(this._image, 0, 0, this._widget.width, this._widget.height);
  429. };
Test
  1. <?php $maxwidth=320; ?>
  2. <?php $tagname='img'; ?>
  1. switch ($tagname) {
  2. case 'img':
  3.     $src='/files/images/htmlcssjs.jpg';
  4.     $width=1280;
  5.     $height=720;
  6.     break;
  7. case 'video':
  8.     $src='/files/videos/Horloge.webm';
  9.     $type='video/webm';
  10.     $width=854;
  11.     $height=480;
  12.     break;
  13. case 'canvas':
  14.     $width=600;
  15.     $height=$width;
  16.     break;
  17. }
  1. <?php $id=uniqid('id'); ?>
  1. <div id="<?php echo $id; ?>" class="noprint">
  2. <div class="test_display">
  3. <?php if ($tagname == 'img'): ?>
  4. <img src="<?php echo $src; ?>" alt="" width="<?php echo $width; ?>" height="<?php echo $height; ?>" hidden/>
  5. <?php elseif ($tagname == 'video'): ?>
  6. <video width="<?php echo $width; ?>" height="<?php echo $height; ?>" preload="auto">
  7. <source src="<?php echo $src; ?>" type="<?php echo $type; ?>" />
  8. </video>
  9. <?php elseif ($tagname == 'canvas'): ?>
  10. <canvas width="<?php echo $width; ?>" height="<?php echo $height; ?>"></canvas>
  11. <?php endif; ?>
  12. </div>
  13. </div>
  1. <?php head('javascript', '/objectivejs/Objective.js'); ?>
  2. <?php head('javascript', '/objectivejs/Responder.js'); ?>
  3. <?php head('javascript', '/objectivejs/View.js'); ?>
  4. <?php head('javascript', '/objectivejs/DrawingArea.js'); ?>
  1. (function() {
  2.     const canvas = document.querySelector('#<?php echo $id; ?> canvas');
  3.     const ctx = canvas.getContext('2d');
  4.  
  5.     const w = canvas.width / 2;
  6.     const h = canvas.height / 2;
  7.  
  8.     ctx.fillStyle = '#FD0';
  9.     ctx.fillRect(0, 0, w, h);
  10.     ctx.fillStyle = '#6C0';
  11.     ctx.fillRect(w, 0, w, h);
  12.     ctx.fillStyle = '#09F';
  13.     ctx.fillRect(0, h, w, h);
  14.     ctx.fillStyle = '#F30';
  15.     ctx.fillRect(w, h, w, h);
  16.     ctx.fillStyle = '#FFF';
  17.  
  18.     ctx.globalAlpha = 0.2;
  19.  
  20.     for (let i = 0; i < 7; i++) {
  21.         ctx.beginPath();
  22.         ctx.arc(w, h, w / 10 + h / 10 * i, 0, Math.PI * 2, true);
  23.         ctx.fill();
  24.     }
  25. })();
  1. const width = <?php echo $width; ?>;
  2. const height = <?php echo $height; ?>;
  3. const maxwidth = <?php echo $maxwidth; ?>;
  4.  
  5. const ratio = Math.round(width / height * 100) / 100;
  1. const image = document.querySelector('#<?php echo $id; ?> <?php echo $tagname; ?>');
  1. const canvas = new DrawingArea();
  2.  
  3. canvas.size = [maxwidth, Math.ceil(maxwidth / ratio)];
  4.  
  5. canvas.setManagedWidget(image);
SEE ALSO

View, VideoClip, Editing a video clip, Signature

Comments

Your comment:
[p] [b] [i] [u] [s] [quote] [pre] [br] [code] [url] [email] strip help 2000

Enter a maximum of 2000 characters.
Improve the presentation of your text with the following formatting tags:
[p]paragraph[/p], [b]bold[/b], [i]italics[/i], [u]underline[/u], [s]strike[/s], [quote]citation[/quote], [pre]as is[/pre], [br]line break,
[url]http://www.izend.org[/url], [url=http://www.izend.org]site[/url], [email]izend@izend.org[/email], [email=izend@izend.org]izend[/email],
[code]command[/code], [code=language]source code in c, java, php, html, javascript, xml, css, sql, bash, dos, make, etc.[/code].